统一卡片 UI 设计,优化主题切换与背景样式
This commit is contained in:
1 parent
00fd21d78e
commit
012cb77cea
9 files changed
+212
-47
No files matched your search
@@ -338,6 +338,30 @@ for (const pair of remoteMutedContrastPairs) {
|
||||
remoteMutedContrastRatios[pair.label] = assertMutedContrast(pair.tokens, pair.label, pair.bg, pair.ink);
|
||||
}
|
||||
|
||||
const olFrostBlock = extractCssBlock(globalCss, '.ol-frost');
|
||||
assert.doesNotMatch(
|
||||
olFrostBlock,
|
||||
/rgba\(\s*255\s*,\s*255\s*,\s*255/i,
|
||||
'.ol-frost in global.css must not hardcode white rgba background gradients',
|
||||
);
|
||||
assert.match(globalCss, /background:\s*var\(--ol-frost-bg\)/, '.ol-frost must use --ol-frost-bg token');
|
||||
|
||||
assert.match(
|
||||
tokens,
|
||||
/\[data-ol-theme='dark'\][\s\S]*--ol-input-ink:/,
|
||||
'tokens.css must define --ol-input-ink in dark theme',
|
||||
);
|
||||
assert.match(
|
||||
tokens,
|
||||
/\[data-ol-theme='dark'\][\s\S]*--ol-capsule-confirm-bg:/,
|
||||
'tokens.css must define --ol-capsule-confirm-bg in dark theme',
|
||||
);
|
||||
assert.match(
|
||||
tokens,
|
||||
/\[data-ol-theme='dark'\][\s\S]*--ol-capsule-confirm-ink:/,
|
||||
'tokens.css must define --ol-capsule-confirm-ink in dark theme',
|
||||
);
|
||||
|
||||
assert.match(globalCss, /\.ol-app-shell-bg\b/, 'global.css must expose .ol-app-shell-bg');
|
||||
assert.match(globalCss, /\.ol-aura-panel\b/, 'global.css must expose .ol-aura-panel');
|
||||
assert.doesNotMatch(globalCss, /@keyframes ol-aura-halo/, 'global.css must not add an animated halo');
|
||||
|
||||
@@ -22,7 +22,8 @@ const capsuleTsx = await readFile(new URL('../src/components/Capsule.tsx', impor
|
||||
const capsuleLayoutTs = await readFile(new URL('../src/lib/capsuleLayout.ts', import.meta.url), 'utf-8');
|
||||
const windowChromeTsx = await readFile(new URL('../src/components/WindowChrome.tsx', import.meta.url), 'utf-8');
|
||||
const floatingShellTsx = await readFile(new URL('../src/components/FloatingShell.tsx', import.meta.url), 'utf-8');
|
||||
const tokensCss = await readFile(new URL('../src/styles/tokens.css', import.meta.url), 'utf-8');
|
||||
const themeModeTs = await readFile(new URL('../src/lib/themeMode.ts', import.meta.url), 'utf-8');
|
||||
const platformTs = await readFile(new URL('../src/lib/platform.ts', import.meta.url), 'utf-8');
|
||||
|
||||
if (!capsuleWindow) {
|
||||
throw new Error('capsule window config missing');
|
||||
@@ -34,13 +35,31 @@ assertEqual(capsuleWindow.width, 220, 'windows capsule config keeps translation-
|
||||
assertEqual(capsuleWindow.height, 110, 'windows capsule config keeps translation-capable height baseline');
|
||||
assertEqual(capsuleWindow.transparent, true, 'capsule window should keep transparent visuals');
|
||||
assertEqual(capsuleWindow.alwaysOnTop, true, 'capsule window should stay above the focused app while recording');
|
||||
assertEqual(mainWindow.decorations, true, 'shared main window config should keep native macOS traffic lights');
|
||||
assertEqual(mainWindow.decorations, true, 'windows main window should keep native decorations');
|
||||
assertEqual(mainWindow.visible, false, 'windows main window should stay hidden until the intended first show point');
|
||||
|
||||
assertMatch(
|
||||
libRs,
|
||||
/#\[cfg\(target_os = "windows"\)\][\s\S]*?main\.set_decorations\(false\)/,
|
||||
'windows runtime should disable native chrome before the first show',
|
||||
/fn apply_windows_caption_theme[\s\S]*?DWMWA_USE_IMMERSIVE_DARK_MODE[\s\S]*?DWMWA_CAPTION_COLOR[\s\S]*?DWMWA_TEXT_COLOR[\s\S]*?DWMWA_BORDER_COLOR/,
|
||||
'windows runtime should sync immersive dark mode and caption/text/border colors',
|
||||
);
|
||||
|
||||
assertMatch(
|
||||
libRs,
|
||||
/#\[tauri::command\][\s\S]*?fn set_windows_caption_theme/,
|
||||
'windows caption theme should be exposed as a Tauri command',
|
||||
);
|
||||
|
||||
assertMatch(
|
||||
themeModeTs,
|
||||
/export function applyThemeMode[\s\S]*?syncWindowsCaptionTheme/,
|
||||
'applyThemeMode should sync Windows native caption theme',
|
||||
);
|
||||
|
||||
assertMatch(
|
||||
platformTs,
|
||||
/export async function syncWindowsCaptionTheme[\s\S]*?set_windows_caption_theme/,
|
||||
'platform IPC wrapper should invoke set_windows_caption_theme',
|
||||
);
|
||||
|
||||
assertMatch(
|
||||
@@ -49,10 +68,18 @@ assertMatch(
|
||||
'macOS capsule should show without taking the key window',
|
||||
);
|
||||
|
||||
if (!/function WindowsResizeHandles\(\)/.test(windowChromeTsx)) {
|
||||
throw new Error('windows frameless shell should expose explicit resize handles');
|
||||
const tokensCss = await readFile(new URL('../src/styles/tokens.css', import.meta.url), 'utf-8');
|
||||
|
||||
if (!/os === 'win' \|\| os === 'android' \? 0 : 14/.test(windowChromeTsx)) {
|
||||
throw new Error('windows main shell should rely on native decorations instead of a frameless chrome shell');
|
||||
}
|
||||
|
||||
assertMatch(
|
||||
windowChromeTsx,
|
||||
/\/\/ Windows: decorations:true 时外层不画圆角/,
|
||||
'windows WindowChrome should defer chrome to native decorations',
|
||||
);
|
||||
|
||||
assertMatch(
|
||||
windowChromeTsx,
|
||||
/const MAC_TITLEBAR_HEIGHT = 28;/,
|
||||
@@ -66,8 +93,8 @@ assertMatch(
|
||||
if (/standardWindowButton|setFrameOrigin: origin|tune_macos_main_window_controls/.test(libRs)) {
|
||||
throw new Error('macOS traffic lights should not be manually repositioned; keep native AppKit button frames visible');
|
||||
}
|
||||
if (!/action=\"close\"/.test(windowChromeTsx) || !/tone=\"danger\"/.test(windowChromeTsx)) {
|
||||
throw new Error('windows titlebar should keep the close button and danger hover treatment');
|
||||
if (!/className=\"ol-linux-close-btn\"/.test(windowChromeTsx)) {
|
||||
throw new Error('linux titlebar should keep the close button treatment');
|
||||
}
|
||||
assertMatch(
|
||||
tokensCss,
|
||||
@@ -75,12 +102,14 @@ assertMatch(
|
||||
'shared motion tokens should drive shell animations and transitions',
|
||||
);
|
||||
|
||||
if (!/startResizeDragging\(direction\)/.test(windowChromeTsx)) {
|
||||
throw new Error('windows resize handles should delegate edge dragging to Tauri');
|
||||
}
|
||||
assertMatch(
|
||||
windowChromeTsx,
|
||||
/function LinuxTitlebar\(\)/,
|
||||
'linux should keep the custom ol-linux-titlebar shell',
|
||||
);
|
||||
|
||||
if (!/borderRadius:\s*'var\(--ol-window-console-radius\)'/.test(floatingShellTsx)) {
|
||||
throw new Error('floating shell should consume the shared window-console radius');
|
||||
if (!/borderRadius:\s*'var\(--ol-r-lg\)'/.test(floatingShellTsx)) {
|
||||
throw new Error('floating shell should consume the shared radius token');
|
||||
}
|
||||
|
||||
assertMatch(
|
||||
|
||||
@@ -281,6 +281,7 @@ macro_rules! app_invoke_handler_desktop {
|
||||
commands::sherpa_onnx_asr_reveal_model_dir,
|
||||
commands::export_error_log,
|
||||
restart_app,
|
||||
set_windows_caption_theme,
|
||||
]
|
||||
};
|
||||
}
|
||||
@@ -507,9 +508,9 @@ fn run_desktop() {
|
||||
if let Err(e) = apply_mica(&main, None) {
|
||||
log::warn!("[main] mica failed: {e}");
|
||||
}
|
||||
// Win11 22H2+: 把原生标题栏底色调成白色,与应用 sidebar 视觉统一。
|
||||
// Win11 22H2+: 同步原生标题栏主题;前端就绪后会再调 set_windows_caption_theme。
|
||||
// 老版 Windows 静默失败,不阻塞。
|
||||
apply_windows_caption_color(&main);
|
||||
apply_windows_caption_theme(&main, false);
|
||||
}
|
||||
// 静默启动开关:prefs.start_minimized = true → 不弹主窗口,
|
||||
// 用户从菜单栏 / 托盘点击访问。开机自启时尤其有用,避免每次
|
||||
@@ -957,41 +958,84 @@ pub(crate) fn refresh_tray_microphone_menu(_app: &AppHandle) -> tauri::Result<()
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// 把 Win11 原生标题栏底色刷成白色,与应用 sidebar 视觉统一。需要 Win11 22H2+
|
||||
/// (Build 22621+) 才支持 `DWMWA_CAPTION_COLOR`(35);老 Windows 上 DwmSetWindowAttribute
|
||||
/// 返回错误,仅打 warn 不阻塞启动。
|
||||
/// Win11 22H2+ (Build 22621+) 同步原生标题栏沉浸式暗色 / caption / text / border 色。
|
||||
/// 老 Windows 上 DwmSetWindowAttribute 返回错误,仅打 warn 不阻塞启动。
|
||||
#[cfg(target_os = "windows")]
|
||||
fn apply_windows_caption_color<R: Runtime>(window: &tauri::WebviewWindow<R>) {
|
||||
fn apply_windows_caption_theme<R: Runtime>(window: &tauri::WebviewWindow<R>, dark: bool) {
|
||||
use raw_window_handle::{HasWindowHandle, RawWindowHandle};
|
||||
use windows::Win32::Foundation::HWND;
|
||||
use windows::Win32::Graphics::Dwm::{DwmSetWindowAttribute, DWMWA_CAPTION_COLOR};
|
||||
use windows::Win32::Graphics::Dwm::{
|
||||
DwmSetWindowAttribute, DWMWA_BORDER_COLOR, DWMWA_CAPTION_COLOR, DWMWA_TEXT_COLOR,
|
||||
DWMWA_USE_IMMERSIVE_DARK_MODE,
|
||||
};
|
||||
|
||||
let handle = match window.window_handle().map(|h| h.as_raw()) {
|
||||
Ok(RawWindowHandle::Win32(handle)) => handle,
|
||||
Ok(other) => {
|
||||
log::warn!("[main] unexpected raw window handle for caption color: {other:?}");
|
||||
log::warn!("[main] unexpected raw window handle for caption theme: {other:?}");
|
||||
return;
|
||||
}
|
||||
Err(e) => {
|
||||
log::warn!("[main] read raw window handle for caption color failed: {e}");
|
||||
log::warn!("[main] read raw window handle for caption theme failed: {e}");
|
||||
return;
|
||||
}
|
||||
};
|
||||
let hwnd = HWND(handle.hwnd.get() as *mut core::ffi::c_void);
|
||||
|
||||
// COLORREF 0x00BBGGRR 编码——选用 rgb(245,245,247) 跟 WindowChrome 的 glass linear-gradient
|
||||
// 起始色一致,减小原生 caption bar 跟应用磨砂玻璃的色差(用户反馈:纯白 caption + 半透灰 glass
|
||||
// 色差很丑)。R=0xF5 G=0xF5 B=0xF7 → COLORREF = 0x00F7F5F5。
|
||||
let glass_match: u32 = 0x00F7F5F5;
|
||||
// COLORREF 0x00BBGGRR — light 对齐 WindowChrome glass 起始色 rgb(245,245,247);
|
||||
// dark 对齐 tokens.css --ol-surface (#141922) / --ol-ink (#f4f7fb) / --ol-surface-2 (#1a202b)。
|
||||
let immersive_dark: i32 = i32::from(dark);
|
||||
let caption_color: u32 = if dark { 0x0022_1914 } else { 0x00F7_F5F5 };
|
||||
let text_color: u32 = if dark { 0x00FB_F7F4 } else { 0x002A_170F };
|
||||
let border_color: u32 = if dark { 0x002B_201A } else { 0x00E8_E8E8 };
|
||||
|
||||
unsafe {
|
||||
if let Err(e) = DwmSetWindowAttribute(
|
||||
set_dwm_window_attribute(
|
||||
hwnd,
|
||||
DWMWA_USE_IMMERSIVE_DARK_MODE,
|
||||
&immersive_dark,
|
||||
"immersive dark mode",
|
||||
);
|
||||
set_dwm_window_attribute(
|
||||
hwnd,
|
||||
DWMWA_CAPTION_COLOR,
|
||||
&glass_match as *const _ as *const core::ffi::c_void,
|
||||
std::mem::size_of_val(&glass_match) as u32,
|
||||
) {
|
||||
log::warn!("[main] set caption color failed (likely pre-22H2 Win): {e}");
|
||||
}
|
||||
&caption_color,
|
||||
"caption color",
|
||||
);
|
||||
set_dwm_window_attribute(hwnd, DWMWA_TEXT_COLOR, &text_color, "text color");
|
||||
set_dwm_window_attribute(hwnd, DWMWA_BORDER_COLOR, &border_color, "border color");
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(target_os = "windows")]
|
||||
unsafe fn set_dwm_window_attribute<T>(
|
||||
hwnd: windows::Win32::Foundation::HWND,
|
||||
attribute: windows::Win32::Graphics::Dwm::DWMWINDOWATTRIBUTE,
|
||||
value: &T,
|
||||
label: &str,
|
||||
) {
|
||||
use windows::Win32::Graphics::Dwm::DwmSetWindowAttribute;
|
||||
|
||||
if let Err(e) = DwmSetWindowAttribute(
|
||||
hwnd,
|
||||
attribute,
|
||||
value as *const _ as *const core::ffi::c_void,
|
||||
std::mem::size_of_val(value) as u32,
|
||||
) {
|
||||
log::warn!("[main] set {label} failed (likely pre-22H2 Win): {e}");
|
||||
}
|
||||
}
|
||||
|
||||
/// 前端主题切换时同步主窗口原生标题栏;非 Windows 为 no-op。
|
||||
#[tauri::command]
|
||||
fn set_windows_caption_theme(app: AppHandle, dark: bool) {
|
||||
#[cfg(target_os = "windows")]
|
||||
if let Some(main) = app.get_webview_window("main") {
|
||||
apply_windows_caption_theme(&main, dark);
|
||||
}
|
||||
#[cfg(not(target_os = "windows"))]
|
||||
{
|
||||
let _ = (app, dark);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -114,10 +114,10 @@ function CircleButton({ variant, enabled, onClick }: CircleButtonProps) {
|
||||
width: 28,
|
||||
height: 28,
|
||||
borderRadius: 'var(--ol-pill-radius)',
|
||||
background: isCancel ? 'var(--ol-control-muted-strong)' : 'var(--ol-control-solid)',
|
||||
background: isCancel ? 'var(--ol-capsule-cancel-bg)' : 'var(--ol-capsule-confirm-bg)',
|
||||
backdropFilter: useBackdrop ? 'blur(12px) saturate(160%)' : 'none',
|
||||
WebkitBackdropFilter: useBackdrop ? 'blur(12px) saturate(160%)' : 'none',
|
||||
color: 'var(--ol-ink)',
|
||||
color: isCancel ? 'var(--ol-capsule-cancel-ink)' : 'var(--ol-capsule-confirm-ink)',
|
||||
border: '0.8px solid var(--ol-glass-border)',
|
||||
display: 'inline-flex',
|
||||
alignItems: 'center',
|
||||
|
||||
@@ -120,3 +120,21 @@ export async function getPlatformCapabilities(): Promise<PlatformCapabilities> {
|
||||
export function getCachedPlatformCapabilities(): PlatformCapabilities | null {
|
||||
return cachedCapabilities;
|
||||
}
|
||||
|
||||
/** Win11 原生标题栏暗色同步;非 Windows / 非 Tauri 为 no-op。 */
|
||||
export async function syncWindowsCaptionTheme(dark: boolean): Promise<void> {
|
||||
if (typeof window === 'undefined') return;
|
||||
if (detectOS() !== 'win') return;
|
||||
|
||||
const isTauri =
|
||||
globalThis.window !== undefined &&
|
||||
'__TAURI_INTERNALS__' in globalThis.window;
|
||||
if (!isTauri) return;
|
||||
|
||||
try {
|
||||
const { invoke } = await import('@tauri-apps/api/core');
|
||||
await invoke('set_windows_caption_theme', { dark });
|
||||
} catch (err) {
|
||||
console.warn('[platform] set_windows_caption_theme failed', err);
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,9 @@
|
||||
// 主题模式 — localStorage 持久化,通过 html[data-ol-theme] 切换暗色 token 集。
|
||||
|
||||
import { syncWindowsCaptionTheme } from './platform';
|
||||
|
||||
export type ThemeMode = 'system' | 'light' | 'dark';
|
||||
export type ResolvedThemeMode = 'light' | 'dark';
|
||||
|
||||
const THEME_MODE_KEY = 'ol-theme-mode';
|
||||
|
||||
@@ -8,6 +11,12 @@ function systemPrefersDark(): boolean {
|
||||
return window.matchMedia('(prefers-color-scheme: dark)').matches;
|
||||
}
|
||||
|
||||
export function resolveThemeMode(mode: ThemeMode): ResolvedThemeMode {
|
||||
if (mode === 'dark') return 'dark';
|
||||
if (mode === 'light') return 'light';
|
||||
return systemPrefersDark() ? 'dark' : 'light';
|
||||
}
|
||||
|
||||
export function readThemeMode(): ThemeMode {
|
||||
try {
|
||||
const v = window.localStorage.getItem(THEME_MODE_KEY);
|
||||
@@ -17,12 +26,14 @@ export function readThemeMode(): ThemeMode {
|
||||
}
|
||||
|
||||
export function applyThemeMode(mode: ThemeMode): void {
|
||||
const resolved = resolveThemeMode(mode);
|
||||
const root = document.documentElement;
|
||||
if (mode === 'dark' || (mode === 'system' && systemPrefersDark())) {
|
||||
if (resolved === 'dark') {
|
||||
root.dataset.olTheme = 'dark';
|
||||
} else {
|
||||
delete root.dataset.olTheme;
|
||||
}
|
||||
void syncWindowsCaptionTheme(resolved === 'dark');
|
||||
}
|
||||
|
||||
export function setThemeMode(mode: ThemeMode): ThemeMode {
|
||||
|
||||
@@ -137,7 +137,9 @@ export const inputStyle: CSSProperties = {
|
||||
fontSize: 12.5,
|
||||
fontFamily: "inherit",
|
||||
outline: "none",
|
||||
background: "var(--ol-surface-2)",
|
||||
background: "var(--ol-input-bg)",
|
||||
color: "var(--ol-input-ink)",
|
||||
caretColor: "var(--ol-input-ink)",
|
||||
width: "100%",
|
||||
maxWidth: 360,
|
||||
transition:
|
||||
|
||||
@@ -66,6 +66,13 @@ input, textarea {
|
||||
font-family: inherit;
|
||||
user-select: text;
|
||||
-webkit-user-select: text;
|
||||
color: var(--ol-input-ink);
|
||||
caret-color: var(--ol-input-ink);
|
||||
}
|
||||
|
||||
input::placeholder,
|
||||
textarea::placeholder {
|
||||
color: var(--ol-input-placeholder);
|
||||
}
|
||||
|
||||
a { color: inherit; text-decoration: none; }
|
||||
@@ -145,14 +152,7 @@ a { color: inherit; text-decoration: none; }
|
||||
.ol-frost {
|
||||
position: relative;
|
||||
isolation: isolate;
|
||||
/* 体渐变 + 左上高光扫面 —— 半透明白底(~0.9),给磨砂面体积感而不是死平。 */
|
||||
background:
|
||||
radial-gradient(135% 86% at 15% -10%,
|
||||
rgba(255, 255, 255, 0.97) 0%,
|
||||
rgba(255, 255, 255, 0) 56%),
|
||||
linear-gradient(161deg,
|
||||
rgba(255, 255, 255, 0.93) 0%,
|
||||
rgba(244, 247, 252, 0.88) 100%);
|
||||
background: var(--ol-frost-bg);
|
||||
}
|
||||
|
||||
.ol-frost::before {
|
||||
@@ -161,12 +161,12 @@ a { color: inherit; text-decoration: none; }
|
||||
inset: 0;
|
||||
z-index: -1;
|
||||
border-radius: inherit;
|
||||
/* 不透明灰度噪点,normal 混合 —— 这是"磨砂颗粒"的来源。opacity 直接等于颗粒
|
||||
强度:0.1 几乎看不见,0.32 能明显看出磨砂质感又不脏。要更糙往 0.45 调。 */
|
||||
/* 不透明灰度噪点,normal 混合 —— 这是"磨砂颗粒"的来源。opacity 由
|
||||
--ol-frost-grain-opacity 控制颗粒强度。 */
|
||||
background-image: var(--ol-frost-grain);
|
||||
/* tile 与 SVG 视口同尺寸(100),stitchTiles 的无缝拼接才成立 */
|
||||
background-size: 100px 100px;
|
||||
opacity: 0.32;
|
||||
opacity: var(--ol-frost-grain-opacity);
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
|
||||
@@ -56,6 +56,25 @@
|
||||
|
||||
/* Frost grain texture used by the .ol-frost helpers in global.css. */
|
||||
--ol-frost-grain: url("data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20width='100'%20height='100'%3E%3Cfilter%20id='g'%3E%3CfeTurbulence%20type='fractalNoise'%20baseFrequency='0.95'%20numOctaves='1'%20stitchTiles='stitch'/%3E%3CfeColorMatrix%20type='matrix'%20values='0.34%200.34%200.34%200%200%200.34%200.34%200.34%200%200%200.34%200.34%200.34%200%200%200%200%200%200%201'/%3E%3C/filter%3E%3Crect%20width='100'%20height='100'%20filter='url(%23g)'/%3E%3C/svg%3E");
|
||||
--ol-frost-bg:
|
||||
radial-gradient(135% 86% at 15% -10%,
|
||||
rgba(255, 255, 255, 0.97) 0%,
|
||||
rgba(255, 255, 255, 0) 56%),
|
||||
linear-gradient(161deg,
|
||||
rgba(255, 255, 255, 0.93) 0%,
|
||||
rgba(244, 247, 252, 0.88) 100%);
|
||||
--ol-frost-grain-opacity: 0.32;
|
||||
|
||||
/* Capsule circle buttons */
|
||||
--ol-capsule-cancel-bg: var(--ol-control-muted-strong);
|
||||
--ol-capsule-cancel-ink: var(--ol-ink);
|
||||
--ol-capsule-confirm-bg: var(--ol-control-solid);
|
||||
--ol-capsule-confirm-ink: var(--ol-ink);
|
||||
|
||||
/* Settings / form inputs */
|
||||
--ol-input-bg: var(--ol-surface-2);
|
||||
--ol-input-ink: var(--ol-ink);
|
||||
--ol-input-placeholder: var(--ol-placeholder);
|
||||
|
||||
/* Motion */
|
||||
--ol-motion-spring: cubic-bezier(0.16, 1, 0.3, 1);
|
||||
@@ -240,6 +259,24 @@
|
||||
--ol-glass-border: rgba(255, 255, 255, 0.10);
|
||||
--ol-aura-glass-border: rgba(255, 255, 255, 0.10);
|
||||
|
||||
--ol-frost-bg:
|
||||
radial-gradient(135% 86% at 15% -10%,
|
||||
rgba(255, 255, 255, 0.10) 0%,
|
||||
rgba(255, 255, 255, 0) 56%),
|
||||
linear-gradient(161deg,
|
||||
rgba(22, 28, 38, 0.88) 0%,
|
||||
rgba(14, 18, 26, 0.82) 100%);
|
||||
--ol-frost-grain-opacity: 0.28;
|
||||
|
||||
--ol-capsule-cancel-bg: rgba(255, 255, 255, 0.10);
|
||||
--ol-capsule-cancel-ink: var(--ol-ink-2);
|
||||
--ol-capsule-confirm-bg: var(--ol-accent-solid-bg);
|
||||
--ol-capsule-confirm-ink: var(--ol-accent-solid-ink);
|
||||
|
||||
--ol-input-bg: rgba(255, 255, 255, 0.06);
|
||||
--ol-input-ink: var(--ol-ink);
|
||||
--ol-input-placeholder: var(--ol-ink-4);
|
||||
|
||||
--ol-shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.34), 0 0 0 0.5px rgba(255, 255, 255, 0.04);
|
||||
--ol-shadow-md: 0 10px 30px -20px rgba(0, 0, 0, 0.42), 0 0 0 0.5px rgba(255, 255, 255, 0.05);
|
||||
--ol-shadow-lg: 0 24px 72px -32px rgba(0, 0, 0, 0.58), 0 0 0 0.5px rgba(255, 255, 255, 0.05);
|
||||
|
||||
Reference in new issue
Block a user