Files
Cyrene_v2/frontend/web/src/styles/index.css
T
AskaEth 8d70f6d331
CI / Backend (build / vet / test / cross-compile) (push) Has been cancelled
CI / Frontend (tsc + vite build) (push) Has been cancelled
feat(web): 双档 UI 模式(性能档 = 现状 / Smooth Corner 华丽档)+ 开关挂载(裁决 16.4.4)
- design/uiMode.ts:档位纯逻辑(localStorage `cyrene.ui-mode` 持久化、跨标签页同步、未知值回落默认档),
  只改 <html> 类名与 data 属性 ⇒ 不碰 React 树、不重挂载、几何尺寸不变
- 性能档=**现状**:tokens.css / styles/index.css 的改动**全为新增(0 删除)**,且全部限定在
  `:root.ui-mode-fancy` 下;75 元素签名比对证明性能档渲染与改动前逐元素一致
- 华丽档对齐六大核心:连续曲率 corner-shape / 多层 Surface 环境光 / 弹簧动效 / 深色优先(浅色单列补偿)/
  毛玻璃升级 / Liquid Glass(4 折射 + RGB 色差 + 鼠标跟踪 + 双层动态边框)
- 开关挂载:main.tsx 在 createRoot 之前 initUiMode(零闪烁);TopBar/Nav/AdminTopBar 三处挂载,
  窄屏(<640px)按既有约定收起(实测否则 375px 角色块被压到 27px、面板溢出 73px),移动端由侧栏抽屉覆盖
- 复核:tsc 0 错 + vite build 成功;uiMode 38 项 node 测试 + headless Chrome 真渲染 30 项(真点击/真持久化/
  真指针事件);变异反证(去掉读回 → 持久化往返必红)
2026-10-04 13:41:09 +08:00

396 lines
14 KiB
CSS
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
@import "../design/tokens.css";
@import "tailwindcss";
/* 让 Tailwind 通过对 token 的映射生成工具类(bg-surface-1 / rounded-smooth / ease-spring 等)。
tokens.css 里的 surface 是动态值(Light 会覆盖),这里用静态 hex 生成工具类。 */
@theme {
--color-surface-1: #161616;
--color-surface-2: #0c0c0c;
--color-surface-3: #1c1c1c;
--color-surface-4: #242424;
--color-surface-5: #2c2c2c;
--color-text-hi: #f5f5f7;
--color-text-mid: #b4b4b8;
--color-text-lo: #7a7a80;
--color-accent: #3d6bff;
--color-accent-hi: #6a8dff;
--color-ok: #35c26b;
--color-warn: #ff9f43;
--color-err: #ff5c5c;
--radius-smooth: 0.625rem;
--radius-pill: 62.5rem;
--ease-spring: cubic-bezier(0.34, 1.56, 0.64, 1);
--ease-smooth: cubic-bezier(0.22, 1, 0.36, 1);
}
html,
body,
#root {
height: 100%;
}
body {
margin: 0;
background: var(--mu-surface-2);
color: var(--mu-text-hi);
font-family:
"MiSans",
system-ui,
-apple-system,
"PingFang SC",
"Microsoft YaHei",
sans-serif;
-webkit-font-smoothing: antialiased;
text-rendering: optimizeLegibility;
overscroll-behavior: none;
}
/* 毛玻璃表面 —— TopBar / Sidebar / BottomNav 用 */
.glass {
background: color-mix(in srgb, var(--mu-surface-1) calc(var(--mu-glass-alpha) * 100%), transparent);
backdrop-filter: blur(var(--mu-glass-blur)) saturate(1.4);
-webkit-backdrop-filter: blur(var(--mu-glass-blur)) saturate(1.4);
border: 1px solid var(--mu-glass-border);
}
/* Liquid Glass 寓意:内高光 + 折射描边 + 深层玻璃阴影 */
.liquid-glass {
position: relative;
background:
linear-gradient(135deg, var(--mu-liquid-highlight), transparent 42%),
color-mix(in srgb, var(--mu-surface-4) 88%, transparent);
box-shadow:
var(--mu-shadow-2),
inset 0 1px 0 var(--mu-liquid-rim),
inset 0 0 0 1px var(--mu-liquid-rim);
backdrop-filter: blur(var(--mu-glass-blur)) saturate(1.3);
-webkit-backdrop-filter: blur(var(--mu-glass-blur)) saturate(1.3);
transition: transform 0.4s var(--mu-spring), box-shadow 0.4s var(--mu-ease);
}
.liquid-glass:hover {
transform: translateY(-1px);
box-shadow: var(--mu-shadow-3), inset 0 1px 0 var(--mu-liquid-rim);
}
/* 轻量液态玻璃毛玻璃 —— 聊天气泡:半透明(透出底层背景)+ 内高光/折射描边 +
适度的 backdrop blur 把透出的背景柔化成毛玻璃。主人要求"气泡能隐约看到背景"。
不透明度 ~68%,blur 中等,既透背景又不影响文字可读。 */
.liquid-glass-soft {
position: relative;
background:
linear-gradient(135deg, rgba(255,255,255,0.07), transparent 45%),
color-mix(in srgb, var(--mu-surface-3) 68%, transparent);
box-shadow:
inset 0 1px 0 rgba(255,255,255,0.04),
inset 0 0 0 1px rgba(255,255,255,0.03);
backdrop-filter: blur(8px) saturate(1.15);
-webkit-backdrop-filter: blur(8px) saturate(1.15);
}
/* 用户气泡的半透明毛玻璃 —— accent 主色压到 ~76%(白字仍可读),
透出背景 + blur 柔化;内高光/折射描边保留、边线弱(不刺眼)。 */
.liquid-glass-accent {
position: relative;
background:
linear-gradient(135deg, rgba(255,255,255,0.07), transparent 45%),
linear-gradient(180deg, color-mix(in srgb, var(--mu-accent) 76%, transparent), color-mix(in srgb, var(--mu-accent) 72%, transparent));
box-shadow:
inset 0 1px 0 rgba(255,255,255,0.04),
inset 0 0 0 1px rgba(255,255,255,0.03);
backdrop-filter: blur(8px) saturate(1.2);
-webkit-backdrop-filter: blur(8px) saturate(1.2);
}
/* Smooth Corner 优先:全局圆角走 token(k=0.55 近似值),落地在组件里用 rounded-smooth */
* {
border-radius: var(--mu-radius);
scrollbar-width: thin;
scrollbar-color: var(--mu-surface-5) transparent;
}
*::-webkit-scrollbar {
width: 8px;
height: 8px;
}
*::-webkit-scrollbar-thumb {
background: var(--mu-surface-5);
border-radius: var(--mu-radius-pill);
}
*::-webkit-scrollbar-track {
background: transparent;
}
button {
font: inherit;
color: inherit;
background: none;
border: none;
cursor: pointer;
}
input,
textarea {
font: inherit;
color: inherit;
}
/* 欢迎出现动画(仅交互/入场) */
@keyframes mu-rise-in {
from {
opacity: 0;
transform: translateY(10px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
.mu-rise-in {
animation: mu-rise-in 0.36s var(--mu-spring) both;
}
/* 思维链呼吸点 */
@keyframes mu-blink {
0%,
100% {
opacity: 0.35;
}
50% {
opacity: 1;
}
}
.mu-blink {
animation: mu-blink 1.2s ease-in-out infinite;
}
/* 唤醒上升(静息 → 唤醒 → 全能)的短暂光芒:弹簧过冲 + 脉动光晕。
仅用于 capacity_awaken 状态徽标 / 唤醒路径当前节点,避免常态动画。 */
@keyframes mu-awaken {
0% {
box-shadow: 0 0 0 0 color-mix(in srgb, var(--mu-accent) 0%, transparent);
}
40% {
transform: scale(1.05);
box-shadow: 0 0 0 4px color-mix(in srgb, var(--mu-accent) 32%, transparent);
}
100% {
box-shadow: 0 0 0 0 color-mix(in srgb, var(--mu-accent) 0%, transparent);
}
}
.mu-awaken {
animation: mu-awaken 1.2s var(--mu-spring) ease-in-out;
}
/* 移动端抽屉(MobileNav)滑入:从左侧收起,弹簧过冲,仅一次性入场 */
@keyframes mu-drawer-in {
from {
transform: translateX(-100%);
}
to {
transform: translateX(0);
}
}
/* ═══════════════════════════════════════════════════════════════════════════
双档 UI 模式(裁决 16.4.4 / design/07 §0.1)
上面全部 =「UI 性能模式」(默认档,现状 token 近似,未改一行);
本节全部以 `:root.ui-mode-fancy` 限定 ⇒ 性能档下**零生效、零开销**。
档位由 src/design/uiMode.ts 打在 <html> 上(类名 + data-ui-mode)。
切换只改 <html>、不改几何尺寸 ⇒ 不丢会话状态、不明显闪烁。
═══════════════════════════════════════════════════════════════════════════ */
/* —— 1. Smooth Corner:连续曲率(k=0.55 的 squircle 角型,直线到圆弧丝滑过渡)——
只作用于「明确设计过圆角」的元素;`rounded-full` 的真圆(头像/指示点)不受影响。
不支持 corner-shape 的浏览器自动回落 border-radius 近似,无副作用。 */
:root.ui-mode-fancy [class*="rounded"]:not([class*="rounded-full"]),
:root.ui-mode-fancy .glass,
:root.ui-mode-fancy .liquid-glass,
:root.ui-mode-fancy .liquid-glass-soft,
:root.ui-mode-fancy .liquid-glass-accent {
corner-shape: var(--mu-corner-shape);
}
/* —— 2. 多层 Surface:整屏环境光,给所有玻璃表面一层被照亮的底 —— */
:root.ui-mode-fancy body::before {
content: "";
position: fixed;
inset: 0;
z-index: -1;
pointer-events: none;
background-image: var(--mu-ambient);
}
/* —— 5. 毛玻璃:顶栏 / 侧栏 / 输入栏加「上缘受光 + 折射内描边」 —— */
:root.ui-mode-fancy .glass {
backdrop-filter: blur(var(--mu-glass-blur)) saturate(var(--mu-glass-saturate));
-webkit-backdrop-filter: blur(var(--mu-glass-blur)) saturate(var(--mu-glass-saturate));
box-shadow:
inset 0 1px 0 var(--mu-edge-light),
inset 0 0 0 1px var(--mu-liquid-rim);
}
/* —— 6. Liquid Glass(大件:卡片 / 弹层 / 下拉)——
真折射(默认 4 模式里的预设 1)+ 鼠标跟踪镜面高光 + RGB 色差分离 + 双层动态边框。
第二条 backdrop-filter 带 SVG 位移滤镜:不支持的浏览器在解析期即丢弃该声明,
自动回落第一条的模糊链,不会把玻璃做成透明片。 */
:root.ui-mode-fancy .liquid-glass {
isolation: isolate;
background:
radial-gradient(140% 120% at var(--mu-lens-x, 30%) var(--mu-lens-y, 0%), var(--mu-liquid-specular), transparent 45%),
radial-gradient(120% 90% at 50% 130%, var(--mu-liquid-caustic), transparent 62%),
linear-gradient(135deg, var(--mu-liquid-highlight), transparent 42%),
color-mix(in srgb, var(--mu-surface-4) 78%, transparent);
box-shadow:
var(--mu-elev-3),
inset 0 0 0 1px var(--mu-liquid-rim),
-1px 0 0 var(--mu-liquid-chroma-r),
1px 0 0 var(--mu-liquid-chroma-b);
backdrop-filter: blur(var(--mu-glass-blur)) saturate(var(--mu-glass-saturate));
-webkit-backdrop-filter: blur(var(--mu-glass-blur)) saturate(var(--mu-glass-saturate));
backdrop-filter: blur(3px) saturate(var(--mu-glass-saturate)) url("#mu-refract-1");
rotate: var(--mu-lens-rotate, 0deg);
scale: var(--mu-lens-scale, 1);
transition:
rotate 0.5s var(--mu-spring-slow),
scale 0.5s var(--mu-spring-slow),
transform 0.4s var(--mu-spring),
box-shadow 0.5s var(--mu-ease),
background 0.4s var(--mu-ease);
}
:root.ui-mode-fancy .liquid-glass:hover {
transform: translateY(-2px);
box-shadow:
var(--mu-elev-3),
0 0 0 1px var(--mu-liquid-ring),
-1px 0 0 var(--mu-liquid-chroma-r),
1px 0 0 var(--mu-liquid-chroma-b);
}
/* 双层动态边框:内环(实线流光)+ 外环(色差光晕),各转各的、方向相反。
角度靠 @property 插值;不支持时自动退化为静态双层边框(仍有形、只是不转)。 */
:root.ui-mode-fancy .liquid-glass::before,
:root.ui-mode-fancy .liquid-glass::after {
content: "";
position: absolute;
inset: 0;
z-index: -1;
border-radius: inherit;
pointer-events: none;
padding: 1px;
background: conic-gradient(
from var(--mu-ring-angle, 0deg),
transparent 0deg,
var(--mu-liquid-ring) 70deg,
transparent 150deg
);
-webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
-webkit-mask-composite: xor;
mask-composite: exclude;
animation: mu-ring-spin var(--mu-liquid-ring-dur) linear infinite;
}
:root.ui-mode-fancy .liquid-glass::after {
inset: -3px;
padding: 2px;
opacity: 0.6;
filter: blur(7px);
background: conic-gradient(
from var(--mu-ring-angle, 0deg),
var(--mu-liquid-chroma-r) 0deg,
transparent 90deg,
var(--mu-liquid-chroma-b) 220deg,
transparent 310deg
);
animation-direction: reverse;
}
@keyframes mu-ring-spin {
from {
--mu-ring-angle: 0deg;
}
to {
--mu-ring-angle: 360deg;
}
}
/* —— 6b. Liquid Glass 的 4 折射模式:默认最克制(预设 1),元素可用
`data-refract="2|3|4"` 自选更夸张的折射(预设在 uiMode.ts 里注入) —— */
:root.ui-mode-fancy :is(.liquid-glass, .liquid-glass-soft, .liquid-glass-accent)[data-refract="1"] {
backdrop-filter: blur(3px) saturate(1.7) url("#mu-refract-1");
}
:root.ui-mode-fancy :is(.liquid-glass, .liquid-glass-soft, .liquid-glass-accent)[data-refract="2"] {
backdrop-filter: blur(4px) saturate(1.8) url("#mu-refract-2");
}
:root.ui-mode-fancy :is(.liquid-glass, .liquid-glass-soft, .liquid-glass-accent)[data-refract="3"] {
backdrop-filter: blur(5px) saturate(1.9) url("#mu-refract-3");
}
:root.ui-mode-fancy :is(.liquid-glass, .liquid-glass-soft, .liquid-glass-accent)[data-refract="4"] {
backdrop-filter: blur(6px) saturate(2) url("#mu-refract-4");
}
/* —— 聊天气泡(轻量液态玻璃):镜面高光 + 色差分离 + 鼠标跟踪的弹性形变 —— */
:root.ui-mode-fancy .liquid-glass-soft,
:root.ui-mode-fancy .liquid-glass-accent {
rotate: var(--mu-lens-rotate, 0deg);
scale: var(--mu-lens-scale, 1);
transition:
rotate 0.5s var(--mu-spring-slow),
scale 0.5s var(--mu-spring-slow),
box-shadow 0.5s var(--mu-ease),
background 0.4s var(--mu-ease);
}
:root.ui-mode-fancy .liquid-glass-soft {
background:
radial-gradient(130% 160% at var(--mu-lens-x, 30%) var(--mu-lens-y, 0%), color-mix(in srgb, var(--mu-liquid-specular) 62%, transparent), transparent 42%),
linear-gradient(135deg, var(--mu-liquid-highlight), transparent 45%),
color-mix(in srgb, var(--mu-surface-3) 62%, transparent);
box-shadow:
var(--mu-elev-1),
inset 0 0 0 1px var(--mu-liquid-rim),
-0.5px 0 0 var(--mu-liquid-chroma-r),
0.5px 0 0 var(--mu-liquid-chroma-b);
backdrop-filter: blur(14px) saturate(1.6);
-webkit-backdrop-filter: blur(14px) saturate(1.6);
}
:root.ui-mode-fancy .liquid-glass-accent {
background:
radial-gradient(130% 160% at var(--mu-lens-x, 30%) var(--mu-lens-y, 0%), color-mix(in srgb, var(--mu-liquid-specular) 62%, transparent), transparent 42%),
linear-gradient(135deg, var(--mu-liquid-highlight), transparent 45%),
linear-gradient(
180deg,
color-mix(in srgb, var(--mu-accent) 70%, transparent),
color-mix(in srgb, var(--mu-accent) 64%, transparent)
);
box-shadow:
0 8px 22px color-mix(in srgb, var(--mu-accent) 26%, transparent),
inset 0 0 0 1px var(--mu-liquid-rim),
-0.5px 0 0 var(--mu-liquid-chroma-r),
0.5px 0 0 var(--mu-liquid-chroma-b);
backdrop-filter: blur(14px) saturate(1.6);
-webkit-backdrop-filter: blur(14px) saturate(1.6);
}
/* —— 3. 弹簧动效:华丽档的入场也走弹簧,过冲可见(仍只用于入场/交互,不常态抖动) —— */
:root.ui-mode-fancy .mu-rise-in {
animation-duration: 0.52s;
}
/* 尊重系统「减弱动效」:华丽档保留静态的曲率/玻璃/色差,但停掉旋转与跟踪形变 */
@media (prefers-reduced-motion: reduce) {
:root.ui-mode-fancy .liquid-glass::before,
:root.ui-mode-fancy .liquid-glass::after {
animation: none;
}
:root.ui-mode-fancy .liquid-glass,
:root.ui-mode-fancy .liquid-glass-soft,
:root.ui-mode-fancy .liquid-glass-accent {
rotate: none;
scale: none;
}
:root.ui-mode-fancy .mu-rise-in {
animation-duration: 0.01ms;
}
}