Merge pull request #34400 from backstage/feat/bui-token-redesign

feat(ui): introduce semantic color token families and deprecate legacy tokens
This commit is contained in:
Charles de Dreuille
2026-05-29 15:40:20 +01:00
committed by GitHub
10 changed files with 1022 additions and 258 deletions
@@ -0,0 +1,5 @@
---
'@backstage/eslint-plugin': patch
---
Adds a new `@backstage/no-deprecated-bui-tokens` lint rule that warns when a deprecated `@backstage/ui` CSS token is referenced in a JavaScript or TypeScript file (including CSS-in-JS patterns and template literals). The rule is included in the `recommended` config, so plugin authors using `plugin:@backstage/recommended` will receive warnings automatically when using tokens that have been superseded by the new semantic color families. Note that plain CSS and CSS module files are outside ESLint's scope and are not covered by this rule.
+63
View File
@@ -0,0 +1,63 @@
---
'@backstage/ui': patch
---
Introduces a new set of semantic color token families — Accent, Announcement, Warning, Negative, and Positive — each providing a consistent set of background, foreground, and border tokens for both light and dark themes. A gray scale (`--bui-gray-1` through `--bui-gray-11`) and updated foreground tokens are also included.
The previous tokens remain in place for backward compatibility but are now deprecated and will be removed in a future release.
**Migration:**
**Neutral backgrounds**
The neutral background tokens keep their existing names (`--bui-bg-app`, `--bui-bg-neutral-1` through `--bui-bg-neutral-4`) but are updated with new solid-color values for both light and dark themes. No token renaming is required. The `-hover`, `-pressed`, and `-disabled` interaction variants of these tokens are deprecated and should be removed.
**Foreground**
| Deprecated | Replacement |
| ------------------ | ----------------------- |
| `--bui-fg-danger` | `--bui-fg-negative` |
| `--bui-fg-success` | `--bui-fg-positive` |
| `--bui-fg-info` | `--bui-fg-announcement` |
**Accent**
| Deprecated | Replacement |
| ------------------------- | -------------------------- |
| `--bui-bg-solid` | `--bui-accent-bg` |
| `--bui-bg-solid-hover` | `--bui-accent-bg-hover` |
| `--bui-bg-solid-disabled` | `--bui-accent-bg-disabled` |
| `--bui-fg-solid` | `--bui-accent-fg` |
| `--bui-fg-solid-disabled` | `--bui-accent-fg-disabled` |
**Positive**
| Deprecated | Replacement |
| ------------------------ | --------------------------- |
| `--bui-bg-success` | `--bui-positive-bg-subdued` |
| `--bui-fg-success-on-bg` | `--bui-positive-fg-subdued` |
| `--bui-border-success` | `--bui-positive-border` |
**Negative**
| Deprecated | Replacement |
| ----------------------- | --------------------------- |
| `--bui-bg-danger` | `--bui-negative-bg-subdued` |
| `--bui-fg-danger-on-bg` | `--bui-negative-fg-subdued` |
| `--bui-border-danger` | `--bui-negative-border` |
**Warning**
| Deprecated | Replacement |
| ------------------------ | -------------------------- |
| `--bui-bg-warning` | `--bui-warning-bg-subdued` |
| `--bui-fg-warning-on-bg` | `--bui-warning-fg-subdued` |
| `--bui-border-warning` | `--bui-warning-border` |
**Announcement**
| Deprecated | Replacement |
| --------------------- | ------------------------------- |
| `--bui-bg-info` | `--bui-announcement-bg-subdued` |
| `--bui-fg-info-on-bg` | `--bui-announcement-fg-subdued` |
| `--bui-border-info` | `--bui-announcement-border` |
+15 -17
View File
@@ -193,49 +193,47 @@
}
[data-theme-mode='light'][data-theme-name='spotify'] {
--bui-ring: rgba(0, 0, 0, 0.2);
--bui-accent-bg: #1ed760;
--bui-accent-bg-hover: #3be477;
--bui-accent-bg-disabled: #0f6c30;
--bui-accent-fg: var(--bui-black);
--bui-accent-fg-disabled: #62ab7c;
/* Deprecated tokens */
--bui-bg-solid: #1ed760;
--bui-bg-solid-hover: #3be477;
--bui-bg-solid-pressed: #1abc54;
--bui-bg-solid-disabled: #0f6c30;
--bui-fg-primary: var(--bui-black);
--bui-fg-secondary: #757575;
--bui-fg-solid: var(--bui-black);
--bui-fg-solid-disabled: #62ab7c;
--bui-border-2: #d9d9d9;
--bui-border-danger: #f87a7a;
--bui-border-warning: #e36d05;
--bui-border-success: #53db83;
--bui-ring: rgba(0, 0, 0, 0.2);
}
[data-theme-mode='dark'][data-theme-name='spotify'] {
--bui-bg-app: var(--bui-black);
--bui-ring: rgba(255, 255, 255, 0.2);
--bui-accent-bg: #1ed760;
--bui-accent-bg-hover: #3be477;
--bui-accent-bg-disabled: #0f6c30;
--bui-accent-fg: var(--bui-black);
--bui-accent-fg-disabled: #62ab7c;
/* Deprecated tokens */
--bui-bg-solid: #1ed760;
--bui-bg-solid-hover: #3be477;
--bui-bg-solid-pressed: #1abc54;
--bui-bg-solid-disabled: #0f6c30;
--bui-bg-danger: #3b1219;
--bui-bg-warning: #302008;
--bui-bg-success: #132d21;
--bui-fg-primary: var(--bui-white);
--bui-fg-secondary: #9e9e9e;
--bui-fg-disabled: #575757;
--bui-fg-solid: var(--bui-black);
--bui-fg-solid-disabled: #072f15;
--bui-fg-danger: #e22b2b;
--bui-fg-warning: #e36d05;
--bui-fg-success: #1db954;
--bui-border-2: #373737;
--bui-border-danger: #f87a7a;
--bui-border-warning: #e36d05;
--bui-border-success: #53db83;
--bui-ring: rgba(255, 255, 255, 0.2);
}
@@ -0,0 +1,108 @@
# no-deprecated-bui-tokens
Warns when a deprecated `@backstage/ui` CSS token is referenced inside a JS/TS string or template literal.
The `@backstage/ui` design token system has been updated with a new set of semantic color families. The old tokens still work for backward compatibility, but they are scheduled for removal in a future major version.
## Rule Details
This rule reports a warning for any string value that contains a reference to a deprecated BUI CSS custom property, such as `var(--bui-bg-solid)` or `var(--bui-fg-danger)`.
Examples of **incorrect** code for this rule:
```js
// Deprecated background token
const style = { background: 'var(--bui-bg-solid)' };
// Deprecated foreground token
const style = { color: 'var(--bui-fg-danger)' };
// Deprecated token in a template literal
const css = `border: 1px solid var(--bui-border-danger)`;
```
Examples of **correct** code for this rule:
```js
// New accent family
const style = { background: 'var(--bui-accent-bg)' };
// New semantic negative family
const style = { color: 'var(--bui-negative-fg-subdued)' };
// New semantic positive family
const style = { borderColor: 'var(--bui-positive-border)' };
```
## Migration Guide
Replace deprecated tokens with their equivalents from the new semantic families.
### Neutral backgrounds
The neutral background tokens (`--bui-bg-app`, `--bui-bg-neutral-1..4`) are now the active semantic tokens with updated solid-color values. The `-hover`, `-pressed`, and `-disabled` interaction variants remain deprecated:
| Deprecated | Replacement |
| ----------------------------- | --------------------- |
| `--bui-bg-neutral-1-hover` | _(remove or restyle)_ |
| `--bui-bg-neutral-1-pressed` | _(remove or restyle)_ |
| `--bui-bg-neutral-1-disabled` | _(remove or restyle)_ |
| `--bui-bg-neutral-2-hover` | _(remove or restyle)_ |
| `--bui-bg-neutral-2-pressed` | _(remove or restyle)_ |
| `--bui-bg-neutral-2-disabled` | _(remove or restyle)_ |
| `--bui-bg-neutral-3-hover` | _(remove or restyle)_ |
| `--bui-bg-neutral-3-pressed` | _(remove or restyle)_ |
| `--bui-bg-neutral-3-disabled` | _(remove or restyle)_ |
| `--bui-bg-neutral-4-hover` | _(remove or restyle)_ |
| `--bui-bg-neutral-4-pressed` | _(remove or restyle)_ |
| `--bui-bg-neutral-4-disabled` | _(remove or restyle)_ |
### Foreground
| Deprecated | Replacement |
| ------------------ | ----------------------- |
| `--bui-fg-danger` | `--bui-fg-negative` |
| `--bui-fg-success` | `--bui-fg-positive` |
| `--bui-fg-info` | `--bui-fg-announcement` |
### Accent
| Deprecated | Replacement |
| ------------------------- | -------------------------- |
| `--bui-bg-solid` | `--bui-accent-bg` |
| `--bui-bg-solid-hover` | `--bui-accent-bg-hover` |
| `--bui-bg-solid-disabled` | `--bui-accent-bg-disabled` |
| `--bui-fg-solid` | `--bui-accent-fg` |
| `--bui-fg-solid-disabled` | `--bui-accent-fg-disabled` |
### Positive
| Deprecated | Replacement |
| ------------------------ | --------------------------- |
| `--bui-bg-success` | `--bui-positive-bg-subdued` |
| `--bui-fg-success-on-bg` | `--bui-positive-fg-subdued` |
| `--bui-border-success` | `--bui-positive-border` |
### Negative
| Deprecated | Replacement |
| ----------------------- | --------------------------- |
| `--bui-bg-danger` | `--bui-negative-bg-subdued` |
| `--bui-fg-danger-on-bg` | `--bui-negative-fg-subdued` |
| `--bui-border-danger` | `--bui-negative-border` |
### Warning
| Deprecated | Replacement |
| ------------------------ | -------------------------- |
| `--bui-bg-warning` | `--bui-warning-bg-subdued` |
| `--bui-fg-warning-on-bg` | `--bui-warning-fg-subdued` |
| `--bui-border-warning` | `--bui-warning-border` |
### Announcement
| Deprecated | Replacement |
| --------------------- | ------------------------------- |
| `--bui-bg-info` | `--bui-announcement-bg-subdued` |
| `--bui-fg-info-on-bg` | `--bui-announcement-fg-subdued` |
| `--bui-border-info` | `--bui-announcement-border` |
+2
View File
@@ -25,6 +25,7 @@ module.exports = {
'@backstage/no-mixed-plugin-imports': 'warn',
'@backstage/no-ui-css-imports-in-non-frontend': 'error',
'@backstage/no-self-package-imports': 'error',
'@backstage/no-deprecated-bui-tokens': 'warn',
},
},
},
@@ -36,5 +37,6 @@ module.exports = {
'no-mixed-plugin-imports': require('./rules/no-mixed-plugin-imports'),
'no-ui-css-imports-in-non-frontend': require('./rules/no-ui-css-imports-in-non-frontend'),
'no-self-package-imports': require('./rules/no-self-package-imports'),
'no-deprecated-bui-tokens': require('./rules/no-deprecated-bui-tokens'),
},
};
@@ -0,0 +1,117 @@
/*
* Copyright 2025 The Backstage Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// @ts-check
/** @type {string[]} */
const DEPRECATED_TOKENS = [
'--bui-bg-solid',
'--bui-bg-solid-hover',
'--bui-bg-solid-pressed',
'--bui-bg-solid-disabled',
'--bui-bg-neutral-1-hover',
'--bui-bg-neutral-1-pressed',
'--bui-bg-neutral-1-disabled',
'--bui-bg-neutral-2-hover',
'--bui-bg-neutral-2-pressed',
'--bui-bg-neutral-2-disabled',
'--bui-bg-neutral-3-hover',
'--bui-bg-neutral-3-pressed',
'--bui-bg-neutral-3-disabled',
'--bui-bg-neutral-4-hover',
'--bui-bg-neutral-4-pressed',
'--bui-bg-neutral-4-disabled',
'--bui-bg-danger',
'--bui-bg-warning',
'--bui-bg-success',
'--bui-bg-info',
'--bui-fg-solid',
'--bui-fg-solid-disabled',
'--bui-fg-danger-on-bg',
'--bui-fg-warning-on-bg',
'--bui-fg-success-on-bg',
'--bui-fg-info-on-bg',
'--bui-fg-danger',
'--bui-fg-success',
'--bui-fg-info',
'--bui-border-info',
'--bui-border-danger',
'--bui-border-warning',
'--bui-border-success',
'--bui-shadow',
];
const DEPRECATED_SET = new Set(DEPRECATED_TOKENS);
/**
* Extracts all CSS custom property names referenced inside a string value,
* e.g. "var(--bui-bg-solid)" → ["--bui-bg-solid"]
* @param {string} value
* @returns {string[]}
*/
function extractTokenNames(value) {
const matches = value.match(/--bui-[\w-]+/g);
return matches ?? [];
}
/** @type {import('eslint').Rule.RuleModule} */
module.exports = {
meta: {
type: 'suggestion',
docs: {
description:
'Warn when deprecated Backstage UI CSS tokens are referenced in JS/TS string literals.',
url: 'https://github.com/backstage/backstage/blob/master/packages/eslint-plugin/docs/rules/no-deprecated-bui-tokens.md',
},
messages: {
deprecated:
"'{{token}}' is a deprecated BUI token. Replace it with the appropriate current BUI token for its usage (for example, a semantic intent, surface/background, or shadow token); see this rule's migration guide for the correct mapping.",
},
schema: [],
},
create(context) {
/**
* @param {import('estree').Node} node
* @param {string} value
*/
function checkValue(node, value) {
for (const token of extractTokenNames(value)) {
if (DEPRECATED_SET.has(token)) {
context.report({
node,
messageId: 'deprecated',
data: { token },
});
}
}
}
return {
Literal(node) {
if (typeof node.value === 'string') {
checkValue(node, node.value);
}
},
TemplateElement(node) {
if (node.value?.cooked) {
checkValue(node, node.value.cooked);
}
},
};
},
};
@@ -0,0 +1,257 @@
/*
* Copyright 2025 The Backstage Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { RuleTester } from 'eslint';
import rule from '../rules/no-deprecated-bui-tokens';
const ruleTester = new RuleTester({
parserOptions: {
sourceType: 'module',
ecmaVersion: 2021,
},
});
ruleTester.run('no-deprecated-bui-tokens', rule, {
valid: [
// Non-deprecated tokens — should not warn
{ code: `const s = 'var(--bui-fg-primary)'` },
{ code: `const s = 'var(--bui-fg-secondary)'` },
{ code: `const s = 'var(--bui-fg-disabled)'` },
{ code: `const s = 'var(--bui-fg-warning)'` },
{ code: `const s = 'var(--bui-fg-positive)'` },
{ code: `const s = 'var(--bui-fg-negative)'` },
{ code: `const s = 'var(--bui-fg-announcement)'` },
{ code: `const s = 'var(--bui-border-1)'` },
{ code: `const s = 'var(--bui-border-2)'` },
{ code: `const s = 'var(--bui-accent-bg)'` },
{ code: `const s = 'var(--bui-accent-bg-hover)'` },
{ code: `const s = 'var(--bui-accent-bg-disabled)'` },
{ code: `const s = 'var(--bui-accent-fg)'` },
{ code: `const s = 'var(--bui-accent-fg-disabled)'` },
{ code: `const s = 'var(--bui-negative-bg)'` },
{ code: `const s = 'var(--bui-positive-bg)'` },
{ code: `const s = 'var(--bui-warning-bg)'` },
{ code: `const s = 'var(--bui-announcement-bg)'` },
{ code: `const s = 'var(--bui-gray-1)'` },
{ code: `const s = 'var(--bui-bg-app)'` },
{ code: `const s = 'var(--bui-bg-neutral-1)'` },
{ code: `const s = 'var(--bui-bg-neutral-2)'` },
{ code: `const s = 'var(--bui-bg-neutral-3)'` },
{ code: `const s = 'var(--bui-bg-neutral-4)'` },
// Unrelated strings — should not warn
{ code: `const s = 'some-other-string'` },
{ code: `const n = 42` },
],
invalid: [
// Plain string literals
{
code: `const s = 'var(--bui-bg-solid)'`,
errors: [{ messageId: 'deprecated', data: { token: '--bui-bg-solid' } }],
},
{
code: `const s = 'var(--bui-bg-solid-hover)'`,
errors: [
{ messageId: 'deprecated', data: { token: '--bui-bg-solid-hover' } },
],
},
{
code: `const s = 'var(--bui-bg-solid-pressed)'`,
errors: [
{ messageId: 'deprecated', data: { token: '--bui-bg-solid-pressed' } },
],
},
{
code: `const s = 'var(--bui-bg-solid-disabled)'`,
errors: [
{
messageId: 'deprecated',
data: { token: '--bui-bg-solid-disabled' },
},
],
},
{
code: `const s = 'var(--bui-bg-neutral-2-hover)'`,
errors: [
{
messageId: 'deprecated',
data: { token: '--bui-bg-neutral-2-hover' },
},
],
},
{
code: `const s = 'var(--bui-bg-neutral-3-pressed)'`,
errors: [
{
messageId: 'deprecated',
data: { token: '--bui-bg-neutral-3-pressed' },
},
],
},
{
code: `const s = 'var(--bui-bg-neutral-4-disabled)'`,
errors: [
{
messageId: 'deprecated',
data: { token: '--bui-bg-neutral-4-disabled' },
},
],
},
{
code: `const s = 'var(--bui-bg-danger)'`,
errors: [{ messageId: 'deprecated', data: { token: '--bui-bg-danger' } }],
},
{
code: `const s = 'var(--bui-bg-warning)'`,
errors: [
{ messageId: 'deprecated', data: { token: '--bui-bg-warning' } },
],
},
{
code: `const s = 'var(--bui-bg-success)'`,
errors: [
{ messageId: 'deprecated', data: { token: '--bui-bg-success' } },
],
},
{
code: `const s = 'var(--bui-bg-info)'`,
errors: [{ messageId: 'deprecated', data: { token: '--bui-bg-info' } }],
},
{
code: `const s = 'var(--bui-fg-solid)'`,
errors: [{ messageId: 'deprecated', data: { token: '--bui-fg-solid' } }],
},
{
code: `const s = 'var(--bui-fg-solid-disabled)'`,
errors: [
{ messageId: 'deprecated', data: { token: '--bui-fg-solid-disabled' } },
],
},
{
code: `const s = 'var(--bui-fg-danger-on-bg)'`,
errors: [
{ messageId: 'deprecated', data: { token: '--bui-fg-danger-on-bg' } },
],
},
{
code: `const s = 'var(--bui-fg-warning-on-bg)'`,
errors: [
{ messageId: 'deprecated', data: { token: '--bui-fg-warning-on-bg' } },
],
},
{
code: `const s = 'var(--bui-fg-success-on-bg)'`,
errors: [
{ messageId: 'deprecated', data: { token: '--bui-fg-success-on-bg' } },
],
},
{
code: `const s = 'var(--bui-fg-info-on-bg)'`,
errors: [
{ messageId: 'deprecated', data: { token: '--bui-fg-info-on-bg' } },
],
},
{
code: `const s = 'var(--bui-fg-danger)'`,
errors: [{ messageId: 'deprecated', data: { token: '--bui-fg-danger' } }],
},
{
code: `const s = 'var(--bui-fg-success)'`,
errors: [
{ messageId: 'deprecated', data: { token: '--bui-fg-success' } },
],
},
{
code: `const s = 'var(--bui-fg-info)'`,
errors: [{ messageId: 'deprecated', data: { token: '--bui-fg-info' } }],
},
{
code: `const s = 'var(--bui-border-info)'`,
errors: [
{ messageId: 'deprecated', data: { token: '--bui-border-info' } },
],
},
{
code: `const s = 'var(--bui-border-danger)'`,
errors: [
{ messageId: 'deprecated', data: { token: '--bui-border-danger' } },
],
},
{
code: `const s = 'var(--bui-border-warning)'`,
errors: [
{ messageId: 'deprecated', data: { token: '--bui-border-warning' } },
],
},
{
code: `const s = 'var(--bui-border-success)'`,
errors: [
{ messageId: 'deprecated', data: { token: '--bui-border-success' } },
],
},
{
code: `const s = 'var(--bui-shadow)'`,
errors: [{ messageId: 'deprecated', data: { token: '--bui-shadow' } }],
},
// Template literals
{
code: 'const s = `var(--bui-bg-solid)`',
errors: [{ messageId: 'deprecated', data: { token: '--bui-bg-solid' } }],
},
{
code: 'const s = `var(--bui-fg-danger)`',
errors: [{ messageId: 'deprecated', data: { token: '--bui-fg-danger' } }],
},
{
code: 'const s = `border: 1px solid var(--bui-border-danger)`',
errors: [
{ messageId: 'deprecated', data: { token: '--bui-border-danger' } },
],
},
// Multiple deprecated tokens in one string — one error per token
{
code: `const s = 'background: var(--bui-bg-solid); color: var(--bui-fg-solid)'`,
errors: [
{ messageId: 'deprecated', data: { token: '--bui-bg-solid' } },
{ messageId: 'deprecated', data: { token: '--bui-fg-solid' } },
],
},
// Inline style usage patterns (JSX)
{
code: `const el = <div style={{ background: 'var(--bui-bg-danger)' }} />`,
parserOptions: {
sourceType: 'module',
ecmaVersion: 2021,
ecmaFeatures: { jsx: true },
},
errors: [{ messageId: 'deprecated', data: { token: '--bui-bg-danger' } }],
},
{
code: `const el = <div style={{ color: 'var(--bui-fg-success)' }} />`,
parserOptions: {
sourceType: 'module',
ecmaVersion: 2021,
ecmaFeatures: { jsx: true },
},
errors: [
{ messageId: 'deprecated', data: { token: '--bui-fg-success' } },
],
},
],
});
+2 -1
View File
@@ -3,7 +3,8 @@ module.exports = {
extends: ['plugin:storybook/recommended'],
rules: {
'react/forbid-elements': 'off',
'@backstage/no-mixed-plugin-imports': 'off'
'@backstage/no-mixed-plugin-imports': 'off',
'@backstage/no-deprecated-bui-tokens': 'warn',
},
};
+269 -172
View File
@@ -14,192 +14,289 @@
* limitations under the License.
*/
import preview from '../../../../.storybook/preview';
import { Box } from '../components/Box';
import { Flex } from '../components/Flex';
import { Text } from '../components/Text';
const meta = preview.meta({
title: 'Backstage UI/Colors',
tags: ['!manifest'],
});
/**
* A `<div>` styled with `background: var(--bui-bg-inherit)` should always
* resolve to the same color as the surrounding bg provider — at every level
* of the neutral chain and inside intent surfaces.
*/
const Probe = ({ label }: { label: string }) => (
type SwatchItem = { label: string; token: string };
const Swatch = ({ label, token }: SwatchItem) => (
<div
style={{
backgroundColor: 'var(--bui-bg-inherit)',
padding: '0.5rem 0.75rem',
borderRadius: '0.25rem',
outline: '1px dashed var(--bui-fg-secondary)',
display: 'flex',
alignItems: 'center',
gap: '0.75rem',
padding: '0.375rem 0',
}}
>
<Text>{label}</Text>
<div
style={{
width: 28,
height: 28,
borderRadius: 6,
backgroundColor: `var(${token})`,
border: '1px solid rgba(127 127 127 / 20%)',
flexShrink: 0,
}}
/>
<div style={{ display: 'flex', flexDirection: 'column', gap: 1 }}>
<span
style={{
fontSize: '0.8125rem',
color: 'var(--bui-fg-primary)',
lineHeight: 1.3,
}}
>
{label}
</span>
<span
style={{
fontSize: '0.6875rem',
color: 'var(--bui-fg-secondary)',
fontFamily: 'var(--bui-font-monospace)',
lineHeight: 1.3,
}}
>
{token}
</span>
</div>
</div>
);
export const Default = meta.story({
const Section = ({
title,
tokens,
}: {
title: string;
tokens: SwatchItem[];
}) => (
<div style={{ display: 'flex', flexDirection: 'column', minWidth: 260 }}>
<div
style={{
fontSize: '0.75rem',
fontWeight: 600,
textTransform: 'uppercase',
letterSpacing: '0.06em',
color: 'var(--bui-fg-secondary)',
padding: '0.5rem 0',
marginBottom: '0.25rem',
borderBottom: '1px solid var(--bui-border-1)',
}}
>
{title}
</div>
{tokens.map(t => (
<Swatch key={t.token} {...t} />
))}
</div>
);
export const All = meta.story({
name: 'All Colors',
render: () => (
<div style={{ backgroundColor: 'var(--bui-bg-app)' }}>
<Box p="4" style={{ backgroundColor: 'var(--bui-bg-neutral-1)' }}>
<Flex direction="row" gap="4" align="center">
<Text>Neutral 1</Text>
<Flex
px="2"
py="1"
style={{ backgroundColor: 'var(--bui-bg-neutral-1-hover)' }}
>
<Text>Hover</Text>
</Flex>
<Flex
px="2"
py="1"
style={{ backgroundColor: 'var(--bui-bg-neutral-1-pressed)' }}
>
<Text>Pressed</Text>
</Flex>
<Flex
px="2"
py="1"
style={{ backgroundColor: 'var(--bui-bg-neutral-1-disabled)' }}
>
<Text style={{ color: 'var(--bui-fg-disabled)' }}>Disabled</Text>
</Flex>
</Flex>
<Box
p="4"
mt="4"
style={{ backgroundColor: 'var(--bui-bg-neutral-2)' }}
>
<Flex direction="row" gap="4" align="center">
<Text>Neutral 2</Text>
<Flex
px="2"
py="1"
style={{ backgroundColor: 'var(--bui-bg-neutral-2-hover)' }}
>
<Text>Hover</Text>
</Flex>
<Flex
px="2"
py="1"
style={{ backgroundColor: 'var(--bui-bg-neutral-2-pressed)' }}
>
<Text>Pressed</Text>
</Flex>
<Flex
px="2"
py="1"
style={{ backgroundColor: 'var(--bui-bg-neutral-2-disabled)' }}
>
<Text style={{ color: 'var(--bui-fg-disabled)' }}>Disabled</Text>
</Flex>
</Flex>
<Box
p="4"
mt="4"
style={{ backgroundColor: 'var(--bui-bg-neutral-3)' }}
>
<Flex direction="row" gap="4" align="center">
<Text>Neutral 3</Text>
<Flex
px="2"
py="1"
style={{ backgroundColor: 'var(--bui-bg-neutral-3-hover)' }}
>
<Text>Hover</Text>
</Flex>
<Flex
px="2"
py="1"
style={{ backgroundColor: 'var(--bui-bg-neutral-3-pressed)' }}
>
<Text>Pressed</Text>
</Flex>
<Flex
px="2"
py="1"
style={{ backgroundColor: 'var(--bui-bg-neutral-3-disabled)' }}
>
<Text style={{ color: 'var(--bui-fg-disabled)' }}>
Disabled
</Text>
</Flex>
</Flex>
<Box
p="4"
mt="4"
style={{ backgroundColor: 'var(--bui-bg-neutral-4)' }}
>
<Flex direction="row" gap="4" align="center">
<Text>Neutral 4</Text>
<Flex
px="2"
py="1"
style={{ backgroundColor: 'var(--bui-bg-neutral-4-hover)' }}
>
<Text>Hover</Text>
</Flex>
<Flex
px="2"
py="1"
style={{ backgroundColor: 'var(--bui-bg-neutral-4-pressed)' }}
>
<Text>Pressed</Text>
</Flex>
<Flex
px="2"
py="1"
style={{
backgroundColor: 'var(--bui-bg-neutral-4-disabled)',
}}
>
<Text style={{ color: 'var(--bui-fg-disabled)' }}>
Disabled
</Text>
</Flex>
</Flex>
</Box>
</Box>
</Box>
</Box>
<div
style={{
display: 'grid',
gridTemplateColumns: 'repeat(auto-fill, minmax(260px, 1fr))',
gap: '2.5rem 3rem',
padding: '2rem',
}}
>
<Section
title="Gray Scale"
tokens={[
{ label: 'Gray 1', token: '--bui-gray-1' },
{ label: 'Gray 2', token: '--bui-gray-2' },
{ label: 'Gray 3', token: '--bui-gray-3' },
{ label: 'Gray 4', token: '--bui-gray-4' },
{ label: 'Gray 5', token: '--bui-gray-5' },
{ label: 'Gray 6', token: '--bui-gray-6' },
{ label: 'Gray 7', token: '--bui-gray-7' },
{ label: 'Gray 8', token: '--bui-gray-8' },
{ label: 'Gray 9', token: '--bui-gray-9' },
{ label: 'Gray 10', token: '--bui-gray-10' },
{ label: 'Gray 11', token: '--bui-gray-11' },
]}
/>
<Section
title="Neutral Backgrounds"
tokens={[
{ label: 'App', token: '--bui-bg-app' },
{ label: 'Neutral 1', token: '--bui-bg-neutral-1' },
{ label: 'Neutral 2', token: '--bui-bg-neutral-2' },
{ label: 'Neutral 3', token: '--bui-bg-neutral-3' },
{ label: 'Neutral 4', token: '--bui-bg-neutral-4' },
]}
/>
<Section
title="Foreground"
tokens={[
{ label: 'Primary', token: '--bui-fg-primary' },
{ label: 'Secondary', token: '--bui-fg-secondary' },
{ label: 'Disabled', token: '--bui-fg-disabled' },
{ label: 'Positive', token: '--bui-fg-positive' },
{ label: 'Negative', token: '--bui-fg-negative' },
{ label: 'Warning', token: '--bui-fg-warning' },
{ label: 'Announcement', token: '--bui-fg-announcement' },
]}
/>
<Section
title="Border"
tokens={[
{ label: 'Border 1', token: '--bui-border-1' },
{ label: 'Border 2', token: '--bui-border-2' },
]}
/>
<Section
title="Accent"
tokens={[
{ label: 'Bg', token: '--bui-accent-bg' },
{ label: 'Bg - Hover', token: '--bui-accent-bg-hover' },
{ label: 'Bg - Disabled', token: '--bui-accent-bg-disabled' },
{ label: 'Fg', token: '--bui-accent-fg' },
{ label: 'Fg - Disabled', token: '--bui-accent-fg-disabled' },
]}
/>
<Section
title="Announcement"
tokens={[
{ label: 'Bg - Base', token: '--bui-announcement-bg' },
{
label: 'Bg - Base - Hover',
token: '--bui-announcement-bg-hover',
},
{
label: 'Bg - Base - Disabled',
token: '--bui-announcement-bg-disabled',
},
{ label: 'Bg - Subdued', token: '--bui-announcement-bg-subdued' },
{
label: 'Bg - Subdued - Hover',
token: '--bui-announcement-bg-subdued-hover',
},
{
label: 'Bg - Subdued - Disabled',
token: '--bui-announcement-bg-subdued-disabled',
},
{ label: 'Border', token: '--bui-announcement-border' },
{ label: 'Fg - On Base', token: '--bui-announcement-fg' },
{
label: 'Fg - On Base - Disabled',
token: '--bui-announcement-fg-disabled',
},
{
label: 'Fg - On Subdued',
token: '--bui-announcement-fg-subdued',
},
{
label: 'Fg - On Subdued - Disabled',
token: '--bui-announcement-fg-subdued-disabled',
},
]}
/>
<Section
title="Warning"
tokens={[
{ label: 'Bg - Base', token: '--bui-warning-bg' },
{ label: 'Bg - Base - Hover', token: '--bui-warning-bg-hover' },
{
label: 'Bg - Base - Disabled',
token: '--bui-warning-bg-disabled',
},
{ label: 'Bg - Subdued', token: '--bui-warning-bg-subdued' },
{
label: 'Bg - Subdued - Hover',
token: '--bui-warning-bg-subdued-hover',
},
{
label: 'Bg - Subdued - Disabled',
token: '--bui-warning-bg-subdued-disabled',
},
{ label: 'Border', token: '--bui-warning-border' },
{ label: 'Fg - On Base', token: '--bui-warning-fg' },
{
label: 'Fg - On Base - Disabled',
token: '--bui-warning-fg-disabled',
},
{ label: 'Fg - On Subdued', token: '--bui-warning-fg-subdued' },
{
label: 'Fg - On Subdued - Disabled',
token: '--bui-warning-fg-subdued-disabled',
},
]}
/>
<Section
title="Negative"
tokens={[
{ label: 'Bg - Base', token: '--bui-negative-bg' },
{ label: 'Bg - Base - Hover', token: '--bui-negative-bg-hover' },
{
label: 'Bg - Base - Disabled',
token: '--bui-negative-bg-disabled',
},
{ label: 'Bg - Subdued', token: '--bui-negative-bg-subdued' },
{
label: 'Bg - Subdued - Hover',
token: '--bui-negative-bg-subdued-hover',
},
{
label: 'Bg - Subdued - Disabled',
token: '--bui-negative-bg-subdued-disabled',
},
{ label: 'Border', token: '--bui-negative-border' },
{ label: 'Fg - On Base', token: '--bui-negative-fg' },
{
label: 'Fg - On Base - Disabled',
token: '--bui-negative-fg-disabled',
},
{ label: 'Fg - On Subdued', token: '--bui-negative-fg-subdued' },
{
label: 'Fg - On Subdued - Disabled',
token: '--bui-negative-fg-subdued-disabled',
},
]}
/>
<Section
title="Positive"
tokens={[
{ label: 'Bg - Base', token: '--bui-positive-bg' },
{ label: 'Bg - Base - Hover', token: '--bui-positive-bg-hover' },
{
label: 'Bg - Base - Disabled',
token: '--bui-positive-bg-disabled',
},
{ label: 'Bg - Subdued', token: '--bui-positive-bg-subdued' },
{
label: 'Bg - Subdued - Hover',
token: '--bui-positive-bg-subdued-hover',
},
{
label: 'Bg - Subdued - Disabled',
token: '--bui-positive-bg-subdued-disabled',
},
{ label: 'Border', token: '--bui-positive-border' },
{ label: 'Fg - On Base', token: '--bui-positive-fg' },
{
label: 'Fg - On Base - Disabled',
token: '--bui-positive-fg-disabled',
},
{ label: 'Fg - On Subdued', token: '--bui-positive-fg-subdued' },
{
label: 'Fg - On Subdued - Disabled',
token: '--bui-positive-fg-subdued-disabled',
},
]}
/>
</div>
),
});
export const BgInherit = meta.story({
render: () => (
<Flex direction="column" gap="4">
<Probe label="App level (no provider) — resolves to --bui-bg-app" />
<Box bg="neutral" p="4">
<Flex direction="column" gap="3">
<Probe label="Inside neutral-1 — resolves to --bui-bg-neutral-1" />
<Box bg="neutral" p="4">
<Flex direction="column" gap="3">
<Probe label="Inside neutral-2 — resolves to --bui-bg-neutral-2" />
<Box bg="neutral" p="4">
<Probe label="Inside neutral-3 — resolves to --bui-bg-neutral-3" />
</Box>
</Flex>
</Box>
</Flex>
</Box>
<Box bg="danger" p="4">
<Probe label="Inside danger — resolves to --bui-bg-danger" />
</Box>
<Box bg="warning" p="4">
<Probe label="Inside warning — resolves to --bui-bg-warning" />
</Box>
<Box bg="success" p="4">
<Probe label="Inside success — resolves to --bui-bg-success" />
</Box>
</Flex>
),
});
+184 -68
View File
@@ -67,150 +67,266 @@
--bui-radius-6: calc(1.25rem);
--bui-radius-full: 9999px;
/* Animations */
--bui-animate-pulse: pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite;
/* Base Colors */
--bui-black: #000000;
--bui-white: #ffffff;
--bui-ring: #1f5493;
--bui-scrollbar: #a0a0a03b;
--bui-scrollbar-thumb: #a0a0a0;
/* Solid background colors */
/* Gray scale */
--bui-gray-1: #fafafa;
--bui-gray-2: #f5f5f5;
--bui-gray-3: #e5e5e5;
--bui-gray-4: #d4d4d4;
--bui-gray-5: #a1a1a1;
--bui-gray-6: #737373;
--bui-gray-7: #525252;
--bui-gray-8: #404040;
--bui-gray-9: #262626;
--bui-gray-10: #171717;
--bui-gray-11: #0a0a0a;
/* Neutral background colors */
--bui-bg-app: #f5f5f5;
--bui-bg-neutral-1: var(--bui-white);
--bui-bg-neutral-2: #f7f7f7;
--bui-bg-neutral-3: var(--bui-white);
--bui-bg-neutral-4: #f7f7f7;
/* Foreground colors */
--bui-fg-primary: var(--bui-black);
--bui-fg-secondary: #696969;
--bui-fg-disabled: #aaaaaa;
--bui-fg-positive: #1abc54;
--bui-fg-negative: #ee3a4c;
--bui-fg-warning: #f18900;
--bui-fg-announcement: #2a86f3;
/* Border colors */
--bui-border-1: var(--bui-gray-3);
--bui-border-2: var(--bui-gray-6);
/* Accent */
--bui-accent-bg: #1f5493;
--bui-accent-bg-hover: #163a66;
--bui-accent-bg-disabled: #163a66;
--bui-accent-fg: #ffffff;
--bui-accent-fg-disabled: #98a8bc;
/* Announcement */
--bui-announcement-bg: #0d72ea;
--bui-announcement-bg-hover: #2b88f5;
--bui-announcement-bg-disabled: #0d72ea;
--bui-announcement-bg-subdued: #c8e0fc;
--bui-announcement-bg-subdued-hover: #e0edfd;
--bui-announcement-bg-subdued-disabled: #c8e0fc;
--bui-announcement-border: #549ef4;
--bui-announcement-fg: #ffffff;
--bui-announcement-fg-disabled: #a4ccfb;
--bui-announcement-fg-subdued: #173da6;
--bui-announcement-fg-subdued-disabled: #7391e3;
/* Warning */
--bui-warning-bg: #ff9400;
--bui-warning-bg-hover: #ffb656;
--bui-warning-bg-disabled: #ff9400;
--bui-warning-bg-subdued: #ffedd5;
--bui-warning-bg-subdued-hover: #f8ddb9;
--bui-warning-bg-subdued-disabled: #f8ddb9;
--bui-warning-border: #ff9400;
--bui-warning-fg: #000000;
--bui-warning-fg-disabled: #aa4d00;
--bui-warning-fg-subdued: #aa4d00;
--bui-warning-fg-subdued-disabled: #e3a572;
/* Negative */
--bui-negative-bg: #dc2626;
--bui-negative-bg-hover: #f44b4b;
--bui-negative-bg-disabled: #ff8686;
--bui-negative-bg-subdued: #ffcbcb;
--bui-negative-bg-subdued-hover: #f7b6b6;
--bui-negative-bg-subdued-disabled: #f7b6b6;
--bui-negative-border: #d06565;
--bui-negative-fg: #ffffff;
--bui-negative-fg-disabled: #f7b6b6;
--bui-negative-fg-subdued: #991919;
--bui-negative-fg-subdued-disabled: #bb7272;
/* Positive */
--bui-positive-bg: #1ed760;
--bui-positive-bg-hover: #3be477;
--bui-positive-bg-disabled: #1abc54;
--bui-positive-bg-subdued: #96f0b6;
--bui-positive-bg-subdued-hover: #c5f7d7;
--bui-positive-bg-subdued-disabled: #96f0b6;
--bui-positive-border: #54a671;
--bui-positive-fg: #000000;
--bui-positive-fg-disabled: #0c632b;
--bui-positive-fg-subdued: #0c632b;
--bui-positive-fg-subdued-disabled: #4b9666;
/* Deprecated tokens */
--bui-bg-solid: #1f5493;
--bui-bg-solid-hover: #163a66;
--bui-bg-solid-pressed: #0f2b4e;
--bui-bg-solid-disabled: #163a66;
/* Neutral background colors */
--bui-bg-app: #f8f8f8;
--bui-bg-neutral-1: #fff;
--bui-bg-neutral-1-hover: oklch(0% 0 0 / 6%);
--bui-bg-neutral-1-pressed: oklch(0% 0 0 / 12%);
--bui-bg-neutral-1-disabled: oklch(0% 0 0 / 6%);
--bui-bg-neutral-2: oklch(0% 0 0 / 6%);
--bui-bg-neutral-2-hover: oklch(0% 0 0 / 12%);
--bui-bg-neutral-2-pressed: oklch(0% 0 0 / 16%);
--bui-bg-neutral-2-disabled: oklch(0% 0 0 / 6%);
--bui-bg-neutral-3: oklch(0% 0 0 / 6%);
--bui-bg-neutral-3-hover: oklch(0% 0 0 / 12%);
--bui-bg-neutral-3-pressed: oklch(0% 0 0 / 16%);
--bui-bg-neutral-3-disabled: oklch(0% 0 0 / 6%);
--bui-bg-neutral-4: oklch(0% 0 0 / 6%);
--bui-bg-neutral-4-hover: oklch(0% 0 0 / 12%);
--bui-bg-neutral-4-pressed: oklch(0% 0 0 / 16%);
--bui-bg-neutral-4-disabled: oklch(0% 0 0 / 6%);
/* Status background colors */
--bui-bg-danger: #ffe2e2;
--bui-bg-warning: #ffedd5;
--bui-bg-success: #dcfce7;
--bui-bg-info: #dbeafe;
/* Foreground colors */
--bui-fg-primary: var(--bui-black);
--bui-fg-secondary: oklch(0% 0 0 / 50%);
--bui-fg-disabled: oklch(0% 0 0 / 28%);
--bui-fg-solid: var(--bui-white);
--bui-fg-solid-disabled: #98a8bc;
/* Foreground Statuses */
--bui-fg-danger-on-bg: #991919;
--bui-fg-warning-on-bg: #92310a;
--bui-fg-success-on-bg: #116932;
--bui-fg-info-on-bg: #173da6;
--bui-fg-danger: #ec3b18;
--bui-fg-warning: #ef7a32;
--bui-fg-success: #1aaf4f;
--bui-fg-info: #0d74ce;
/* Border colors */
--bui-border-1: #d5d5d5;
--bui-border-2: #bababa;
--bui-border-info: #7ea9d6;
--bui-border-danger: #f87a7a;
--bui-border-warning: #e36d05;
--bui-border-success: #53db83;
/* Special colors */
--bui-ring: #1f5493;
--bui-scrollbar: #a0a0a03b;
--bui-scrollbar-thumb: #a0a0a0;
/* Shadows */
--bui-shadow: 0 10px 15px -3px rgba(0 0 0 / 0.1),
0 4px 6px -4px rgba(0 0 0 / 0.1);
--bui-animate-pulse: pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite;
}
/* Dark theme tokens */
[data-theme-mode='dark'] {
/* Solid background colors */
/* Base colors */
--bui-ring: #1f5493;
--bui-scrollbar: #3636363a;
--bui-scrollbar-thumb: #575757;
/* Neutral background colors */
--bui-bg-app: #333333;
--bui-bg-neutral-1: #1a1a1a;
--bui-bg-neutral-2: #282828;
--bui-bg-neutral-3: #393939;
--bui-bg-neutral-4: #474747;
/* Foreground colors */
--bui-fg-primary: var(--bui-white);
--bui-fg-secondary: #a3a3a3;
--bui-fg-disabled: var(--bui-white);
--bui-fg-positive: #21b656;
--bui-fg-negative: #ee3a4c;
--bui-fg-warning: #f18900;
--bui-fg-announcement: #2a86f3;
/* Border colors */
--bui-border-1: var(--bui-gray-6);
--bui-border-2: var(--bui-gray-5);
/* Accent */
--bui-accent-bg: #9cc9ff;
--bui-accent-bg-hover: #83b9fd;
--bui-accent-bg-disabled: #3b6293;
--bui-accent-fg: #101821;
--bui-accent-fg-disabled: #6191cc;
/* Announcement */
--bui-announcement-bg: #0d72ea;
--bui-announcement-bg-hover: #2b88f5;
--bui-announcement-bg-disabled: #0d72ea;
--bui-announcement-bg-subdued: #052a56;
--bui-announcement-bg-subdued-hover: #0c3d77;
--bui-announcement-bg-subdued-disabled: #052a56;
--bui-announcement-border: #2363af;
--bui-announcement-fg: #ffffff;
--bui-announcement-fg-disabled: #70b8ff;
--bui-announcement-fg-subdued: #70b8ff;
--bui-announcement-fg-subdued-disabled: #4275a6;
/* Warning */
--bui-warning-bg: #ffa42c;
--bui-warning-bg-hover: #ffb656;
--bui-warning-bg-disabled: #ffb656;
--bui-warning-bg-subdued: #491e00;
--bui-warning-bg-subdued-hover: #612901;
--bui-warning-bg-subdued-disabled: #582400;
--bui-warning-border: #7c4903;
--bui-warning-fg: #000000;
--bui-warning-fg-disabled: #aa4d00;
--bui-warning-fg-subdued: #f2ab4a;
--bui-warning-fg-subdued-disabled: #aa4d00;
/* Negative */
--bui-negative-bg: #dc2626;
--bui-negative-bg-hover: #f44b4b;
--bui-negative-bg-disabled: #dc2626;
--bui-negative-bg-subdued: #350708;
--bui-negative-bg-subdued-hover: #5e1a1b;
--bui-negative-bg-subdued-disabled: #5e1a1b;
--bui-negative-border: #6f101c;
--bui-negative-fg: #ffffff;
--bui-negative-fg-disabled: #f7b6b6;
--bui-negative-fg-subdued: #fca5a5;
--bui-negative-fg-subdued-disabled: #bb7272;
/* Positive */
--bui-positive-bg: #1ed760;
--bui-positive-bg-hover: #3be477;
--bui-positive-bg-disabled: #1abc54;
--bui-positive-bg-subdued: #073116;
--bui-positive-bg-subdued-hover: #0b431f;
--bui-positive-bg-subdued-disabled: #073116;
--bui-positive-border: #136d33;
--bui-positive-fg: #000000;
--bui-positive-fg-disabled: #0c632b;
--bui-positive-fg-subdued: #8ddeaa;
--bui-positive-fg-subdued-disabled: #509c6b;
/* Deprecated tokens */
--bui-bg-solid: #9cc9ff;
--bui-bg-solid-hover: #83b9fd;
--bui-bg-solid-pressed: #83b9fd;
--bui-bg-solid-disabled: #1b3d68;
/* Neutral background colors */
--bui-bg-app: #333333;
--bui-bg-neutral-1: oklch(100% 0 0 / 10%);
--bui-bg-neutral-1-hover: oklch(100% 0 0 / 14%);
--bui-bg-neutral-1-pressed: oklch(100% 0 0 / 20%);
--bui-bg-neutral-1-disabled: oklch(100% 0 0 / 10%);
--bui-bg-neutral-2: oklch(100% 0 0 / 6%);
--bui-bg-neutral-2-hover: oklch(100% 0 0 / 10%);
--bui-bg-neutral-2-pressed: oklch(100% 0 0 / 16%);
--bui-bg-neutral-2-disabled: oklch(100% 0 0 / 6%);
--bui-bg-neutral-3: oklch(100% 0 0 / 8%);
--bui-bg-neutral-3-hover: oklch(100% 0 0 / 12%);
--bui-bg-neutral-3-pressed: oklch(100% 0 0 / 20%);
--bui-bg-neutral-3-disabled: oklch(100% 0 0 / 8%);
--bui-bg-neutral-4: oklch(100% 0 0 / 8%);
--bui-bg-neutral-4-hover: oklch(100% 0 0 / 12%);
--bui-bg-neutral-4-pressed: oklch(100% 0 0 / 20%);
--bui-bg-neutral-4-disabled: oklch(100% 0 0 / 8%);
/* Status background colors */
--bui-bg-danger: #300c0c;
--bui-bg-warning: #302008;
--bui-bg-success: #042713;
--bui-bg-info: #132049;
/* Foreground colors */
--bui-fg-primary: var(--bui-white);
--bui-fg-secondary: oklch(100% 0 0 / 50%);
--bui-fg-disabled: oklch(100% 0 0 / 28%);
--bui-fg-solid: #101821;
--bui-fg-solid-disabled: #6191cc;
/* Foreground statuses */
--bui-fg-danger-on-bg: #fca5a5;
--bui-fg-warning-on-bg: #fdba74;
--bui-fg-success-on-bg: #86efac;
--bui-fg-info-on-bg: #a3cfff;
--bui-fg-danger: #ff5a30;
--bui-fg-warning: #ffa057;
--bui-fg-success: #1ed760;
--bui-fg-info: #70b8ff;
/* Border colors */
--bui-border-1: #434343;
--bui-border-2: #585858;
--bui-border-info: #7ea9d6;
--bui-border-danger: #f87a7a;
--bui-border-warning: #e36d05;
--bui-border-success: #53db83;
/* Special colors */
--bui-ring: #1f5493;
--bui-scrollbar: #3636363a;
--bui-scrollbar-thumb: #575757;
/* Shadows */
--bui-shadow: none;
}
}