ui: starting dark theme

This commit is contained in:
nick-delirium 2025-04-29 14:32:21 +02:00 committed by Delirium
parent d2d886b322
commit c6b0649613
23 changed files with 764 additions and 759 deletions

View file

@ -0,0 +1,64 @@
import React, { createContext, useContext, useState, useEffect, ReactNode } from 'react';
type ThemeType = 'light' | 'dark';
interface ThemeContextType {
theme: ThemeType;
toggleTheme: () => void;
}
const ThemeContext = createContext<ThemeContextType | undefined>(undefined);
export const ThemeProvider: React.FC<{ children: ReactNode }> = ({ children }) => {
const getInitialTheme = (): ThemeType => {
const savedTheme = localStorage.getItem('theme');
if (savedTheme && (savedTheme === 'light' || savedTheme === 'dark')) {
return savedTheme;
}
return window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light';
};
const [theme, setTheme] = useState<ThemeType>(getInitialTheme);
useEffect(() => {
if (theme === 'dark') {
document.documentElement.classList.add('dark');
} else {
document.documentElement.classList.remove('dark');
}
localStorage.setItem('theme', theme);
}, [theme]);
useEffect(() => {
const mediaQuery = window.matchMedia('(prefers-color-scheme: dark)');
const handleChange = (e: MediaQueryListEvent) => {
// Only apply system preference if user hasn't manually set a preference
if (!localStorage.getItem('theme')) {
setTheme(e.matches ? 'dark' : 'light');
}
};
mediaQuery.addEventListener('change', handleChange);
return () => mediaQuery.removeEventListener('change', handleChange);
}, []);
const toggleTheme = () => {
setTheme(prevTheme => (prevTheme === 'dark' ? 'light' : 'dark'));
};
return (
<ThemeContext.Provider value={{ theme, toggleTheme }}>
{children}
</ThemeContext.Provider>
);
};
export const useTheme = (): ThemeContextType => {
const context = useContext(ThemeContext);
if (context === undefined) {
throw new Error('useTheme must be used within a ThemeProvider');
}
return context;
};

View file

@ -44,16 +44,6 @@ function AddCardSelectionModal(props: Props) {
className="addCard"
width={isSaas ? 900 : undefined}
>
{isSaas ? (
<>
<Row gutter={16} justify="center" className="py-2">
<AiQuery />
</Row>
<div className="flex items-center justify-center w-full text-disabled-text">
{t('or')}
</div>
</>
) : null}
<Row gutter={16} justify="center" className="py-5">
<Col span={12}>
<div

View file

@ -2,7 +2,7 @@
height: 50px;
border-bottom: solid thin $gray-lighter;
padding-right: 0;
background-color: white;
background-color: $white;
}
.divider {

View file

@ -227,7 +227,7 @@ function EventsBlock(props: IProps) {
<div
className={cn(
styles.header,
'py-4 px-2 bg-gradient-to-t from-transparent to-neutral-50 h-[57px]',
'py-4 px-2 bg-gradient-to-t from-transparent to-neutral-gray-lightest h-[57px]',
)}
>
{uxtestingStore.isUxt() ? (

View file

@ -13,7 +13,7 @@
.event {
position: relative;
background: #f6f6f6;
background: $gray-lightest;
/* border-radius: 3px; */
user-select: none;
transition: all 0.2s;
@ -147,5 +147,5 @@
}
.lastInGroup {
background: white;
background: $white;
}

View file

@ -3,7 +3,7 @@
border-bottom: solid thin $gray-light;
padding-left: 15px;
padding-right: 0;
background-color: white;
background-color: $white;
}
.divider {

View file

@ -0,0 +1,31 @@
import React from 'react';
import { Button } from 'antd';
import { BulbOutlined, BulbFilled } from '@ant-design/icons';
import { useTheme } from 'App/ThemeContext';
interface ThemeToggleProps {
className?: string;
style?: React.CSSProperties;
size?: 'large' | 'middle' | 'small';
}
const ThemeToggle: React.FC<ThemeToggleProps> = ({
className = '',
style = {},
size = 'middle'
}) => {
const { theme, toggleTheme } = useTheme();
return (
<Button
type="text"
icon={theme === 'dark' ? <BulbFilled /> : <BulbOutlined />}
onClick={toggleTheme}
className={className}
style={style}
size={size}
/>
);
};
export default ThemeToggle;

View file

@ -33,7 +33,7 @@ function SearchActions() {
// @ts-ignore
const originStr = window.env.ORIGIN || window.location.origin;
const isSaas = /app\.openreplay\.com/.test(originStr);
const showAiField = isSaas && activeTab.type === 'sessions';
const showAiField = isSaas && activeTab?.type === 'sessions';
const showPanel = hasEvents || hasFilters || aiFiltersStore.isLoading;
return !metaLoading ? (
<div className="mb-2">

View file

@ -1,9 +1,5 @@
import React from 'react';
import Select, { components, DropdownIndicatorProps } from 'react-select';
import { Icon } from 'UI';
import colors from 'App/theme/colors';
const { ValueContainer } = components;
import { Select } from 'antd';
type ValueObject = {
value: string | number;
@ -12,190 +8,42 @@ type ValueObject = {
interface Props<Value extends ValueObject> {
options: Value[];
isSearchable?: boolean;
defaultValue?: string | number;
plain?: boolean;
components?: any;
styles?: Record<string, any>;
controlStyle?: Record<string, any>;
onChange: (newValue: { name: string; value: Value }) => void;
showSearch?: boolean;
defaultValue?: string | number | (string | number)[];
onChange: (value: any, option: any) => void;
name?: string;
placeholder?: string;
className?: string;
mode?: 'multiple' | 'tags';
[x: string]: any;
}
export default function <Value extends ValueObject>({
export default function CustomSelect<Value extends ValueObject>({
placeholder = 'Select',
name = '',
onChange,
right = false,
plain = false,
options,
isSearchable = false,
components = {},
styles = {},
showSearch = false,
defaultValue = '',
controlStyle = {},
className = '',
mode,
...rest
}: Props<Value>) {
const defaultSelected = Array.isArray(defaultValue)
? defaultValue.map((value) =>
options.find((option) => option.value === value),
)
: options.find((option) => option.value === defaultValue) || null;
const customStyles = {
option: (provided: any, state: any) => ({
...provided,
whiteSpace: 'nowrap',
transition: 'all 0.3s',
backgroundColor: state.isFocused ? colors['active-blue'] : 'transparent',
color: state.isFocused ? colors.teal : 'black',
fontSize: '14px',
'&:hover': {
transition: 'all 0.2s',
backgroundColor: colors['active-blue'],
},
'&:focus': {
transition: 'all 0.2s',
backgroundColor: colors['active-blue'],
},
}),
menu: (provided: any, state: any) => ({
...provided,
top: 31,
borderRadius: '.5rem',
right: right ? 0 : undefined,
border: `1px solid ${colors['gray-light']}`,
// borderRadius: '3px',
backgroundColor: '#fff',
boxShadow: '1px 1px 1px rgba(0, 0, 0, 0.1)',
position: 'absolute',
minWidth: 'fit-content',
// zIndex: 99,
overflow: 'hidden',
zIndex: 100,
...(right && { right: 0 }),
}),
menuList: (provided: any, state: any) => ({
...provided,
padding: 0,
}),
control: (provided: any) => {
const obj = {
...provided,
border: 'solid thin #ddd',
cursor: 'pointer',
minHeight: '36px',
transition: 'all 0.5s',
'&:hover': {
backgroundColor: colors['gray-lightest'],
transition: 'all 0.2s ease-in-out',
},
...controlStyle,
};
if (plain) {
obj.backgroundColor = 'transparent';
obj.border = '1px solid transparent';
obj.backgroundColor = 'transparent';
obj['&:hover'] = {
borderColor: 'transparent',
backgroundColor: colors['gray-light'],
transition: 'all 0.2s ease-in-out',
};
obj['&:focus'] = {
borderColor: 'transparent',
};
obj['&:active'] = {
borderColor: 'transparent',
};
}
return obj;
},
indicatorsContainer: (provided: any) => ({
...provided,
maxHeight: '34px',
padding: 0,
}),
valueContainer: (provided: any) => ({
...provided,
paddingRight: '0px',
}),
singleValue: (provided: any, state: { isDisabled: any }) => {
const opacity = state.isDisabled ? 0.5 : 1;
const transition = 'opacity 300ms';
return {
...provided,
opacity,
transition,
fontWeight: '500',
};
},
input: (provided: any) => ({
...provided,
'& input:focus': {
border: 'none !important',
},
}),
noOptionsMessage: (provided: any) => ({
...provided,
whiteSpace: 'nowrap !important',
// minWidth: 'fit-content',
}),
// Handle onChange to maintain compatibility with the original component
const handleChange = (value: any, option: any) => {
onChange({ name, value: option });
};
return (
<Select
className={`${className} btn-event-condition`}
className={className}
options={options}
isSearchable={isSearchable}
defaultValue={defaultSelected}
components={{
IndicatorSeparator: () => null,
DropdownIndicator,
ValueContainer: CustomValueContainer,
...components,
}}
onChange={(value) => onChange({ name, value })}
styles={{ ...customStyles, ...styles }}
theme={(theme) => ({
...theme,
colors: {
...theme.colors,
primary: '#394EFF',
},
})}
blurInputOnSelect
showSearch={showSearch}
defaultValue={defaultValue}
onChange={handleChange}
placeholder={placeholder}
mode={mode}
{...rest}
/>
);
}
function DropdownIndicator(props: DropdownIndicatorProps<true>) {
return (
<components.DropdownIndicator {...props}>
<Icon name="chevron-down" size="16" />
</components.DropdownIndicator>
);
}
function CustomValueContainer({ children, ...rest }: any) {
const selectedCount = rest.getValue().length;
const conditional = selectedCount < 3;
let firstChild: any = [];
if (!conditional) {
firstChild = [children[0].shift(), children[1]];
}
return (
<ValueContainer {...rest}>
{conditional ? children : firstChild}
{!conditional && ` and ${selectedCount - 1} others`}
</ValueContainer>
);
}

View file

@ -1,8 +1,6 @@
.sessionItem {
background-color: #fff;
background-color: $white;
user-select: none;
/* border-radius: 3px; */
/* border: solid thin #EEEEEE; */
transition: all 0.4s;
& .favorite {

View file

@ -47,6 +47,7 @@ function ListingVisibility() {
onChange={({ value }) => {
changeSettings({ operator: value.value });
}}
className='w-full'
/>
</div>
<div className="col-span-2">
@ -55,6 +56,7 @@ function ListingVisibility() {
type="number"
name="count"
min={0}
height={32}
placeholder="E.g 10"
onChange={({ target: { value } }: any) => {
changeSettings({ count: value > 0 ? value : '' });
@ -63,6 +65,7 @@ function ListingVisibility() {
</div>
<div className="col-span-3">
<Select
className='w-full'
defaultValue={durationSettings.countType || periodOptions[0].value}
options={periodOptions}
onChange={({ value }) => {

View file

@ -15,10 +15,8 @@ export default class SlideModal extends React.PureComponent {
if (prevProps.isDisplayed !== this.props.isDisplayed) {
if (this.props.isDisplayed) {
document.addEventListener('keydown', this.keyPressHandler);
// document.body.classList.add('no-scroll');
} else {
document.removeEventListener('keydown', this.keyPressHandler);
// document.body.classList.remove('no-scroll');
}
}
}

View file

@ -1,75 +0,0 @@
import './styles/index.scss';
import React from 'react';
import { createRoot } from 'react-dom/client';
import './init';
import { Provider } from 'react-redux';
import { HTML5Backend } from 'react-dnd-html5-backend';
import { DndProvider } from 'react-dnd';
import { ConfigProvider, theme } from 'antd';
import colors from 'App/theme/colors';
import { StoreProvider, RootStore } from './mstore';
import Router from './Router';
import store from './store';
// @ts-ignore
window.getCommitHash = () => console.log(window.env.COMMIT_HASH);
const customTheme = {
// algorithm: theme.compactAlgorithm,
components: {
Layout: {
colorBgBody: colors['gray-lightest'],
colorBgHeader: colors['gray-lightest'],
},
Menu: {
// algorithm: true,
// itemColor: colors['red'],
// "itemActiveBg": "rgb(242, 21, 158)",
// itemBgHover: colors['red'],
// colorText: colors['red'],
// colorIcon: colors['red'],
// colorBg: colors['gray-lightest'],
// colorItemText: '#394EFF',
// colorItemTextSelected: colors['teal'],
// colorItemBg: colors['gray-lightest']
},
Button: {
colorPrimary: colors.teal,
algorithm: true, // Enable algorithm
},
},
token: {
colorPrimary: colors.teal,
colorPrimaryActive: '#394EFF',
colorSecondary: '#3EAAAF',
colorBgLayout: colors['gray-lightest'],
colorBgContainer: colors.white,
colorLink: colors.teal,
colorLinkHover: colors['teal-dark'],
borderRadius: 4,
fontSize: 14,
fontFamily: '\'Roboto\', \'ArialMT\', \'Arial\'',
siderBackgroundColor: colors['gray-lightest'],
siderCollapsedWidth: 800,
},
};
document.addEventListener('DOMContentLoaded', () => {
const container = document.getElementById('app');
const root = createRoot(container);
// const theme = window.localStorage.getItem('theme');
root.render(
<ConfigProvider theme={customTheme}>
<Provider store={store}>
<StoreProvider store={new RootStore()}>
<DndProvider backend={HTML5Backend}>
<Router />
</DndProvider>
</StoreProvider>
</Provider>
</ConfigProvider>,
);
});

View file

@ -5,66 +5,147 @@ import { createRoot } from 'react-dom/client';
import './init';
import { HTML5Backend } from 'react-dnd-html5-backend';
import { DndProvider } from 'react-dnd';
import { ConfigProvider, App, theme, ThemeConfig } from 'antd';
import colors from 'App/theme/colors';
import { ConfigProvider, App, theme as antdTheme, ThemeConfig } from 'antd';
import { BrowserRouter } from 'react-router-dom';
import { Notification, MountPoint } from 'UI';
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
import { StoreProvider, RootStore } from './mstore';
import Router from './Router';
import './i18n';
import { ThemeProvider, useTheme } from './ThemeContext';
// @ts-ignore
window.getCommitHash = () => console.log(window.env.COMMIT_HASH);
const queryClient = new QueryClient();
const customTheme: ThemeConfig = {
// algorithm: theme.compactAlgorithm,
components: {
Layout: {
headerBg: colors['gray-lightest'],
siderBg: colors['gray-lightest'],
},
Segmented: {
itemSelectedBg: '#FFFFFF',
itemSelectedColor: colors.main,
},
Menu: {
colorPrimary: colors.teal,
colorBgContainer: colors['gray-lightest'],
colorFillTertiary: colors['gray-lightest'],
colorBgLayout: colors['gray-lightest'],
subMenuItemBg: colors['gray-lightest'],
itemHoverBg: colors['active-blue'],
itemHoverColor: colors.teal,
const cssVar = (name: string) => `var(--color-${name})`;
itemActiveBg: colors['active-blue'],
itemSelectedBg: colors['active-blue'],
itemSelectedColor: colors.teal,
const ThemedApp: React.FC = () => {
const { theme } = useTheme();
itemMarginBlock: 0,
// itemPaddingInline: 50,
// iconMarginInlineEnd: 14,
collapsedWidth: 180,
// Create theme based on current theme setting
const customTheme: ThemeConfig = {
algorithm: theme === 'dark' ? antdTheme.darkAlgorithm : antdTheme.defaultAlgorithm,
components: {
Layout: {
headerBg: cssVar('gray-lightest'),
siderBg: cssVar('gray-lightest'),
},
Segmented: {
itemSelectedBg: theme === 'dark' ? cssVar('gray-darkest') : '#FFFFFF',
itemSelectedColor: cssVar('main'),
},
Menu: {
colorPrimary: cssVar('teal'),
colorBgContainer: cssVar('gray-lightest'),
colorFillTertiary: cssVar('gray-lightest'),
colorBgLayout: cssVar('gray-lightest'),
subMenuItemBg: cssVar('gray-lightest'),
itemHoverBg: cssVar('active-blue'),
itemHoverColor: cssVar('teal'),
itemActiveBg: cssVar('tealx-light'),
itemSelectedBg: cssVar('tealx-light'),
itemSelectedColor: cssVar('teal'),
itemColor: cssVar('gray-darkest'),
itemMarginBlock: 0,
collapsedWidth: 180,
},
Button: {
colorPrimary: cssVar('main'),
},
Select: {
colorBgContainer: cssVar('white'),
colorBgElevated: cssVar('white'),
colorBorder: cssVar('gray-light'),
colorPrimaryHover: cssVar('main'),
colorPrimary: cssVar('main'),
colorText: cssVar('gray-darkest'),
colorTextPlaceholder: cssVar('gray-medium'),
colorTextQuaternary: cssVar('gray-medium'),
controlItemBgActive: cssVar('active-blue'),
controlItemBgHover: cssVar('active-blue'),
},
Radio: {
colorPrimary: cssVar('main'),
colorBorder: cssVar('gray-medium'),
colorBgContainer: cssVar('white'),
},
Switch: {
colorPrimary: cssVar('main'),
colorPrimaryHover: cssVar('teal-dark'),
colorTextQuaternary: cssVar('gray-light'),
colorTextTertiary: cssVar('gray-medium'),
colorBgContainer: cssVar('white'),
},
Input: {
colorBgContainer: cssVar('white'),
colorBorder: cssVar('gray-light'),
colorText: cssVar('gray-darkest'),
colorTextPlaceholder: cssVar('gray-medium'),
activeBorderColor: cssVar('main'),
hoverBorderColor: cssVar('main'),
},
Checkbox: {
colorPrimary: cssVar('main'),
colorBgContainer: cssVar('white'),
colorBorder: cssVar('gray-medium'),
},
Table: {
colorBgContainer: cssVar('white'),
colorText: cssVar('gray-darkest'),
colorTextHeading: cssVar('gray-darkest'),
colorBorderSecondary: cssVar('gray-light'),
headerBg: cssVar('gray-lighter'),
},
Modal: {
colorBgElevated: cssVar('white'),
colorText: cssVar('gray-darkest'),
},
Card: {
colorBgContainer: cssVar('white'),
colorBorderSecondary: cssVar('gray-light'),
},
Tooltip: {
colorBgSpotlight: cssVar('white'),
colorTextLightSolid: cssVar('gray-darkest'),
},
},
Button: {
colorPrimary: colors.teal,
token: {
colorPrimary: cssVar('main'),
colorPrimaryActive: cssVar('teal-dark'),
colorPrimaryHover: cssVar('main'),
colorPrimaryBorder: cssVar('main'),
colorBorder: cssVar('gray-lightest'),
colorBgLayout: cssVar('gray-lightest'),
colorBgContainer: cssVar('white'),
colorLink: cssVar('teal'),
colorLinkHover: cssVar('teal-dark'),
colorText: cssVar('gray-darkest'),
colorTextSecondary: cssVar('gray-dark'),
colorTextDisabled: cssVar('disabled-text'),
borderRadius: 4,
fontSize: 14,
fontFamily: "'Roboto', 'ArialMT', 'Arial'",
fontWeightStrong: 400,
},
},
token: {
colorPrimary: colors.teal,
colorPrimaryActive: '#394EFF',
colorBgLayout: colors['gray-lightest'],
colorBgContainer: colors.white,
colorLink: colors.teal,
colorLinkHover: colors['teal-dark'],
};
borderRadius: 4,
fontSize: 14,
fontFamily: "'Roboto', 'ArialMT', 'Arial'",
fontWeightStrong: 400,
},
return (
<ConfigProvider theme={customTheme}>
<App>
<StoreProvider store={new RootStore()}>
<DndProvider backend={HTML5Backend}>
<BrowserRouter>
<Notification />
<Router />
</BrowserRouter>
</DndProvider>
<MountPoint />
</StoreProvider>
</App>
</ConfigProvider>
);
};
document.addEventListener('DOMContentLoaded', () => {
@ -72,22 +153,11 @@ document.addEventListener('DOMContentLoaded', () => {
// @ts-ignore
const root = createRoot(container);
// const theme = window.localStorage.getItem('theme');
root.render(
<QueryClientProvider client={queryClient}>
<ConfigProvider theme={customTheme}>
<App>
<StoreProvider store={new RootStore()}>
<DndProvider backend={HTML5Backend}>
<BrowserRouter>
<Notification />
<Router />
</BrowserRouter>
</DndProvider>
<MountPoint />
</StoreProvider>
</App>
</ConfigProvider>
</QueryClientProvider>,
<QueryClientProvider client={queryClient}>
<ThemeProvider>
<ThemedApp />
</ThemeProvider>
</QueryClientProvider>
);
});

View file

@ -10,6 +10,7 @@ import GettingStartedProgress from 'Shared/GettingStarted/GettingStartedProgress
import ProjectDropdown from 'Shared/ProjectDropdown';
import { useStore } from 'App/mstore';
import { observer } from 'mobx-react-lite';
import ThemeToggle from 'Components/ThemeToggle';
function TopRight() {
const { userStore } = useStore();
@ -27,6 +28,7 @@ function TopRight() {
{account.name ? <HealthStatus /> : null}
</>
)}
<ThemeToggle />
<Popover content={<UserMenu />} placement="topRight">
<div className="flex items-center cursor-pointer">

View file

@ -1,268 +1,330 @@
/* Auto-generated, DO NOT EDIT */
/* Uses CSS variables (--color-*) generated by Tailwind config */
/* fill */
.fill-main { fill: #394EFF }
.fill-gray-light-shade { fill: #EEEEEE }
.fill-gray-lightest { fill: #f6f6f6 }
.fill-gray-lighter { fill: #f1f1f1 }
.fill-gray-light { fill: #ddd }
.fill-gray-bg { fill: #CCC }
.fill-gray-medium { fill: #888 }
.fill-gray-dark { fill: #666 }
.fill-gray-darkest { fill: #333 }
.fill-gray-light-blue { fill: #F8F8FA }
.fill-teal { fill: #394EFF }
.fill-teal-dark { fill: #2331A8 }
.fill-teal-light { fill: rgba(57, 78, 255, 0.1) }
.fill-tealx { fill: #3EAAAF }
.fill-tealx-light { fill: #E2F0EE }
.fill-tealx-light-border { fill: #C6DCDA }
.fill-tealx-lightest { fill: rgba(62, 170, 175, 0.1) }
.fill-orange { fill: #E28940 }
.fill-yellow { fill: #FFFBE5 }
.fill-yellow2 { fill: #F5A623 }
.fill-orange-dark { fill: #C26822 }
.fill-green { fill: #42AE5E }
.fill-green2 { fill: #00dc69 }
.fill-green-dark { fill: #2C9848 }
.fill-red { fill: #cc0000 }
.fill-red2 { fill: #F5A623 }
.fill-red-lightest { fill: rgba(204, 0, 0, 0.1) }
.fill-blue { fill: #366CD9 }
.fill-blue2 { fill: #0076FF }
.fill-active-blue { fill: #F6F7FF }
.fill-active-dark-blue { fill: #E2E4F6 }
.fill-bg-blue { fill: #e3e6ff }
.fill-active-blue-border { fill: #D0D4F2 }
.fill-pink { fill: #ffb9b9 }
.fill-light-blue-bg { fill: #E5F7F7 }
.fill-white { fill: #fff }
.fill-borderColor-default { fill: #DDDDDD }
.fill-borderColor-gray-light-shade { fill: #EEEEEE }
.fill-borderColor-primary { fill: #3490dc }
.fill-borderColor-transparent { fill: transparent }
.fill-transparent { fill: transparent }
.fill-cyan { fill: #EBF4F5 }
.fill-figmaColors-accent-secondary { fill: rgba(62, 170, 175, 1) }
.fill-figmaColors-main { fill: rgba(57, 78, 255, 1) }
.fill-figmaColors-primary-outlined-hover-background { fill: rgba(62, 170, 175, 0.08) }
.fill-figmaColors-primary-outlined-resting-border { fill: rgba(62, 170, 175, 0.5) }
.fill-figmaColors-secondary-outlined-hover-background { fill: rgba(63, 81, 181, 0.08) }
.fill-figmaColors-secondary-outlined-resting-border { fill: rgba(63, 81, 181, 0.5) }
.fill-figmaColors-text-disabled { fill: rgba(0,0,0, 0.38) }
.fill-figmaColors-text-primary { fill: rgba(0,0,0, 0.87) }
.fill-figmaColors-outlined-border { fill: rgba(0,0,0, 0.23) }
.fill-figmaColors-divider { fill: rgba(0, 0, 0, 0.12) }
.hover-fill-main:hover svg { fill: #394EFF }
.hover-fill-gray-light-shade:hover svg { fill: #EEEEEE }
.hover-fill-gray-lightest:hover svg { fill: #f6f6f6 }
.hover-fill-gray-lighter:hover svg { fill: #f1f1f1 }
.hover-fill-gray-light:hover svg { fill: #ddd }
.hover-fill-gray-bg:hover svg { fill: #CCC }
.hover-fill-gray-medium:hover svg { fill: #888 }
.hover-fill-gray-dark:hover svg { fill: #666 }
.hover-fill-gray-darkest:hover svg { fill: #333 }
.hover-fill-gray-light-blue:hover svg { fill: #F8F8FA }
.hover-fill-teal:hover svg { fill: #394EFF }
.hover-fill-teal-dark:hover svg { fill: #2331A8 }
.hover-fill-teal-light:hover svg { fill: rgba(57, 78, 255, 0.1) }
.hover-fill-tealx:hover svg { fill: #3EAAAF }
.hover-fill-tealx-light:hover svg { fill: #E2F0EE }
.hover-fill-tealx-light-border:hover svg { fill: #C6DCDA }
.hover-fill-tealx-lightest:hover svg { fill: rgba(62, 170, 175, 0.1) }
.hover-fill-orange:hover svg { fill: #E28940 }
.hover-fill-yellow:hover svg { fill: #FFFBE5 }
.hover-fill-yellow2:hover svg { fill: #F5A623 }
.hover-fill-orange-dark:hover svg { fill: #C26822 }
.hover-fill-green:hover svg { fill: #42AE5E }
.hover-fill-green2:hover svg { fill: #00dc69 }
.hover-fill-green-dark:hover svg { fill: #2C9848 }
.hover-fill-red:hover svg { fill: #cc0000 }
.hover-fill-red2:hover svg { fill: #F5A623 }
.hover-fill-red-lightest:hover svg { fill: rgba(204, 0, 0, 0.1) }
.hover-fill-blue:hover svg { fill: #366CD9 }
.hover-fill-blue2:hover svg { fill: #0076FF }
.hover-fill-active-blue:hover svg { fill: #F6F7FF }
.hover-fill-active-dark-blue:hover svg { fill: #E2E4F6 }
.hover-fill-bg-blue:hover svg { fill: #e3e6ff }
.hover-fill-active-blue-border:hover svg { fill: #D0D4F2 }
.hover-fill-pink:hover svg { fill: #ffb9b9 }
.hover-fill-light-blue-bg:hover svg { fill: #E5F7F7 }
.hover-fill-white:hover svg { fill: #fff }
.hover-fill-borderColor-default:hover svg { fill: #DDDDDD }
.hover-fill-borderColor-gray-light-shade:hover svg { fill: #EEEEEE }
.hover-fill-borderColor-primary:hover svg { fill: #3490dc }
.hover-fill-borderColor-transparent:hover svg { fill: transparent }
.hover-fill-transparent:hover svg { fill: transparent }
.hover-fill-cyan:hover svg { fill: #EBF4F5 }
.hover-fill-figmaColors-accent-secondary:hover svg { fill: rgba(62, 170, 175, 1) }
.hover-fill-figmaColors-main:hover svg { fill: rgba(57, 78, 255, 1) }
.hover-fill-figmaColors-primary-outlined-hover-background:hover svg { fill: rgba(62, 170, 175, 0.08) }
.hover-fill-figmaColors-primary-outlined-resting-border:hover svg { fill: rgba(62, 170, 175, 0.5) }
.hover-fill-figmaColors-secondary-outlined-hover-background:hover svg { fill: rgba(63, 81, 181, 0.08) }
.hover-fill-figmaColors-secondary-outlined-resting-border:hover svg { fill: rgba(63, 81, 181, 0.5) }
.hover-fill-figmaColors-text-disabled:hover svg { fill: rgba(0,0,0, 0.38) }
.hover-fill-figmaColors-text-primary:hover svg { fill: rgba(0,0,0, 0.87) }
.hover-fill-figmaColors-outlined-border:hover svg { fill: rgba(0,0,0, 0.23) }
.hover-fill-figmaColors-divider:hover svg { fill: rgba(0, 0, 0, 0.12) }
.fill-main { fill: var(--color-main) }
.fill-gray-light-shade { fill: var(--color-gray-light-shade) }
.fill-gray-lightest { fill: var(--color-gray-lightest) }
.fill-gray-lighter { fill: var(--color-gray-lighter) }
.fill-gray-light { fill: var(--color-gray-light) }
.fill-gray-bg { fill: var(--color-gray-bg) }
.fill-gray-medium { fill: var(--color-gray-medium) }
.fill-gray-dark { fill: var(--color-gray-dark) }
.fill-gray-darkest { fill: var(--color-gray-darkest) }
.fill-gray-light-blue { fill: var(--color-gray-light-blue) }
.fill-teal { fill: var(--color-teal) }
.fill-teal-dark { fill: var(--color-teal-dark) }
.fill-teal-light { fill: var(--color-teal-light) }
.fill-tealx { fill: var(--color-tealx) }
.fill-tealx-light { fill: var(--color-tealx-light) }
.fill-tealx-light-border { fill: var(--color-tealx-light-border) }
.fill-tealx-lightest { fill: var(--color-tealx-lightest) }
.fill-orange { fill: var(--color-orange) }
.fill-yellow { fill: var(--color-yellow) }
.fill-yellow2 { fill: var(--color-yellow2) }
.fill-orange-dark { fill: var(--color-orange-dark) }
.fill-green { fill: var(--color-green) }
.fill-green2 { fill: var(--color-green2) }
.fill-green-dark { fill: var(--color-green-dark) }
.fill-red { fill: var(--color-red) }
.fill-red2 { fill: var(--color-red2) }
.fill-red-lightest { fill: var(--color-red-lightest) }
.fill-blue { fill: var(--color-blue) }
.fill-blue2 { fill: var(--color-blue2) }
.fill-active-blue { fill: var(--color-active-blue) }
.fill-active-dark-blue { fill: var(--color-active-dark-blue) }
.fill-bg-blue { fill: var(--color-bg-blue) }
.fill-active-blue-border { fill: var(--color-active-blue-border) }
.fill-pink { fill: var(--color-pink) }
.fill-light-blue-bg { fill: var(--color-light-blue-bg) }
.fill-white { fill: var(--color-white) }
.fill-gray-border { fill: var(--color-gray-border) }
.fill-borderColor-default { fill: var(--color-borderColor-default) }
.fill-borderColor-gray-light-shade { fill: var(--color-borderColor-gray-light-shade) }
.fill-borderColor-primary { fill: var(--color-borderColor-primary) }
.fill-borderColor-transparent { fill: var(--color-borderColor-transparent) }
.fill-transparent { fill: var(--color-transparent) }
.fill-cyan { fill: var(--color-cyan) }
.fill-figmaColors-accent-secondary { fill: var(--color-figmaColors-accent-secondary) }
.fill-figmaColors-main { fill: var(--color-figmaColors-main) }
.fill-figmaColors-primary-outlined-hover-background { fill: var(--color-figmaColors-primary-outlined-hover-background) }
.fill-figmaColors-primary-outlined-resting-border { fill: var(--color-figmaColors-primary-outlined-resting-border) }
.fill-figmaColors-secondary-outlined-hover-background { fill: var(--color-figmaColors-secondary-outlined-hover-background) }
.fill-figmaColors-secondary-outlined-resting-border { fill: var(--color-figmaColors-secondary-outlined-resting-border) }
.fill-figmaColors-text-disabled { fill: var(--color-figmaColors-text-disabled) }
.fill-figmaColors-text-primary { fill: var(--color-figmaColors-text-primary) }
.fill-figmaColors-outlined-border { fill: var(--color-figmaColors-outlined-border) }
.fill-figmaColors-divider { fill: var(--color-figmaColors-divider) }
.hover-fill-main:hover svg { fill: var(--color-main) }
.hover-fill-gray-light-shade:hover svg { fill: var(--color-gray-light-shade) }
.hover-fill-gray-lightest:hover svg { fill: var(--color-gray-lightest) }
.hover-fill-gray-lighter:hover svg { fill: var(--color-gray-lighter) }
.hover-fill-gray-light:hover svg { fill: var(--color-gray-light) }
.hover-fill-gray-bg:hover svg { fill: var(--color-gray-bg) }
.hover-fill-gray-medium:hover svg { fill: var(--color-gray-medium) }
.hover-fill-gray-dark:hover svg { fill: var(--color-gray-dark) }
.hover-fill-gray-darkest:hover svg { fill: var(--color-gray-darkest) }
.hover-fill-gray-light-blue:hover svg { fill: var(--color-gray-light-blue) }
.hover-fill-teal:hover svg { fill: var(--color-teal) }
.hover-fill-teal-dark:hover svg { fill: var(--color-teal-dark) }
.hover-fill-teal-light:hover svg { fill: var(--color-teal-light) }
.hover-fill-tealx:hover svg { fill: var(--color-tealx) }
.hover-fill-tealx-light:hover svg { fill: var(--color-tealx-light) }
.hover-fill-tealx-light-border:hover svg { fill: var(--color-tealx-light-border) }
.hover-fill-tealx-lightest:hover svg { fill: var(--color-tealx-lightest) }
.hover-fill-orange:hover svg { fill: var(--color-orange) }
.hover-fill-yellow:hover svg { fill: var(--color-yellow) }
.hover-fill-yellow2:hover svg { fill: var(--color-yellow2) }
.hover-fill-orange-dark:hover svg { fill: var(--color-orange-dark) }
.hover-fill-green:hover svg { fill: var(--color-green) }
.hover-fill-green2:hover svg { fill: var(--color-green2) }
.hover-fill-green-dark:hover svg { fill: var(--color-green-dark) }
.hover-fill-red:hover svg { fill: var(--color-red) }
.hover-fill-red2:hover svg { fill: var(--color-red2) }
.hover-fill-red-lightest:hover svg { fill: var(--color-red-lightest) }
.hover-fill-blue:hover svg { fill: var(--color-blue) }
.hover-fill-blue2:hover svg { fill: var(--color-blue2) }
.hover-fill-active-blue:hover svg { fill: var(--color-active-blue) }
.hover-fill-active-dark-blue:hover svg { fill: var(--color-active-dark-blue) }
.hover-fill-bg-blue:hover svg { fill: var(--color-bg-blue) }
.hover-fill-active-blue-border:hover svg { fill: var(--color-active-blue-border) }
.hover-fill-pink:hover svg { fill: var(--color-pink) }
.hover-fill-light-blue-bg:hover svg { fill: var(--color-light-blue-bg) }
.hover-fill-white:hover svg { fill: var(--color-white) }
.hover-fill-gray-border:hover svg { fill: var(--color-gray-border) }
.hover-fill-borderColor-default:hover svg { fill: var(--color-borderColor-default) }
.hover-fill-borderColor-gray-light-shade:hover svg { fill: var(--color-borderColor-gray-light-shade) }
.hover-fill-borderColor-primary:hover svg { fill: var(--color-borderColor-primary) }
.hover-fill-borderColor-transparent:hover svg { fill: var(--color-borderColor-transparent) }
.hover-fill-transparent:hover svg { fill: var(--color-transparent) }
.hover-fill-cyan:hover svg { fill: var(--color-cyan) }
.hover-fill-figmaColors-accent-secondary:hover svg { fill: var(--color-figmaColors-accent-secondary) }
.hover-fill-figmaColors-main:hover svg { fill: var(--color-figmaColors-main) }
.hover-fill-figmaColors-primary-outlined-hover-background:hover svg { fill: var(--color-figmaColors-primary-outlined-hover-background) }
.hover-fill-figmaColors-primary-outlined-resting-border:hover svg { fill: var(--color-figmaColors-primary-outlined-resting-border) }
.hover-fill-figmaColors-secondary-outlined-hover-background:hover svg { fill: var(--color-figmaColors-secondary-outlined-hover-background) }
.hover-fill-figmaColors-secondary-outlined-resting-border:hover svg { fill: var(--color-figmaColors-secondary-outlined-resting-border) }
.hover-fill-figmaColors-text-disabled:hover svg { fill: var(--color-figmaColors-text-disabled) }
.hover-fill-figmaColors-text-primary:hover svg { fill: var(--color-figmaColors-text-primary) }
.hover-fill-figmaColors-outlined-border:hover svg { fill: var(--color-figmaColors-outlined-border) }
.hover-fill-figmaColors-divider:hover svg { fill: var(--color-figmaColors-divider) }
/* color */
.color-main { color: #394EFF }
.color-gray-light-shade { color: #EEEEEE }
.color-gray-lightest { color: #f6f6f6 }
.color-gray-lighter { color: #f1f1f1 }
.color-gray-light { color: #ddd }
.color-gray-bg { color: #CCC }
.color-gray-medium { color: #888 }
.color-gray-dark { color: #666 }
.color-gray-darkest { color: #333 }
.color-gray-light-blue { color: #F8F8FA }
.color-teal { color: #394EFF }
.color-teal-dark { color: #2331A8 }
.color-teal-light { color: rgba(57, 78, 255, 0.1) }
.color-tealx { color: #3EAAAF }
.color-tealx-light { color: #E2F0EE }
.color-tealx-light-border { color: #C6DCDA }
.color-tealx-lightest { color: rgba(62, 170, 175, 0.1) }
.color-orange { color: #E28940 }
.color-yellow { color: #FFFBE5 }
.color-yellow2 { color: #F5A623 }
.color-orange-dark { color: #C26822 }
.color-green { color: #42AE5E }
.color-green2 { color: #00dc69 }
.color-green-dark { color: #2C9848 }
.color-red { color: #cc0000 }
.color-red2 { color: #F5A623 }
.color-red-lightest { color: rgba(204, 0, 0, 0.1) }
.color-blue { color: #366CD9 }
.color-blue2 { color: #0076FF }
.color-active-blue { color: #F6F7FF }
.color-active-dark-blue { color: #E2E4F6 }
.color-bg-blue { color: #e3e6ff }
.color-active-blue-border { color: #D0D4F2 }
.color-pink { color: #ffb9b9 }
.color-light-blue-bg { color: #E5F7F7 }
.color-white { color: #fff }
.color-borderColor-default { color: #DDDDDD }
.color-borderColor-gray-light-shade { color: #EEEEEE }
.color-borderColor-primary { color: #3490dc }
.color-borderColor-transparent { color: transparent }
.color-transparent { color: transparent }
.color-cyan { color: #EBF4F5 }
.color-figmaColors-accent-secondary { color: rgba(62, 170, 175, 1) }
.color-figmaColors-main { color: rgba(57, 78, 255, 1) }
.color-figmaColors-primary-outlined-hover-background { color: rgba(62, 170, 175, 0.08) }
.color-figmaColors-primary-outlined-resting-border { color: rgba(62, 170, 175, 0.5) }
.color-figmaColors-secondary-outlined-hover-background { color: rgba(63, 81, 181, 0.08) }
.color-figmaColors-secondary-outlined-resting-border { color: rgba(63, 81, 181, 0.5) }
.color-figmaColors-text-disabled { color: rgba(0,0,0, 0.38) }
.color-figmaColors-text-primary { color: rgba(0,0,0, 0.87) }
.color-figmaColors-outlined-border { color: rgba(0,0,0, 0.23) }
.color-figmaColors-divider { color: rgba(0, 0, 0, 0.12) }
.color-main { color: var(--color-main) }
.color-gray-light-shade { color: var(--color-gray-light-shade) }
.color-gray-lightest { color: var(--color-gray-lightest) }
.color-gray-lighter { color: var(--color-gray-lighter) }
.color-gray-light { color: var(--color-gray-light) }
.color-gray-bg { color: var(--color-gray-bg) }
.color-gray-medium { color: var(--color-gray-medium) }
.color-gray-dark { color: var(--color-gray-dark) }
.color-gray-darkest { color: var(--color-gray-darkest) }
.color-gray-light-blue { color: var(--color-gray-light-blue) }
.color-teal { color: var(--color-teal) }
.color-teal-dark { color: var(--color-teal-dark) }
.color-teal-light { color: var(--color-teal-light) }
.color-tealx { color: var(--color-tealx) }
.color-tealx-light { color: var(--color-tealx-light) }
.color-tealx-light-border { color: var(--color-tealx-light-border) }
.color-tealx-lightest { color: var(--color-tealx-lightest) }
.color-orange { color: var(--color-orange) }
.color-yellow { color: var(--color-yellow) }
.color-yellow2 { color: var(--color-yellow2) }
.color-orange-dark { color: var(--color-orange-dark) }
.color-green { color: var(--color-green) }
.color-green2 { color: var(--color-green2) }
.color-green-dark { color: var(--color-green-dark) }
.color-red { color: var(--color-red) }
.color-red2 { color: var(--color-red2) }
.color-red-lightest { color: var(--color-red-lightest) }
.color-blue { color: var(--color-blue) }
.color-blue2 { color: var(--color-blue2) }
.color-active-blue { color: var(--color-active-blue) }
.color-active-dark-blue { color: var(--color-active-dark-blue) }
.color-bg-blue { color: var(--color-bg-blue) }
.color-active-blue-border { color: var(--color-active-blue-border) }
.color-pink { color: var(--color-pink) }
.color-light-blue-bg { color: var(--color-light-blue-bg) }
.color-white { color: var(--color-white) }
.color-gray-border { color: var(--color-gray-border) }
.color-borderColor-default { color: var(--color-borderColor-default) }
.color-borderColor-gray-light-shade { color: var(--color-borderColor-gray-light-shade) }
.color-borderColor-primary { color: var(--color-borderColor-primary) }
.color-borderColor-transparent { color: var(--color-borderColor-transparent) }
.color-transparent { color: var(--color-transparent) }
.color-cyan { color: var(--color-cyan) }
.color-figmaColors-accent-secondary { color: var(--color-figmaColors-accent-secondary) }
.color-figmaColors-main { color: var(--color-figmaColors-main) }
.color-figmaColors-primary-outlined-hover-background { color: var(--color-figmaColors-primary-outlined-hover-background) }
.color-figmaColors-primary-outlined-resting-border { color: var(--color-figmaColors-primary-outlined-resting-border) }
.color-figmaColors-secondary-outlined-hover-background { color: var(--color-figmaColors-secondary-outlined-hover-background) }
.color-figmaColors-secondary-outlined-resting-border { color: var(--color-figmaColors-secondary-outlined-resting-border) }
.color-figmaColors-text-disabled { color: var(--color-figmaColors-text-disabled) }
.color-figmaColors-text-primary { color: var(--color-figmaColors-text-primary) }
.color-figmaColors-outlined-border { color: var(--color-figmaColors-outlined-border) }
.color-figmaColors-divider { color: var(--color-figmaColors-divider) }
/* hover color */
.hover-main:hover { color: #394EFF }
.hover-gray-light-shade:hover { color: #EEEEEE }
.hover-gray-lightest:hover { color: #f6f6f6 }
.hover-gray-lighter:hover { color: #f1f1f1 }
.hover-gray-light:hover { color: #ddd }
.hover-gray-bg:hover { color: #CCC }
.hover-gray-medium:hover { color: #888 }
.hover-gray-dark:hover { color: #666 }
.hover-gray-darkest:hover { color: #333 }
.hover-gray-light-blue:hover { color: #F8F8FA }
.hover-teal:hover { color: #394EFF }
.hover-teal-dark:hover { color: #2331A8 }
.hover-teal-light:hover { color: rgba(57, 78, 255, 0.1) }
.hover-tealx:hover { color: #3EAAAF }
.hover-tealx-light:hover { color: #E2F0EE }
.hover-tealx-light-border:hover { color: #C6DCDA }
.hover-tealx-lightest:hover { color: rgba(62, 170, 175, 0.1) }
.hover-orange:hover { color: #E28940 }
.hover-yellow:hover { color: #FFFBE5 }
.hover-yellow2:hover { color: #F5A623 }
.hover-orange-dark:hover { color: #C26822 }
.hover-green:hover { color: #42AE5E }
.hover-green2:hover { color: #00dc69 }
.hover-green-dark:hover { color: #2C9848 }
.hover-red:hover { color: #cc0000 }
.hover-red2:hover { color: #F5A623 }
.hover-red-lightest:hover { color: rgba(204, 0, 0, 0.1) }
.hover-blue:hover { color: #366CD9 }
.hover-blue2:hover { color: #0076FF }
.hover-active-blue:hover { color: #F6F7FF }
.hover-active-dark-blue:hover { color: #E2E4F6 }
.hover-bg-blue:hover { color: #e3e6ff }
.hover-active-blue-border:hover { color: #D0D4F2 }
.hover-pink:hover { color: #ffb9b9 }
.hover-light-blue-bg:hover { color: #E5F7F7 }
.hover-white:hover { color: #fff }
.hover-borderColor-default:hover { color: #DDDDDD }
.hover-borderColor-gray-light-shade:hover { color: #EEEEEE }
.hover-borderColor-primary:hover { color: #3490dc }
.hover-borderColor-transparent:hover { color: transparent }
.hover-transparent:hover { color: transparent }
.hover-cyan:hover { color: #EBF4F5 }
.hover-figmaColors-accent-secondary:hover { color: rgba(62, 170, 175, 1) }
.hover-figmaColors-main:hover { color: rgba(57, 78, 255, 1) }
.hover-figmaColors-primary-outlined-hover-background:hover { color: rgba(62, 170, 175, 0.08) }
.hover-figmaColors-primary-outlined-resting-border:hover { color: rgba(62, 170, 175, 0.5) }
.hover-figmaColors-secondary-outlined-hover-background:hover { color: rgba(63, 81, 181, 0.08) }
.hover-figmaColors-secondary-outlined-resting-border:hover { color: rgba(63, 81, 181, 0.5) }
.hover-figmaColors-text-disabled:hover { color: rgba(0,0,0, 0.38) }
.hover-figmaColors-text-primary:hover { color: rgba(0,0,0, 0.87) }
.hover-figmaColors-outlined-border:hover { color: rgba(0,0,0, 0.23) }
.hover-figmaColors-divider:hover { color: rgba(0, 0, 0, 0.12) }
.hover-main:hover { color: var(--color-main) }
.hover-gray-light-shade:hover { color: var(--color-gray-light-shade) }
.hover-gray-lightest:hover { color: var(--color-gray-lightest) }
.hover-gray-lighter:hover { color: var(--color-gray-lighter) }
.hover-gray-light:hover { color: var(--color-gray-light) }
.hover-gray-bg:hover { color: var(--color-gray-bg) }
.hover-gray-medium:hover { color: var(--color-gray-medium) }
.hover-gray-dark:hover { color: var(--color-gray-dark) }
.hover-gray-darkest:hover { color: var(--color-gray-darkest) }
.hover-gray-light-blue:hover { color: var(--color-gray-light-blue) }
.hover-teal:hover { color: var(--color-teal) }
.hover-teal-dark:hover { color: var(--color-teal-dark) }
.hover-teal-light:hover { color: var(--color-teal-light) }
.hover-tealx:hover { color: var(--color-tealx) }
.hover-tealx-light:hover { color: var(--color-tealx-light) }
.hover-tealx-light-border:hover { color: var(--color-tealx-light-border) }
.hover-tealx-lightest:hover { color: var(--color-tealx-lightest) }
.hover-orange:hover { color: var(--color-orange) }
.hover-yellow:hover { color: var(--color-yellow) }
.hover-yellow2:hover { color: var(--color-yellow2) }
.hover-orange-dark:hover { color: var(--color-orange-dark) }
.hover-green:hover { color: var(--color-green) }
.hover-green2:hover { color: var(--color-green2) }
.hover-green-dark:hover { color: var(--color-green-dark) }
.hover-red:hover { color: var(--color-red) }
.hover-red2:hover { color: var(--color-red2) }
.hover-red-lightest:hover { color: var(--color-red-lightest) }
.hover-blue:hover { color: var(--color-blue) }
.hover-blue2:hover { color: var(--color-blue2) }
.hover-active-blue:hover { color: var(--color-active-blue) }
.hover-active-dark-blue:hover { color: var(--color-active-dark-blue) }
.hover-bg-blue:hover { color: var(--color-bg-blue) }
.hover-active-blue-border:hover { color: var(--color-active-blue-border) }
.hover-pink:hover { color: var(--color-pink) }
.hover-light-blue-bg:hover { color: var(--color-light-blue-bg) }
.hover-white:hover { color: var(--color-white) }
.hover-gray-border:hover { color: var(--color-gray-border) }
.hover-borderColor-default:hover { color: var(--color-borderColor-default) }
.hover-borderColor-gray-light-shade:hover { color: var(--color-borderColor-gray-light-shade) }
.hover-borderColor-primary:hover { color: var(--color-borderColor-primary) }
.hover-borderColor-transparent:hover { color: var(--color-borderColor-transparent) }
.hover-transparent:hover { color: var(--color-transparent) }
.hover-cyan:hover { color: var(--color-cyan) }
.hover-figmaColors-accent-secondary:hover { color: var(--color-figmaColors-accent-secondary) }
.hover-figmaColors-main:hover { color: var(--color-figmaColors-main) }
.hover-figmaColors-primary-outlined-hover-background:hover { color: var(--color-figmaColors-primary-outlined-hover-background) }
.hover-figmaColors-primary-outlined-resting-border:hover { color: var(--color-figmaColors-primary-outlined-resting-border) }
.hover-figmaColors-secondary-outlined-hover-background:hover { color: var(--color-figmaColors-secondary-outlined-hover-background) }
.hover-figmaColors-secondary-outlined-resting-border:hover { color: var(--color-figmaColors-secondary-outlined-resting-border) }
.hover-figmaColors-text-disabled:hover { color: var(--color-figmaColors-text-disabled) }
.hover-figmaColors-text-primary:hover { color: var(--color-figmaColors-text-primary) }
.hover-figmaColors-outlined-border:hover { color: var(--color-figmaColors-outlined-border) }
.hover-figmaColors-divider:hover { color: var(--color-figmaColors-divider) }
.border-main { border-color: #394EFF }
.border-gray-light-shade { border-color: #EEEEEE }
.border-gray-lightest { border-color: #f6f6f6 }
.border-gray-lighter { border-color: #f1f1f1 }
.border-gray-light { border-color: #ddd }
.border-gray-bg { border-color: #CCC }
.border-gray-medium { border-color: #888 }
.border-gray-dark { border-color: #666 }
.border-gray-darkest { border-color: #333 }
.border-gray-light-blue { border-color: #F8F8FA }
.border-teal { border-color: #394EFF }
.border-teal-dark { border-color: #2331A8 }
.border-teal-light { border-color: rgba(57, 78, 255, 0.1) }
.border-tealx { border-color: #3EAAAF }
.border-tealx-light { border-color: #E2F0EE }
.border-tealx-light-border { border-color: #C6DCDA }
.border-tealx-lightest { border-color: rgba(62, 170, 175, 0.1) }
.border-orange { border-color: #E28940 }
.border-yellow { border-color: #FFFBE5 }
.border-yellow2 { border-color: #F5A623 }
.border-orange-dark { border-color: #C26822 }
.border-green { border-color: #42AE5E }
.border-green2 { border-color: #00dc69 }
.border-green-dark { border-color: #2C9848 }
.border-red { border-color: #cc0000 }
.border-red2 { border-color: #F5A623 }
.border-red-lightest { border-color: rgba(204, 0, 0, 0.1) }
.border-blue { border-color: #366CD9 }
.border-blue2 { border-color: #0076FF }
.border-active-blue { border-color: #F6F7FF }
.border-active-dark-blue { border-color: #E2E4F6 }
.border-bg-blue { border-color: #e3e6ff }
.border-active-blue-border { border-color: #D0D4F2 }
.border-pink { border-color: #ffb9b9 }
.border-light-blue-bg { border-color: #E5F7F7 }
.border-white { border-color: #fff }
.border-borderColor-default { border-color: #DDDDDD }
.border-borderColor-gray-light-shade { border-color: #EEEEEE }
.border-borderColor-primary { border-color: #3490dc }
.border-borderColor-transparent { border-color: transparent }
.border-transparent { border-color: transparent }
.border-cyan { border-color: #EBF4F5 }
.border-figmaColors-accent-secondary { border-color: rgba(62, 170, 175, 1) }
.border-figmaColors-main { border-color: rgba(57, 78, 255, 1) }
.border-figmaColors-primary-outlined-hover-background { border-color: rgba(62, 170, 175, 0.08) }
.border-figmaColors-primary-outlined-resting-border { border-color: rgba(62, 170, 175, 0.5) }
.border-figmaColors-secondary-outlined-hover-background { border-color: rgba(63, 81, 181, 0.08) }
.border-figmaColors-secondary-outlined-resting-border { border-color: rgba(63, 81, 181, 0.5) }
.border-figmaColors-text-disabled { border-color: rgba(0,0,0, 0.38) }
.border-figmaColors-text-primary { border-color: rgba(0,0,0, 0.87) }
.border-figmaColors-outlined-border { border-color: rgba(0,0,0, 0.23) }
.border-figmaColors-divider { border-color: rgba(0, 0, 0, 0.12) }
/* border color */
.border-main { border-color: var(--color-main) }
.border-gray-light-shade { border-color: var(--color-gray-light-shade) }
.border-gray-lightest { border-color: var(--color-gray-lightest) }
.border-gray-lighter { border-color: var(--color-gray-lighter) }
.border-gray-light { border-color: var(--color-gray-light) }
.border-gray-bg { border-color: var(--color-gray-bg) }
.border-gray-medium { border-color: var(--color-gray-medium) }
.border-gray-dark { border-color: var(--color-gray-dark) }
.border-gray-darkest { border-color: var(--color-gray-darkest) }
.border-gray-light-blue { border-color: var(--color-gray-light-blue) }
.border-teal { border-color: var(--color-teal) }
.border-teal-dark { border-color: var(--color-teal-dark) }
.border-teal-light { border-color: var(--color-teal-light) }
.border-tealx { border-color: var(--color-tealx) }
.border-tealx-light { border-color: var(--color-tealx-light) }
.border-tealx-light-border { border-color: var(--color-tealx-light-border) }
.border-tealx-lightest { border-color: var(--color-tealx-lightest) }
.border-orange { border-color: var(--color-orange) }
.border-yellow { border-color: var(--color-yellow) }
.border-yellow2 { border-color: var(--color-yellow2) }
.border-orange-dark { border-color: var(--color-orange-dark) }
.border-green { border-color: var(--color-green) }
.border-green2 { border-color: var(--color-green2) }
.border-green-dark { border-color: var(--color-green-dark) }
.border-red { border-color: var(--color-red) }
.border-red2 { border-color: var(--color-red2) }
.border-red-lightest { border-color: var(--color-red-lightest) }
.border-blue { border-color: var(--color-blue) }
.border-blue2 { border-color: var(--color-blue2) }
.border-active-blue { border-color: var(--color-active-blue) }
.border-active-dark-blue { border-color: var(--color-active-dark-blue) }
.border-bg-blue { border-color: var(--color-bg-blue) }
.border-active-blue-border { border-color: var(--color-active-blue-border) }
.border-pink { border-color: var(--color-pink) }
.border-light-blue-bg { border-color: var(--color-light-blue-bg) }
.border-white { border-color: var(--color-white) }
.border-gray-border { border-color: var(--color-gray-border) }
.border-borderColor-default { border-color: var(--color-borderColor-default) }
.border-borderColor-gray-light-shade { border-color: var(--color-borderColor-gray-light-shade) }
.border-borderColor-primary { border-color: var(--color-borderColor-primary) }
.border-borderColor-transparent { border-color: var(--color-borderColor-transparent) }
.border-transparent { border-color: var(--color-transparent) }
.border-cyan { border-color: var(--color-cyan) }
.border-figmaColors-accent-secondary { border-color: var(--color-figmaColors-accent-secondary) }
.border-figmaColors-main { border-color: var(--color-figmaColors-main) }
.border-figmaColors-primary-outlined-hover-background { border-color: var(--color-figmaColors-primary-outlined-hover-background) }
.border-figmaColors-primary-outlined-resting-border { border-color: var(--color-figmaColors-primary-outlined-resting-border) }
.border-figmaColors-secondary-outlined-hover-background { border-color: var(--color-figmaColors-secondary-outlined-hover-background) }
.border-figmaColors-secondary-outlined-resting-border { border-color: var(--color-figmaColors-secondary-outlined-resting-border) }
.border-figmaColors-text-disabled { border-color: var(--color-figmaColors-text-disabled) }
.border-figmaColors-text-primary { border-color: var(--color-figmaColors-text-primary) }
.border-figmaColors-outlined-border { border-color: var(--color-figmaColors-outlined-border) }
.border-figmaColors-divider { border-color: var(--color-figmaColors-divider) }
/* background color */
.bg-main { background-color: var(--color-main) }
.bg-gray-light-shade { background-color: var(--color-gray-light-shade) }
.bg-gray-lightest { background-color: var(--color-gray-lightest) }
.bg-gray-lighter { background-color: var(--color-gray-lighter) }
.bg-gray-light { background-color: var(--color-gray-light) }
.bg-gray-bg { background-color: var(--color-gray-bg) }
.bg-gray-medium { background-color: var(--color-gray-medium) }
.bg-gray-dark { background-color: var(--color-gray-dark) }
.bg-gray-darkest { background-color: var(--color-gray-darkest) }
.bg-gray-light-blue { background-color: var(--color-gray-light-blue) }
.bg-teal { background-color: var(--color-teal) }
.bg-teal-dark { background-color: var(--color-teal-dark) }
.bg-teal-light { background-color: var(--color-teal-light) }
.bg-tealx { background-color: var(--color-tealx) }
.bg-tealx-light { background-color: var(--color-tealx-light) }
.bg-tealx-light-border { background-color: var(--color-tealx-light-border) }
.bg-tealx-lightest { background-color: var(--color-tealx-lightest) }
.bg-orange { background-color: var(--color-orange) }
.bg-yellow { background-color: var(--color-yellow) }
.bg-yellow2 { background-color: var(--color-yellow2) }
.bg-orange-dark { background-color: var(--color-orange-dark) }
.bg-green { background-color: var(--color-green) }
.bg-green2 { background-color: var(--color-green2) }
.bg-green-dark { background-color: var(--color-green-dark) }
.bg-red { background-color: var(--color-red) }
.bg-red2 { background-color: var(--color-red2) }
.bg-red-lightest { background-color: var(--color-red-lightest) }
.bg-blue { background-color: var(--color-blue) }
.bg-blue2 { background-color: var(--color-blue2) }
.bg-active-blue { background-color: var(--color-active-blue) }
.bg-active-dark-blue { background-color: var(--color-active-dark-blue) }
.bg-bg-blue { background-color: var(--color-bg-blue) }
.bg-active-blue-border { background-color: var(--color-active-blue-border) }
.bg-pink { background-color: var(--color-pink) }
.bg-light-blue-bg { background-color: var(--color-light-blue-bg) }
.bg-white { background-color: var(--color-white) }
.bg-gray-border { background-color: var(--color-gray-border) }
.bg-borderColor-default { background-color: var(--color-borderColor-default) }
.bg-borderColor-gray-light-shade { background-color: var(--color-borderColor-gray-light-shade) }
.bg-borderColor-primary { background-color: var(--color-borderColor-primary) }
.bg-borderColor-transparent { background-color: var(--color-borderColor-transparent) }
.bg-transparent { background-color: var(--color-transparent) }
.bg-cyan { background-color: var(--color-cyan) }
.bg-figmaColors-accent-secondary { background-color: var(--color-figmaColors-accent-secondary) }
.bg-figmaColors-main { background-color: var(--color-figmaColors-main) }
.bg-figmaColors-primary-outlined-hover-background { background-color: var(--color-figmaColors-primary-outlined-hover-background) }
.bg-figmaColors-primary-outlined-resting-border { background-color: var(--color-figmaColors-primary-outlined-resting-border) }
.bg-figmaColors-secondary-outlined-hover-background { background-color: var(--color-figmaColors-secondary-outlined-hover-background) }
.bg-figmaColors-secondary-outlined-resting-border { background-color: var(--color-figmaColors-secondary-outlined-resting-border) }
.bg-figmaColors-text-disabled { background-color: var(--color-figmaColors-text-disabled) }
.bg-figmaColors-text-primary { background-color: var(--color-figmaColors-text-primary) }
.bg-figmaColors-outlined-border { background-color: var(--color-figmaColors-outlined-border) }
.bg-figmaColors-divider { background-color: var(--color-figmaColors-divider) }

View file

@ -425,10 +425,6 @@ p {
background-color: #ffff;
}
.ant-menu-light .ant-menu-item-selected, :where(.css-dev-only-do-not-override).ant-menu-light>.ant-menu .ant-menu-item-selected{
background-color: #E6E9FA;
}
.pref-projects-menu .ant-menu-light .ant-menu-item-selected{
background-color: #F6F7FF;
color: rgba(0,0,0,.7);

View file

@ -14,7 +14,7 @@ input.no-focus:focus {
}
.widget-wrapper {
@apply rounded-lg shadow-sm border bg-white;
@apply rounded-lg shadow-sm border bg-white border-gray-light;
}
img {

View file

@ -6,110 +6,17 @@
}
* {
border-color: #eeeeee;
border-color: $gray-light;
}
.page {
padding-top: 50px;
}
.page-margin {
padding-top: 81px;
}
.container-fit {
margin: 0 30px 0px;
}
.container {
margin: 0 30px 30px;
}
@media only screen and (max-width: 1380px) {
.container-70 {
width: 90%;
}
}
@media only screen and (min-width: 1380px) {
.container-70 {
width: 1280px;
}
}
.container-70 {
position: relative;
margin: 0 auto;
}
.container-90 {
width: 98%;
margin: 0 auto;
}
.side-menu {
width: 250px;
height: calc(100vh - 80px);
overflow-y: auto;
padding-right: 20px;
position: fixed;
top: 81px;
&
::-webkit-scrollbar {
width: 0px;
}
&
:hover {
&
::-webkit-scrollbar {
width: 0px;
}
}
}
.side-menu-margined {
margin-left: 250px;
}
.top-header {
margin-bottom: 25px;
/* border: dashed thin gray; */
min-height: 40px;
display: flex;
align-items: center;
justify-content: space-between;
}
.page-title {
font-size: 22px;
margin-right: 15px;
&
> span {
font-weight: 300;
}
&
.title {
margin-right: 15px;
&
span {
color: $ gray-medium;
font-weight: 300;
}
}
}
.page-title-flex {
display: flex;
align-items: center;
}
[data-hidden='true'] {
display: none !important;
}
@ -135,15 +42,6 @@ label {
pointer-events: none;
}
.hover {
&
:hover {
background-color: $ active-blue;
}
}
.hover-teal:hover {
background-color: $ active-blue;
color: $ teal;
@ -155,36 +53,6 @@ svg {
}
.note-hover {
border: solid thin transparent;
&
:hover {
background-color: #FFFEF5;
border-color: $ gray-lightest;
}
}
.note-hover-bg {
&
:hover {
background-color: #FFFEF5;
}
}
.text-dotted-underline {
text-decoration: underline dotted !important;
}
.no-scroll {
height: 100vh;
overflow-y: hidden;
padding-right: 15px;
}
.json-view {
display: block;
color: #4d4d4d;
@ -415,4 +283,3 @@ svg {
border-radius: 4px;
cursor: grab;
}

View file

@ -1,6 +1,5 @@
module.exports = {
main: '#394EFF',
'gray-light-shade': '#EEEEEE',
'gray-lightest': '#f6f6f6',
'gray-lighter': '#f1f1f1',
@ -10,17 +9,13 @@ module.exports = {
'gray-dark': '#666',
'gray-darkest': '#333',
'gray-light-blue': '#F8F8FA',
teal: '#394EFF' /* blue */,
'teal-dark': '#2331A8' /* "blue-dark" */,
'teal-light': 'rgba(57, 78, 255, 0.1)' /* "blue-light" */,
teal: '#394EFF', /* blue */
'teal-dark': '#2331A8', /* "blue-dark" */
'teal-light': 'rgba(57, 78, 255, 0.1)', /* "blue-light" */
tealx: '#3EAAAF',
'tealx-light': '#E2F0EE',
'tealx-light-border': '#C6DCDA',
'tealx-lightest': 'rgba(62, 170, 175, 0.1)',
orange: '#E28940',
yellow: '#FFFBE5',
yellow2: '#F5A623',
@ -39,8 +34,8 @@ module.exports = {
'active-blue-border': '#D0D4F2',
pink: '#ffb9b9',
'light-blue-bg': '#E5F7F7',
white: '#fff',
'gray-border': '#999', // Added for border-gray shadow
borderColor: {
default: '#DDDDDD',
'gray-light-shade': '#EEEEEE',
@ -49,7 +44,6 @@ module.exports = {
},
transparent: 'transparent',
cyan: '#EBF4F5',
// actual theme colors - use this for new components
figmaColors: {
'accent-secondary': 'rgba(62, 170, 175, 1)',
@ -63,4 +57,47 @@ module.exports = {
'outlined-border': 'rgba(0,0,0, 0.23)',
divider: 'rgba(0, 0, 0, 0.12)',
},
dark: {
// used as background in multiple places
white: '#0d0d0d',
teal: '#394EFF',
main: '#394EFF',
'text-primary': 'rgba(255, 255, 255, 0.87)',
'text-disabled': 'rgba(255, 255, 255, 0.38)',
'outlined-border': 'rgba(255, 255, 255, 0.23)',
divider: 'rgba(255, 255, 255, 0.12)',
'background': '#f1f1f1',
'surface': '#1E1E1E',
'gray-light-shade': '#333333',
'gray-lightest': '#2A2A2A',
'gray-lighter': '#262626',
'gray-light': '#444',
'gray-bg': '#555',
'gray-medium': '#999',
'gray-dark': '#AAA',
'gray-darkest': '#EEE',
'gray-light-blue': '#1A1A2A',
'gray-border': '#888',
'active-blue': '#1A1B32',
'active-dark-blue': '#1D1F3A',
'bg-blue': '#161A4D',
'active-blue-border': '#2F337D',
'tealx-light': '#1A2A2A',
'tealx-light-border': '#2A3F3F',
'light-blue-bg': '#15292C',
'disabled-text': 'rgba(255, 255, 255, 0.38)',
figmaColors: {
'accent-secondary': 'rgba(82, 190, 195, 1)',
'text-disabled': 'rgba(255, 255, 255, 0.38)',
'text-primary': 'rgba(255, 255, 255, 0.87)',
'outlined-border': 'rgba(255, 255, 255, 0.23)',
divider: 'rgba(255, 255, 255, 0.12)',
}
}
};

View file

@ -2,14 +2,39 @@ const path = require('path');
const colors = require('./app/theme/colors');
const cssnanoOptions = { zindex: false };
const transformColorsToCssVars = (colorsObj) => {
const result = {};
for (const [key, value] of Object.entries(colorsObj)) {
if (typeof value === 'object' && value !== null && key !== 'dark') {
// Handle nested objects
const transformedNested = {};
for (const [nestedKey, nestedValue] of Object.entries(value)) {
// Create CSS variable reference for nested values
transformedNested[nestedKey] = `var(--color-${key}-${nestedKey})`;
}
result[key] = transformedNested;
} else if (key !== 'dark') {
// Create CSS variable reference for direct values
result[key] = `var(--color-${key})`;
}
}
return result;
};
const cssVarColors = transformColorsToCssVars(colors);
module.exports = ({ file, options, env }) => ({
// parser: 'sugarss', // syntax check ?
// parser: 'sugarss', // syntax check ?
plugins: {
'postcss-import': {
path: path.join(__dirname, 'app/styles/import')
},
'postcss-mixins': {},
'postcss-simple-vars': { variables: colors },
'postcss-simple-vars': {
variables: cssVarColors
},
'postcss-nesting': {},
// 'postcss-inline-svg': {
// path: path.join(__dirname, 'app/svg'),
@ -20,4 +45,4 @@ module.exports = ({ file, options, env }) => ({
//'postcss-preset-env': {}, //includes autoprefixer
cssnano: env === 'production' ? cssnanoOptions : false,
}
});
});

View file

@ -1,38 +1,40 @@
const fs = require('fs');
const colors = require('../app/theme/colors.js');
// Helper function to flatten the nested color objects
const flattenColors = (colors) => {
let flatColors = {};
for (const [key, value] of Object.entries(colors)) {
if (typeof value === 'object') {
if (typeof value === 'object' && value !== null && key !== 'dark') {
for (const [nestedKey, nestedValue] of Object.entries(value)) {
flatColors[`${key}-${nestedKey}`] = nestedValue;
flatColors[`${key}-${nestedKey}`] = `${key}-${nestedKey}`;
}
} else {
flatColors[key] = value;
} else if (key !== 'dark') {
flatColors[key] = key;
}
}
return flatColors;
};
const flatColors = flattenColors(colors);
const generatedCSS = `/* Auto-generated, DO NOT EDIT */
/* Uses CSS variables (--color-*) generated by Tailwind config */
/* fill */
${ Object.entries(flatColors).map(([name, value]) => `.fill-${ name.replace(/ /g, '-') } { fill: ${ value } }`).join('\n') }
${ Object.entries(flatColors).map(([name, value]) => `.hover-fill-${ name.replace(/ /g, '-') }:hover svg { fill: ${ value } }`).join('\n') }
${Object.entries(flatColors).map(([name, key]) => `.fill-${name.replace(/ /g, '-')} { fill: var(--color-${key.replace(/ /g, '-')}) }`).join('\n')}
${Object.entries(flatColors).map(([name, key]) => `.hover-fill-${name.replace(/ /g, '-')}:hover svg { fill: var(--color-${key.replace(/ /g, '-')}) }`).join('\n')}
/* color */
${ Object.entries(flatColors).map(([name, value]) => `.color-${ name.replace(/ /g, '-') } { color: ${ value } }`).join('\n') }
${Object.entries(flatColors).map(([name, key]) => `.color-${name.replace(/ /g, '-')} { color: var(--color-${key.replace(/ /g, '-')}) }`).join('\n')}
/* hover color */
${ Object.entries(flatColors).map(([name, value]) => `.hover-${ name.replace(/ /g, '-') }:hover { color: ${ value } }`).join('\n') }
${Object.entries(flatColors).map(([name, key]) => `.hover-${name.replace(/ /g, '-')}:hover { color: var(--color-${key.replace(/ /g, '-')}) }`).join('\n')}
${ Object.entries(flatColors).map(([name, value]) => `.border-${ name.replace(/ /g, '-') } { border-color: ${ value } }`).join('\n') }
/* border color */
${Object.entries(flatColors).map(([name, key]) => `.border-${name.replace(/ /g, '-')} { border-color: var(--color-${key.replace(/ /g, '-')}) }`).join('\n')}
/* background color */
${Object.entries(flatColors).map(([name, key]) => `.bg-${name.replace(/ /g, '-')} { background-color: var(--color-${key.replace(/ /g, '-')}) }`).join('\n')}
`;
// Write the generated CSS to a file

View file

@ -1,29 +1,64 @@
const colors = require('./app/theme/colors');
const defaultColors = require('tailwindcss/colors');
const plugin = require('tailwindcss/plugin');
const deprecatedDefaults = ['lightBlue', 'warmGray', 'trueGray', 'coolGray', 'blueGray']
deprecatedDefaults.forEach(color => {
delete defaultColors[color]
})
const deprecatedDefaults = [
'lightBlue',
'warmGray',
'trueGray',
'coolGray',
'blueGray',
];
deprecatedDefaults.forEach((color) => {
delete defaultColors[color];
});
const cssVar = (name) => `var(--${name})`;
function createColorVariables(colors, darkColors) {
const result = {};
// Process all colors
Object.entries(colors).forEach(([key, value]) => {
// Skip nested objects for now (we'll handle them separately)
if (typeof value !== 'object' || value === null) {
result[key] = cssVar(`color-${key}`);
}
});
// Handle nested color objects
Object.entries(colors).forEach(([key, value]) => {
if (typeof value === 'object' && value !== null && key !== 'dark') {
result[key] = {};
Object.entries(value).forEach(([nestedKey, nestedValue]) => {
result[key][nestedKey] = cssVar(`color-${key}-${nestedKey}`);
});
}
});
return result;
}
const variableBasedColors = createColorVariables(colors);
module.exports = {
mode: 'jit',
darkMode: 'class',
content: ['./app/**/*.tsx', './app/**/*.js'],
theme: {
// Use variable references instead of hard-coded colors
colors: {
...defaultColors,
...colors,
...variableBasedColors,
},
extend: {
keyframes: {
'fade-in': {
'0%': {
opacity: '0',
// transform: 'translateY(-10px)'
},
'100%': {
opacity: '1',
// transform: 'translateY(0)'
},
},
'bg-spin': {
@ -43,12 +78,12 @@ module.exports = {
'bg-spin': 'bg-spin 1s ease infinite',
},
colors: {
'disabled-text': 'rgba(0,0,0, 0.38)',
'disabled-text': cssVar('color-disabled-text'),
},
boxShadow: {
'border-blue': `0 0 0 1px ${colors['active-blue-border']}`,
'border-main': `0 0 0 1px ${colors['main']}`,
'border-gray': '0 0 0 1px #999',
'border-blue': `0 0 0 1px ${cssVar('color-active-blue-border')}`,
'border-main': `0 0 0 1px ${cssVar('color-main')}`,
'border-gray': `0 0 0 1px ${cssVar('color-gray-border')}`,
},
button: {
'background-color': 'red',
@ -58,7 +93,59 @@ module.exports = {
variants: {
visibility: ['responsive', 'hover', 'focus', 'group-hover'],
},
plugins: [],
plugins: [
plugin(function ({ addBase }) {
const lightModeVars = {};
Object.entries(colors).forEach(([key, value]) => {
if (typeof value !== 'object' || value === null || key === 'dark') {
lightModeVars[`--color-${key}`] = value;
}
});
Object.entries(colors).forEach(([key, value]) => {
if (typeof value === 'object' && value !== null && key !== 'dark') {
Object.entries(value).forEach(([nestedKey, nestedValue]) => {
lightModeVars[`--color-${key}-${nestedKey}`] = nestedValue;
});
}
});
const darkModeVars = {};
if (colors.dark) {
// Process flat dark colors
Object.entries(colors.dark).forEach(([key, value]) => {
if (typeof value !== 'object') {
// Find the corresponding light mode key
const lightKey = key.replace('dark-', '');
darkModeVars[`--color-${lightKey}`] = value;
}
});
Object.entries(colors.dark).forEach(([key, value]) => {
if (typeof value === 'object' && value !== null) {
Object.entries(value).forEach(([nestedKey, nestedValue]) => {
darkModeVars[`--color-${key}-${nestedKey}`] = nestedValue;
});
}
});
if (colors['gray-light'] && colors.dark['gray-light']) {
darkModeVars['--color-gray-light'] = colors.dark['gray-light'];
}
if (colors['gray-dark'] && colors.dark['gray-dark']) {
darkModeVars['--color-gray-dark'] = colors.dark['gray-dark'];
}
darkModeVars['--color-disabled-text'] =
colors.dark['text-disabled'] || 'rgba(255, 255, 255, 0.38)';
}
addBase({
':root': lightModeVars,
'.dark': darkModeVars,
});
}),
],
corePlugins: {
preflight: false,
},