1170 lines
33 KiB
CSS
1170 lines
33 KiB
CSS
@import "tailwindcss";
|
||
@import "./features/cosmos.css";
|
||
@import "./features/chat.css";
|
||
@import "./features/characters.css";
|
||
@import "./features/memory.css";
|
||
@import "./features/time.css";
|
||
@import "./features/drive.css";
|
||
@import "./features/world.css";
|
||
@import "./features/evolution.css";
|
||
@import "./features/personality.css";
|
||
|
||
/*
|
||
* ============================================================
|
||
* 琉璃镜(Glazed Mirror)设计语言 — 三层 Token 架构
|
||
* ============================================================
|
||
*
|
||
* 三层的职责分离(per design-dna §1 token-architecture):
|
||
*
|
||
* Layer 0 — 原始色值(Raw Palette)
|
||
* --raw-* 前缀,不变的十六进制 / rgba 常量。
|
||
* 不直接用于生产,仅作为 Layer 1 的原料。
|
||
*
|
||
* Layer 1 — 语义 token(Semantic Tokens)
|
||
* --*-raw / --*-dim / --*-faint 等,按功能角色命名。
|
||
* 随亮 / 暗主题切换而变化,是组件引用层。
|
||
*
|
||
* Layer 2 — 组件 token(Component Tokens)
|
||
* 如 --btn-primary-bg / --card-surface / --pill-patina。
|
||
* 由 Layer 1 的语义 token 推导,业务组件直接使用。
|
||
*
|
||
* 色值命名规约:Descriptive name (hex) — 功能角色与约束(per finesse design-dna §1)。
|
||
*
|
||
* 目标:换主题只需改 Layer 0/Layer 1,无需逐组件调色。
|
||
* ============================================================
|
||
*/
|
||
@custom-variant dark (&:where(.dark, .dark *));
|
||
|
||
@theme inline {
|
||
/* ── 字体(Layer 1: 语义 font stack)──
|
||
* 优先使用系统字体,避免 CJK 网页字体(15MB+),
|
||
* 仅当系统无对应字体时才 fallback 到自托管/ CDN 网页字体。
|
||
* JetBrains Mono 已下载到 public/fonts/,通过 @font-face 自托管。 */
|
||
--font-serif:
|
||
"Source Han Serif SC", "Noto Serif CJK SC", "Songti SC", "STSong", serif;
|
||
--font-sans:
|
||
-apple-system, BlinkMacSystemFont, "PingFang SC", "Microsoft YaHei",
|
||
"Helvetica Neue", system-ui, sans-serif;
|
||
--font-mono: "JetBrains Mono", "SF Mono", ui-monospace, monospace;
|
||
/* Instrument Serif:英文展示衬线(Google Fonts 开源),仅 15KB */
|
||
--font-display-eng: "Instrument Serif", "Georgia", "Times New Roman", serif;
|
||
/* Space Grotesk:英文技术感无衬线(Google Fonts 开源),变量字体 22KB */
|
||
--font-sans-eng:
|
||
"Space Grotesk", "Inter", -apple-system, system-ui, sans-serif;
|
||
/* 霞鹜文楷:开源楷体中文,适合正文/文学场景 */
|
||
--font-kai: "LXGW WenKai", "Kaiti SC", "STKaiti", "KaiTi", serif;
|
||
/* 得意黑:开源现代圆体中文,适合标题/短标签 */
|
||
--font-round: "Smiley Sans", "PingFang SC", system-ui, sans-serif;
|
||
|
||
/* ── Layer 1: 语义色值 —— 运行时 CSS 变量映射 ── */
|
||
--color-surface: var(--surface);
|
||
--color-glass: var(--glass);
|
||
--color-glass-strong: var(--glass-strong);
|
||
--color-border-glass: var(--glass-border);
|
||
--color-fg: var(--fg);
|
||
--color-muted: var(--muted);
|
||
--color-jade: var(--jade);
|
||
--color-gold: var(--gold);
|
||
--color-cinnabar: var(--cinnabar);
|
||
--color-success: var(--success);
|
||
--color-info: var(--info);
|
||
--color-overlay-hover: var(--overlay-hover);
|
||
--color-overlay-active: var(--overlay-active);
|
||
--color-overlay-light: var(--overlay-light);
|
||
|
||
/* ── Layer 1: 铜镜鉴心语义色 ── */
|
||
--color-ink: var(--ink);
|
||
--color-night-bronze: var(--night-bronze);
|
||
--color-gilt: var(--gilt);
|
||
--color-patina: var(--patina);
|
||
--color-patina-bright: var(--patina-bright);
|
||
--color-fg-dim: var(--fg-dim);
|
||
--color-fg-faint: var(--fg-faint);
|
||
--color-rule: var(--rule);
|
||
--color-surface-hi: var(--surface-hi);
|
||
|
||
/* ── Layer 1: 铜镜复合色 — 晕染/描边/悬停态(高频使用) ── */
|
||
--color-patina-wash: var(--patina-wash);
|
||
--color-patina-dim: var(--patina-dim);
|
||
--color-gilt-dim: var(--gilt-dim);
|
||
--color-gilt-faint: var(--gilt-faint);
|
||
--color-cinnabar-wash: var(--cinnabar-wash);
|
||
--color-cinnabar-dim: var(--cinnabar-dim);
|
||
--color-glass: var(--glass);
|
||
--color-glass-border: var(--glass-border);
|
||
--color-overlay-hover: var(--overlay-hover);
|
||
--color-overlay-active: var(--overlay-active);
|
||
--color-bg: var(--bg);
|
||
|
||
/* ── Layer 2: 组件 token(业务组件直接引用)── */
|
||
/* Button */
|
||
--color-btn-primary-bg: var(--patina);
|
||
--color-btn-primary-text: var(--ink);
|
||
--color-btn-primary-border: var(--patina);
|
||
--color-btn-secondary-bg: var(--surface);
|
||
--color-btn-secondary-text: var(--fg);
|
||
--color-btn-secondary-border: var(--rule);
|
||
--color-btn-ghost-text: var(--muted);
|
||
--color-btn-danger-bg: var(--cinnabar);
|
||
--color-btn-danger-text: var(--ink);
|
||
--color-btn-danger-border: var(--cinnabar);
|
||
|
||
/* Pill / Badge */
|
||
--color-pill-patina-bg: var(--patina-wash);
|
||
--color-pill-patina-text: var(--patina);
|
||
--color-pill-patina-border: var(--patina-dim);
|
||
--color-pill-gilt-bg: var(--gilt-faint);
|
||
--color-pill-gilt-text: var(--gilt);
|
||
--color-pill-gilt-border: var(--gilt-dim);
|
||
--color-pill-cinnabar-bg: var(--cinnabar-wash);
|
||
--color-pill-cinnabar-text: var(--cinnabar);
|
||
--color-pill-cinnabar-border: var(--cinnabar-dim);
|
||
|
||
/* Panel / Card */
|
||
--color-panel-bg: var(--surface);
|
||
--color-panel-border: var(--rule);
|
||
--color-card-glass-bg: var(--glass);
|
||
--color-card-elevated-bg: var(--glass-strong);
|
||
|
||
/* Select / input */
|
||
--color-select-bg: var(--surface);
|
||
--color-select-border: var(--rule);
|
||
--color-select-text: var(--fg);
|
||
--color-input-bg: var(--input-bg);
|
||
--color-input-border: var(--rule);
|
||
|
||
/* Modal */
|
||
--color-modal-overlay: rgba(0, 0, 0, 0.5);
|
||
--color-modal-bg: var(--glass-strong);
|
||
--color-modal-border: var(--glass-border);
|
||
|
||
/* Tab */
|
||
--color-tab-active-text: var(--patina);
|
||
--color-tab-active-border: var(--patina);
|
||
--color-tab-inactive-text: var(--fg-faint);
|
||
--color-tab-hover-text: var(--fg-dim);
|
||
|
||
/* Toast */
|
||
--color-toast-success-bg: var(--success-wash);
|
||
--color-toast-success-text: var(--success);
|
||
--color-toast-success-border: var(--success-dim);
|
||
--color-toast-error-bg: var(--cinnabar-wash);
|
||
--color-toast-error-text: var(--cinnabar);
|
||
--color-toast-error-border: var(--cinnabar-dim);
|
||
--color-toast-warning-bg: var(--gilt-faint);
|
||
--color-toast-warning-text: var(--gilt);
|
||
--color-toast-warning-border: var(--gilt-dim);
|
||
--color-toast-info-bg: var(--patina-wash);
|
||
--color-toast-info-text: var(--patina);
|
||
--color-toast-info-border: var(--patina-dim);
|
||
|
||
/* ── 圆角缩放 ── */
|
||
--radius-sm: 6px;
|
||
--radius-md: 12px;
|
||
--radius-lg: 16px;
|
||
--radius-xl: 24px;
|
||
|
||
/* ── 交互层级 ── */
|
||
--z-sticky: 20;
|
||
--z-header: 30;
|
||
--z-popover: 40;
|
||
--z-drawer: 50;
|
||
--z-modal: 60;
|
||
--z-toast: 70;
|
||
|
||
/* ── 动画曲线 ── */
|
||
--ease-out-expo: cubic-bezier(0.16, 1, 0.3, 1);
|
||
--ease-out-quart: cubic-bezier(0.25, 0.46, 0.45, 0.94);
|
||
--ease-smooth: cubic-bezier(0.4, 0, 0.2, 1);
|
||
}
|
||
|
||
@layer base {
|
||
:where(a, button, input, select, textarea, [role="button"]):focus-visible {
|
||
outline: 2px solid var(--patina);
|
||
outline-offset: 2px;
|
||
}
|
||
|
||
/* ============================================================
|
||
* Layer 0: 原始色值(Raw Palette)—— 所有色值的原料
|
||
* 不随主题切换而变,仅作为 Layer 1 的参考来源。
|
||
* 实际使用时引用 Layer 1(:root / .dark 下的语义变量)。
|
||
* ============================================================ */
|
||
:root {
|
||
--raw-patina-light: #3f7d68;
|
||
--raw-patina-bright-light: #2f6450;
|
||
--raw-patina-dark: #6fa389;
|
||
--raw-patina-bright-dark: #84bb9d;
|
||
--raw-gilt-light: #8a6d28;
|
||
--raw-gilt-dark: #c9a24a;
|
||
--raw-cinnabar-light: #a8342a;
|
||
--raw-cinnabar-dark: #b8392e;
|
||
--raw-ink-light: #e7e1d0;
|
||
--raw-ink-dark: #0c0e0d;
|
||
}
|
||
|
||
/* ── Layer 1: 亮色 · 素绢底 ── */
|
||
:root {
|
||
color-scheme: light;
|
||
|
||
/* Layer 1: 语义色值 */
|
||
--bg: #ece8dc;
|
||
--surface: #f4f1e8;
|
||
--glass: rgba(255, 255, 255, 0.55);
|
||
--glass-strong: rgba(255, 255, 255, 0.72);
|
||
--glass-border: rgba(30, 40, 33, 0.1);
|
||
--fg: #1c2420;
|
||
--muted: #6b746e;
|
||
--jade: #3f7d72;
|
||
--gold: #9a7d3e;
|
||
--cinnabar: #a8392c;
|
||
--success: #4a8c6f; /* 碧玉 — Green Jadeite */
|
||
--success-dim: rgba(74, 140, 111, 0.3);
|
||
--success-wash: rgba(74, 140, 111, 0.08);
|
||
--info: #3f7d72; /* 复用铜绿 = jade */
|
||
--overlay-hover: rgba(0, 0, 0, 0.04);
|
||
--overlay-active: rgba(0, 0, 0, 0.08);
|
||
--overlay-light: rgba(255, 255, 255, 0.08);
|
||
--input-bg: rgba(255, 248, 235, 0.5);
|
||
--aurora-1: rgba(63, 125, 114, 0.22);
|
||
--aurora-2: rgba(154, 125, 62, 0.18);
|
||
--aurora-3: rgba(168, 57, 44, 0.1);
|
||
|
||
/* Layer 1: 铜镜鉴心语义色 */
|
||
--ink: #e7e1d0; /* 素绢暖纸底 */
|
||
--night-bronze: #ddd4c0; /* 夜铜暗面带铜温 */
|
||
--surface-hi: rgba(255, 255, 255, 0.74);
|
||
--gilt: #8a6d28; /* 鎏金 — 结构 / 发丝线 / 标签 */
|
||
--gilt-dim: rgba(138, 109, 40, 0.36);
|
||
--gilt-faint: rgba(138, 109, 40, 0.16);
|
||
--patina: #3f7d68; /* 铜绿锈 — 主色:在场 / 健康 / 记忆 */
|
||
--patina-bright: #2f6450;
|
||
--patina-dim: rgba(63, 125, 104, 0.3);
|
||
--patina-wash: rgba(63, 125, 104, 0.05);
|
||
--cinnabar-dim: rgba(168, 52, 42, 0.4);
|
||
--cinnabar-wash: rgba(168, 52, 42, 0.06);
|
||
--fg-dim: #5f594d; /* 次要正文 */
|
||
--fg-faint: #948f82; /* 极淡占位 / mono 副标 */
|
||
--rule: rgba(138, 109, 40, 0.22); /* 发丝线 */
|
||
|
||
/* Layer 1: 光照效果(镜面色泽) */
|
||
--sweep-gradient: linear-gradient(
|
||
130deg,
|
||
transparent 0%,
|
||
transparent 24%,
|
||
rgba(200, 170, 130, 0.06) 30%,
|
||
rgba(255, 248, 235, 0.18) 36%,
|
||
rgba(200, 170, 130, 0.1) 44%,
|
||
transparent 52%,
|
||
transparent 100%
|
||
);
|
||
--face-sheen: linear-gradient(
|
||
165deg,
|
||
rgba(255, 255, 255, 0.7),
|
||
rgba(255, 255, 255, 0.34) 42%,
|
||
rgba(120, 105, 75, 0.08)
|
||
);
|
||
--face-in-top: rgba(255, 255, 255, 0.7);
|
||
--face-in-bot: rgba(120, 100, 60, 0.1);
|
||
--shadow: 0 1px 2px rgba(60, 50, 30, 0.08);
|
||
|
||
/* 代码铭版(恒为深底,不随 .dark 切换) */
|
||
--code-ink: #0d1117;
|
||
--code-edge: rgba(201, 162, 74, 0.22);
|
||
--code-rule: rgba(201, 162, 74, 0.18);
|
||
--code-label: rgba(201, 162, 74, 0.62);
|
||
--code-label-dim: rgba(201, 162, 74, 0.5);
|
||
--code-label-hi: #d4b25a;
|
||
}
|
||
|
||
/* ── Layer 1: 暗色 · 墨夜底 ── */
|
||
.dark {
|
||
color-scheme: dark;
|
||
|
||
--bg: #0b0f0e;
|
||
--surface: #121817;
|
||
--glass: rgba(255, 255, 255, 0.045);
|
||
--glass-strong: rgba(255, 255, 255, 0.08);
|
||
--glass-border: rgba(255, 255, 255, 0.1);
|
||
--fg: #e6e2d6;
|
||
--muted: #8a9389;
|
||
--jade: #5fa192;
|
||
--gold: #c6a664;
|
||
--cinnabar: #b5402f;
|
||
--success: #6abf8e;
|
||
--success-dim: rgba(106, 191, 142, 0.3);
|
||
--success-wash: rgba(106, 191, 142, 0.08);
|
||
--info: #5fa192;
|
||
--overlay-hover: rgba(255, 255, 255, 0.05);
|
||
--overlay-active: rgba(255, 255, 255, 0.1);
|
||
--overlay-light: rgba(255, 255, 255, 0.03);
|
||
--input-bg: rgba(0, 0, 0, 0.3);
|
||
--aurora-1: rgba(95, 161, 146, 0.2);
|
||
--aurora-2: rgba(198, 166, 100, 0.16);
|
||
--aurora-3: rgba(42, 74, 71, 0.3);
|
||
|
||
/* Layer 1: 铜镜鉴心语义色(暗色) */
|
||
--ink: #0c0e0d;
|
||
--night-bronze: #14110d;
|
||
--surface-hi: rgba(255, 255, 255, 0.08);
|
||
--gilt: #c9a24a;
|
||
--gilt-dim: rgba(201, 162, 74, 0.32);
|
||
--gilt-faint: rgba(201, 162, 74, 0.14);
|
||
--patina: #6fa389;
|
||
--patina-bright: #84bb9d;
|
||
--patina-dim: rgba(111, 163, 137, 0.34);
|
||
--patina-wash: rgba(111, 163, 137, 0.06);
|
||
--cinnabar-dim: rgba(184, 57, 46, 0.4);
|
||
--cinnabar-wash: rgba(184, 57, 46, 0.08);
|
||
--fg-dim: #9b958a;
|
||
--fg-faint: #5e5a52;
|
||
--rule: rgba(201, 162, 74, 0.16);
|
||
|
||
/* Layer 1: 光照效果(暗色) */
|
||
--sweep-gradient: linear-gradient(
|
||
130deg,
|
||
transparent 0%,
|
||
transparent 28%,
|
||
rgba(201, 162, 74, 0.025) 34%,
|
||
rgba(255, 255, 255, 0.06) 40%,
|
||
rgba(201, 162, 74, 0.025) 48%,
|
||
transparent 55%,
|
||
transparent 100%
|
||
);
|
||
--face-sheen: linear-gradient(
|
||
165deg,
|
||
rgba(255, 255, 255, 0.09),
|
||
rgba(255, 255, 255, 0.02) 42%,
|
||
rgba(0, 0, 0, 0.18)
|
||
);
|
||
--face-in-top: rgba(255, 255, 255, 0.11);
|
||
--face-in-bot: rgba(0, 0, 0, 0.3);
|
||
--shadow: 0 1px 2px rgba(0, 0, 0, 0.35);
|
||
}
|
||
|
||
/* ── iOS safe-area + 基础 HTML/BODY(Layer 2: 布局 token)── */
|
||
html,
|
||
body {
|
||
height: 100%;
|
||
}
|
||
|
||
body {
|
||
/* iOS safe-area 撑顶 */
|
||
padding-top: env(safe-area-inset-top, 0px);
|
||
padding-bottom: env(safe-area-inset-bottom, 0px);
|
||
padding-left: env(safe-area-inset-left, 0px);
|
||
padding-right: env(safe-area-inset-right, 0px);
|
||
background-color: var(--bg);
|
||
color: var(--fg);
|
||
font-family: var(--font-sans);
|
||
-webkit-font-smoothing: antialiased;
|
||
-moz-osx-font-smoothing: grayscale;
|
||
overflow-x: hidden;
|
||
}
|
||
|
||
/*
|
||
* ============================================================
|
||
* 司命台 · 冷色系(Admin Slate)—— 与主域暖铜色温分化
|
||
*
|
||
* 在 .admin-shell 容器内切换为冷色调(铁青 / 墨灰 / 银线),
|
||
* 与主域琉璃镜的暖铜(素绢 + 鎏金)形成视觉区隔。
|
||
* 所有 Layer 1 语义色变量覆盖为冷系。
|
||
* ============================================================
|
||
*/
|
||
|
||
/* 亮色 · 司命冷灰 */
|
||
.admin-shell {
|
||
--bg: #eef0ec;
|
||
--surface: #f2f4f0;
|
||
--glass: rgba(225, 230, 225, 0.55);
|
||
--glass-strong: rgba(245, 247, 243, 0.72);
|
||
--glass-border: rgba(30, 35, 38, 0.1);
|
||
--fg: #1a1e1c;
|
||
--muted: #6b7170;
|
||
--ink: #e8eae4; /* 冷绢底 */
|
||
--night-bronze: #d6d9d2; /* 冷灰面带铁温 */
|
||
--gilt: #6a7b72; /* 铁青 — 结构/发丝线/标签 */
|
||
--gilt-dim: rgba(106, 123, 114, 0.32);
|
||
--gilt-faint: rgba(106, 123, 114, 0.14);
|
||
--patina: #3f7d68; /* 复用铜绿锈(一致的健康色) */
|
||
--patina-dim: rgba(63, 125, 104, 0.28);
|
||
--patina-wash: rgba(63, 125, 104, 0.05);
|
||
--fg-dim: #5a605c;
|
||
--fg-faint: #8a9089;
|
||
--rule: rgba(106, 123, 114, 0.18);
|
||
--overlay-hover: rgba(0, 0, 0, 0.03);
|
||
--overlay-active: rgba(0, 0, 0, 0.07);
|
||
--cinnabar-dim: rgba(180, 50, 40, 0.38);
|
||
--cinnabar-wash: rgba(180, 50, 40, 0.06);
|
||
--aurora-1: rgba(110, 140, 130, 0.18);
|
||
--aurora-2: rgba(180, 140, 100, 0.1);
|
||
--aurora-3: rgba(60, 80, 75, 0.12);
|
||
--shadow: 0 1px 2px rgba(40, 50, 45, 0.08);
|
||
|
||
/* Layer 2 组件 token 覆盖 */
|
||
--color-btn-primary-bg: var(--patina);
|
||
--color-btn-primary-text: var(--ink);
|
||
--color-btn-secondary-bg: var(--surface);
|
||
--color-btn-secondary-text: var(--fg);
|
||
}
|
||
|
||
/* 暗色 · 司命墨灰 */
|
||
.dark .admin-shell,
|
||
.admin-shell.dark {
|
||
--bg: #0a0e0d;
|
||
--surface: #121615;
|
||
--glass: rgba(255, 255, 255, 0.035);
|
||
--glass-strong: rgba(255, 255, 255, 0.07);
|
||
--glass-border: rgba(160, 175, 168, 0.08);
|
||
--fg: #e0e3de;
|
||
--muted: #7a8280;
|
||
--ink: #0a0e0d;
|
||
--night-bronze: #111514;
|
||
--gilt: #889c90; /* 铁青(暗色亮一些) */
|
||
--gilt-dim: rgba(136, 156, 144, 0.28);
|
||
--gilt-faint: rgba(136, 156, 144, 0.12);
|
||
--patina: #5fa192; /* 铜绿锈(暗色) */
|
||
--patina-dim: rgba(95, 161, 146, 0.3);
|
||
--patina-wash: rgba(95, 161, 146, 0.06);
|
||
--fg-dim: #8a908b;
|
||
--fg-faint: #555c58;
|
||
--rule: rgba(136, 156, 144, 0.14);
|
||
--overlay-hover: rgba(255, 255, 255, 0.04);
|
||
--overlay-active: rgba(255, 255, 255, 0.08);
|
||
--cinnabar-dim: rgba(190, 60, 50, 0.35);
|
||
--cinnabar-wash: rgba(190, 60, 50, 0.06);
|
||
--aurora-1: rgba(95, 161, 146, 0.15);
|
||
--aurora-2: rgba(160, 130, 80, 0.08);
|
||
--aurora-3: rgba(40, 60, 55, 0.2);
|
||
--shadow: 0 1px 2px rgba(0, 0, 0, 0.35);
|
||
}
|
||
|
||
/*
|
||
* aurora 光晕:毛玻璃需要底层色彩才可见。
|
||
* 固定在视口、不可交互,铺三处雾化光斑(铜绿 / 铜金 / 墨青)。
|
||
*/
|
||
body::before {
|
||
content: "";
|
||
position: fixed;
|
||
inset: -10vmax;
|
||
z-index: -1;
|
||
background:
|
||
radial-gradient(
|
||
55vmax 55vmax at 12% 8%,
|
||
var(--aurora-1),
|
||
transparent 60%
|
||
),
|
||
radial-gradient(
|
||
48vmax 48vmax at 88% 16%,
|
||
var(--aurora-2),
|
||
transparent 60%
|
||
),
|
||
radial-gradient(
|
||
60vmax 60vmax at 50% 100%,
|
||
var(--aurora-3),
|
||
transparent 62%
|
||
);
|
||
filter: blur(30px);
|
||
pointer-events: none;
|
||
}
|
||
|
||
/* 细滚动条 */
|
||
* {
|
||
scrollbar-width: thin;
|
||
scrollbar-color: var(--glass-border) transparent;
|
||
}
|
||
*::-webkit-scrollbar {
|
||
width: 8px;
|
||
height: 8px;
|
||
}
|
||
*::-webkit-scrollbar-thumb {
|
||
background-color: var(--glass-border);
|
||
border-radius: 9999px;
|
||
}
|
||
}
|
||
|
||
@layer utilities {
|
||
/* 琉璃面:标准毛玻璃层 */
|
||
.glass {
|
||
background-color: var(--glass);
|
||
backdrop-filter: blur(16px) saturate(140%);
|
||
-webkit-backdrop-filter: blur(16px) saturate(140%);
|
||
border: 1px solid var(--glass-border);
|
||
}
|
||
/* 琉璃面(强):浮层 / 抽屉 / 模态 */
|
||
.glass-strong {
|
||
background-color: var(--glass-strong);
|
||
backdrop-filter: blur(24px) saturate(160%);
|
||
-webkit-backdrop-filter: blur(24px) saturate(160%);
|
||
border: 1px solid var(--glass-border);
|
||
}
|
||
|
||
/* 铜镜镜面(mirror-face):抛光的当下——助手气泡 / 朱批卡的"被照见"感。
|
||
* 鎏金细描边 + 顶光内阴影 + 底铜阴,叠在琉璃底之上;比 .glass 多一层铜温。
|
||
*/
|
||
.mirror-face {
|
||
background-color: var(--glass);
|
||
background-image: var(--face-sheen);
|
||
backdrop-filter: blur(16px) saturate(140%);
|
||
-webkit-backdrop-filter: blur(16px) saturate(140%);
|
||
border: 1px solid var(--gilt-dim);
|
||
box-shadow:
|
||
inset 0 1px 0 var(--face-in-top),
|
||
inset 0 7px 22px -16px var(--face-in-top),
|
||
inset 0 -1px 0 var(--face-in-bot),
|
||
var(--shadow);
|
||
}
|
||
|
||
/*
|
||
* 镜面光泽(对话气泡):静镜 / 活镜二态。
|
||
* 静镜(默认)——已完成消息,光泽凝固于一处(opacity .42,仅静态反射);
|
||
* 活镜(.is-live)——流式生成中,光源流转漫反射(mirror-sweep 9s)。
|
||
* 把签名光泽从"常驻装饰"提为"状态指示器":只有正在生成的镜面才流转。
|
||
* 与登录卡 .animate-sweep 同源,但区分动静二态(登录卡维持永续动画不变)。
|
||
*/
|
||
.mirror-sweep {
|
||
position: relative;
|
||
overflow: hidden;
|
||
}
|
||
.mirror-sweep::before {
|
||
content: "";
|
||
position: absolute;
|
||
inset: 0;
|
||
z-index: 0;
|
||
pointer-events: none;
|
||
background: var(--sweep-gradient);
|
||
background-size: 200% 200%;
|
||
background-position: 35% 35%;
|
||
opacity: 0.42;
|
||
}
|
||
.mirror-sweep.is-live::before {
|
||
background-position: 200% 200%;
|
||
opacity: 1;
|
||
animation: mirror-sweep 9s ease-in-out infinite;
|
||
}
|
||
|
||
/*
|
||
* 铜面颗粒(feTurbulence):与登录卡同源的金属肌理,杀死平坦矢量感。
|
||
* 叠在 .mirror-sweep 镜面之上;亮色 multiply、暗色 overlay,活镜态略强。
|
||
*/
|
||
.mirror-grain::after {
|
||
content: "";
|
||
position: absolute;
|
||
inset: 0;
|
||
z-index: 0;
|
||
pointer-events: none;
|
||
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='g'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2' seed='7'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23g)'/%3E%3C/svg%3E");
|
||
opacity: 0.028;
|
||
mix-blend-mode: multiply;
|
||
}
|
||
.dark .mirror-grain::after {
|
||
opacity: 0.018;
|
||
mix-blend-mode: overlay;
|
||
}
|
||
.mirror-grain.is-live::after {
|
||
opacity: 0.05;
|
||
}
|
||
.dark .mirror-grain.is-live::after {
|
||
opacity: 0.035;
|
||
}
|
||
|
||
/*
|
||
* 朱漆面(vermilion):司命 / 朱批 / 告警的语义热色容器。
|
||
* 左缘 3px 朱漆 + 朱漆辐射底晕——全站唯一热色,仅用于待裁定 / 告警。
|
||
*/
|
||
.vermilion {
|
||
background-color: var(--glass);
|
||
background-image: radial-gradient(
|
||
120% 100% at 0% 0%,
|
||
var(--cinnabar-dim),
|
||
transparent 60%
|
||
);
|
||
border: 1px solid var(--cinnabar-dim);
|
||
border-left: 3px solid var(--cinnabar);
|
||
}
|
||
/*
|
||
* 朱砂浓度即风险等级(与 chat-redesign-preview 同源):
|
||
* L1 浅描(低风险,去朱晕)/ L2 朱块(.vermilion 基类,默认)/ L3 满朱晕染 + 辉光(高危)。
|
||
* 等级一眼可读,文字降为辅助。color-mix 随主题变量自动适配亮/暗。
|
||
*/
|
||
.vermilion-risk-l1 {
|
||
background-image: none;
|
||
background-color: var(--surface);
|
||
border-color: var(--rule);
|
||
border-left-color: var(--cinnabar);
|
||
}
|
||
.vermilion-risk-l3 {
|
||
background-image: radial-gradient(
|
||
120% 100% at 0% 0%,
|
||
color-mix(in srgb, var(--cinnabar) 22%, transparent),
|
||
transparent 55%
|
||
);
|
||
background-color: color-mix(in srgb, var(--cinnabar) 10%, transparent);
|
||
border-color: var(--cinnabar);
|
||
box-shadow: 0 0 28px -8px
|
||
color-mix(in srgb, var(--cinnabar) 35%, transparent);
|
||
}
|
||
|
||
/* 九枢星盘(Astrolabe)SVG 词法 —— 铜镜鉴心的"仪器"线宽与字体 */
|
||
.astrolabe-ring {
|
||
fill: none;
|
||
stroke: var(--gilt-dim);
|
||
stroke-width: 1;
|
||
}
|
||
.astrolabe-ring-fine {
|
||
stroke: var(--gilt-faint);
|
||
}
|
||
.astrolabe-ring-patina {
|
||
fill: none;
|
||
stroke: var(--patina-dim);
|
||
stroke-width: 1;
|
||
}
|
||
.astrolabe-tick {
|
||
stroke: var(--gilt);
|
||
stroke-width: 1;
|
||
opacity: 0.45;
|
||
}
|
||
.astrolabe-spoke {
|
||
stroke: var(--gilt);
|
||
stroke-width: 0.6;
|
||
stroke-dasharray: 1.5 3;
|
||
opacity: 0.4;
|
||
}
|
||
.astrolabe-pivot-label {
|
||
font-family: var(--font-serif);
|
||
font-size: 12.5px;
|
||
fill: var(--fg-dim);
|
||
transition: fill 0.15s;
|
||
}
|
||
.astrolabe-pivot-sub {
|
||
font-family: var(--font-mono);
|
||
font-size: 7px;
|
||
letter-spacing: 0.08em;
|
||
fill: var(--fg-faint);
|
||
}
|
||
.astrolabe-core-glyph {
|
||
font-family: var(--font-serif);
|
||
font-size: 20px;
|
||
font-weight: 700;
|
||
fill: var(--gilt);
|
||
}
|
||
.astrolabe-core-label {
|
||
font-family: var(--font-mono);
|
||
font-size: 7px;
|
||
letter-spacing: 0.2em;
|
||
fill: var(--fg-faint);
|
||
}
|
||
|
||
/*
|
||
* grain 纹理层:feTurbulence SVG 噪点覆盖。
|
||
* 杀死平坦矢量感的关键一层 —— 昂贵页面的秘密。
|
||
* 使用时用 <div className="grain" /> 置于布局顶层。
|
||
*/
|
||
.grain {
|
||
position: fixed;
|
||
inset: 0;
|
||
z-index: 0;
|
||
pointer-events: none;
|
||
opacity: 0.025;
|
||
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='200' height='200'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.75' numOctaves='4'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
|
||
}
|
||
@media (prefers-color-scheme: dark) {
|
||
.grain {
|
||
opacity: 0.035;
|
||
}
|
||
}
|
||
|
||
/* 内容层提升(与 grain 配合) */
|
||
.content-layer {
|
||
position: relative;
|
||
z-index: 5;
|
||
}
|
||
|
||
/* 铜镜脉动环:VitrailPanel 在场指示等 */
|
||
.bg-surface-hi {
|
||
background-color: var(--surface-hi);
|
||
}
|
||
|
||
/* 镜面扫描光泽:登录卡上的斜向亮带滑移 */
|
||
.animate-sweep {
|
||
position: relative;
|
||
overflow: hidden;
|
||
}
|
||
.animate-sweep::before {
|
||
content: "";
|
||
position: absolute;
|
||
inset: 0;
|
||
z-index: 0;
|
||
pointer-events: none;
|
||
background: var(--sweep-gradient);
|
||
background-size: 200% 200%;
|
||
background-position: 200% 200%;
|
||
animation: mirror-sweep 9s ease-in-out infinite;
|
||
}
|
||
@keyframes mirror-sweep {
|
||
0% {
|
||
background-position: 200% 200%;
|
||
}
|
||
40% {
|
||
background-position: 50% 50%;
|
||
}
|
||
60% {
|
||
background-position: 50% 50%;
|
||
}
|
||
100% {
|
||
background-position: -100% -100%;
|
||
}
|
||
}
|
||
|
||
/* 星盘慢旋转:九枢活的仪器,140s 一圈 */
|
||
.animate-slow-rot {
|
||
transform-origin: center;
|
||
animation: slow-rot 140s linear infinite;
|
||
}
|
||
@keyframes slow-rot {
|
||
to {
|
||
transform: rotate(360deg);
|
||
}
|
||
}
|
||
|
||
/*
|
||
* 通用 section 眉标:世界页 / 人物页 / 记忆页共用
|
||
* 设计稿 world-preview.html / time-preview.html
|
||
*/
|
||
.section-label {
|
||
font-family: var(--font-mono);
|
||
font-size: 12px;
|
||
letter-spacing: 0.1em;
|
||
color: var(--fg-faint);
|
||
margin-bottom: 14px;
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 6px;
|
||
}
|
||
.section-label .sub {
|
||
font-size: 12px;
|
||
letter-spacing: 0.04em;
|
||
color: var(--fg-dim);
|
||
opacity: 0.75;
|
||
}
|
||
.section-label .glyph {
|
||
color: var(--gilt);
|
||
opacity: 0.8;
|
||
}
|
||
|
||
/* 人物 pill(世界页/时态页头部 + 设计稿 .char-pill) */
|
||
.char-pill {
|
||
display: inline-flex;
|
||
align-items: center;
|
||
gap: 6px;
|
||
font-size: 12.5px;
|
||
color: var(--patina);
|
||
padding: 3px 11px 3px 4px;
|
||
border: 1px solid var(--patina-dim);
|
||
border-radius: 999px;
|
||
background: var(--patina-wash);
|
||
}
|
||
.char-pill .avatar-mini {
|
||
width: 18px;
|
||
height: 18px;
|
||
border-radius: 50%;
|
||
background: var(--patina);
|
||
color: var(--ink);
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
font-family: var(--font-serif);
|
||
font-size: 11px;
|
||
font-weight: 600;
|
||
}
|
||
|
||
/*
|
||
* 侧栏背景:夜铜渐变底 + 铜绿晕染(6 处重复 -> 统一为 utility)
|
||
* 替代 AppShell / ChatShell / ChatContextRail / SessionSidebar 中的 inline gradient
|
||
*/
|
||
.bg-sidebar {
|
||
background: linear-gradient(
|
||
180deg,
|
||
color-mix(in srgb, var(--night-bronze) 92%, var(--patina) 4%),
|
||
var(--night-bronze)
|
||
);
|
||
}
|
||
|
||
/*
|
||
* 设置卡片(set-card):设置页的分组卡片布局。
|
||
* 设计稿 settings-preview.html §set-card
|
||
*/
|
||
.set-card {
|
||
border: 1px solid var(--rule);
|
||
border-radius: 10px;
|
||
background: var(--surface);
|
||
padding: 18px 20px;
|
||
}
|
||
.set-card-head {
|
||
display: flex;
|
||
align-items: baseline;
|
||
gap: 10px;
|
||
margin-bottom: 4px;
|
||
}
|
||
.set-card-title {
|
||
font-family: var(--font-serif);
|
||
font-size: 16px;
|
||
font-weight: 600;
|
||
color: var(--fg);
|
||
}
|
||
.set-card-eng {
|
||
font-family: var(--font-mono);
|
||
font-size: 11px;
|
||
color: var(--gilt);
|
||
}
|
||
.set-card-desc {
|
||
font-size: 12.5px;
|
||
color: var(--fg-dim);
|
||
margin-bottom: 16px;
|
||
line-height: 1.55;
|
||
}
|
||
.set-row {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 14px;
|
||
padding: 11px 0;
|
||
border-top: 1px solid var(--rule);
|
||
}
|
||
.set-row:first-of-type {
|
||
border-top: none;
|
||
padding-top: 4px;
|
||
}
|
||
.set-row .lab {
|
||
flex: 1;
|
||
}
|
||
.set-row .lab .t {
|
||
font-size: 13.5px;
|
||
color: var(--fg);
|
||
font-weight: 500;
|
||
}
|
||
.set-row .lab .h {
|
||
font-size: 11.5px;
|
||
color: var(--fg-faint);
|
||
margin-top: 1px;
|
||
}
|
||
.set-row .ctrl {
|
||
flex-shrink: 0;
|
||
}
|
||
.theme-pick {
|
||
display: flex;
|
||
gap: 8px;
|
||
}
|
||
.theme-opt {
|
||
display: flex;
|
||
flex-direction: column;
|
||
align-items: center;
|
||
gap: 5px;
|
||
cursor: pointer;
|
||
background: none;
|
||
border: none;
|
||
font-family: inherit;
|
||
padding: 0;
|
||
}
|
||
.theme-opt .swatch {
|
||
width: 46px;
|
||
height: 30px;
|
||
border-radius: 6px;
|
||
border: 1.5px solid var(--rule);
|
||
transition: border-color 0.12s;
|
||
}
|
||
.theme-opt.sel .swatch {
|
||
border-color: var(--patina);
|
||
box-shadow: 0 0 0 2px var(--patina-wash);
|
||
}
|
||
.theme-opt .nm {
|
||
font-size: 11px;
|
||
color: var(--fg-dim);
|
||
}
|
||
.theme-opt.sel .nm {
|
||
color: var(--patina);
|
||
font-weight: 500;
|
||
}
|
||
.seg {
|
||
display: inline-flex;
|
||
border: 1px solid var(--rule);
|
||
border-radius: 7px;
|
||
overflow: hidden;
|
||
}
|
||
.seg button {
|
||
font-family: inherit;
|
||
font-size: 12.5px;
|
||
padding: 6px 14px;
|
||
background: transparent;
|
||
color: var(--fg-dim);
|
||
border: none;
|
||
cursor: pointer;
|
||
border-right: 1px solid var(--rule);
|
||
}
|
||
.seg button:last-child {
|
||
border-right: none;
|
||
}
|
||
.seg button.sel {
|
||
background: var(--patina-wash);
|
||
color: var(--patina);
|
||
font-weight: 500;
|
||
}
|
||
.toggle {
|
||
position: relative;
|
||
width: 38px;
|
||
height: 21px;
|
||
background: var(--rule);
|
||
border-radius: 999px;
|
||
cursor: pointer;
|
||
border: none;
|
||
padding: 0;
|
||
flex-shrink: 0;
|
||
transition: background 0.15s;
|
||
}
|
||
.toggle::after {
|
||
content: "";
|
||
position: absolute;
|
||
top: 2.5px;
|
||
left: 2.5px;
|
||
width: 16px;
|
||
height: 16px;
|
||
border-radius: 50%;
|
||
background: var(--fg-dim);
|
||
transition:
|
||
transform 0.15s,
|
||
background 0.15s;
|
||
}
|
||
.toggle.on {
|
||
background: var(--patina-dim);
|
||
}
|
||
.toggle.on::after {
|
||
transform: translateX(17px);
|
||
background: var(--patina);
|
||
}
|
||
.save-hint {
|
||
font-size: 12px;
|
||
color: var(--patina);
|
||
display: inline-flex;
|
||
align-items: center;
|
||
gap: 6px;
|
||
}
|
||
.save-hint .dot {
|
||
width: 6px;
|
||
height: 6px;
|
||
border-radius: 50%;
|
||
background: var(--patina);
|
||
}
|
||
|
||
/* 铜镜徽标:LOGO 品牌图形基础 */
|
||
.logo-mark-ring {
|
||
fill: none;
|
||
stroke: var(--gilt);
|
||
stroke-width: 1.4;
|
||
opacity: 0.65;
|
||
}
|
||
.logo-mark-inner {
|
||
fill: none;
|
||
stroke: var(--patina-dim);
|
||
stroke-width: 0.8;
|
||
opacity: 0.45;
|
||
}
|
||
.logo-mark-char-ring {
|
||
fill: none;
|
||
stroke: var(--gilt-dim);
|
||
stroke-width: 0.5;
|
||
opacity: 0.35;
|
||
}
|
||
.logo-mark-char {
|
||
font-family: var(--font-serif);
|
||
font-size: 30px;
|
||
fill: var(--gilt);
|
||
font-weight: 700;
|
||
opacity: 0.8;
|
||
}
|
||
.logo-mark-dot {
|
||
fill: var(--gilt);
|
||
opacity: 0.35;
|
||
}
|
||
}
|
||
|
||
/* animate-pulse-ring:在场脉冲 —— 与铜镜呼吸脉动的视觉同构 */
|
||
@keyframes pulse-ring {
|
||
0% {
|
||
box-shadow: 0 0 0 0 rgba(111, 163, 137, 0.5);
|
||
}
|
||
70% {
|
||
box-shadow: 0 0 0 8px transparent;
|
||
}
|
||
100% {
|
||
box-shadow: 0 0 0 0 transparent;
|
||
}
|
||
}
|
||
.animate-pulse-ring {
|
||
animation: pulse-ring 2.6s cubic-bezier(0.16, 1, 0.3, 1) infinite;
|
||
}
|
||
|
||
/* 六爻当爻流光:鎏金光泽沿爻象进度条漫移(设计稿 hex-shimmer)。
|
||
容器为虚线(阴爻·未达),fill 覆盖为阳爻;当爻态漫反射流光。 */
|
||
@keyframes hex-shimmer {
|
||
0% {
|
||
background-position: 200% 0;
|
||
}
|
||
100% {
|
||
background-position: -200% 0;
|
||
}
|
||
}
|
||
.animate-hex-shimmer {
|
||
animation: hex-shimmer 2.4s linear infinite;
|
||
}
|
||
|
||
/* logo「镜启」彩蛋:触发时铜镜 gilt 辉光脉冲(设计稿 logoEggPulse 同源) */
|
||
@keyframes logo-egg-pulse {
|
||
0% {
|
||
transform: scale(1);
|
||
filter: drop-shadow(0 0 0 transparent);
|
||
}
|
||
40% {
|
||
transform: scale(1.2);
|
||
filter: drop-shadow(0 0 7px var(--gilt));
|
||
}
|
||
100% {
|
||
transform: scale(1);
|
||
filter: drop-shadow(0 0 0 transparent);
|
||
}
|
||
}
|
||
.logo-egg-pulse {
|
||
animation: logo-egg-pulse 1.4s ease;
|
||
}
|
||
|
||
/* 尊重减少动态偏好:关闭非必要动画 */
|
||
@media (prefers-reduced-motion: reduce) {
|
||
*,
|
||
*::before,
|
||
*::after {
|
||
animation-duration: 0.01ms !important;
|
||
animation-iteration-count: 1 !important;
|
||
transition-duration: 0.01ms !important;
|
||
}
|
||
}
|
||
|
||
/* ============================================================
|
||
* 自托管字体:JetBrains Mono(已下载到 public/fonts/)
|
||
* 加载优先级:系统已安装 → 本地 woff2 → SF Mono → 通用等宽字体
|
||
* ============================================================ */
|
||
@font-face {
|
||
font-family: "JetBrains Mono";
|
||
font-style: normal;
|
||
font-weight: 400;
|
||
font-display: swap;
|
||
src:
|
||
local("JetBrains Mono"),
|
||
url("/fonts/JetBrainsMono-400.woff2") format("woff2");
|
||
}
|
||
@font-face {
|
||
font-family: "JetBrains Mono";
|
||
font-style: normal;
|
||
font-weight: 500;
|
||
font-display: swap;
|
||
src:
|
||
local("JetBrains Mono Medium"),
|
||
local("JetBrainsMono-Medium"),
|
||
url("/fonts/JetBrainsMono-500.woff2") format("woff2");
|
||
}
|
||
@font-face {
|
||
font-family: "JetBrains Mono";
|
||
font-style: normal;
|
||
font-weight: 600;
|
||
font-display: swap;
|
||
src:
|
||
local("JetBrains Mono SemiBold"),
|
||
local("JetBrainsMono-SemiBold"),
|
||
url("/fonts/JetBrainsMono-600.woff2") format("woff2");
|
||
}
|
||
@font-face {
|
||
font-family: "JetBrains Mono";
|
||
font-style: normal;
|
||
font-weight: 700;
|
||
font-display: swap;
|
||
src:
|
||
local("JetBrains Mono Bold"),
|
||
local("JetBrainsMono-Bold"),
|
||
url("/fonts/JetBrainsMono-700.woff2") format("woff2");
|
||
}
|
||
|
||
/* ============================================================
|
||
* 自托管字体:Instrument Serif(英文展示衬线,15KB)
|
||
* 用于 Hero 标题/英文 slogan 等展示场景
|
||
* ============================================================ */
|
||
@font-face {
|
||
font-family: "Instrument Serif";
|
||
font-style: normal;
|
||
font-weight: 400;
|
||
font-display: swap;
|
||
src:
|
||
local("Instrument Serif"),
|
||
url("/fonts/InstrumentSerif-400.woff2") format("woff2");
|
||
}
|
||
@font-face {
|
||
font-family: "Instrument Serif";
|
||
font-style: italic;
|
||
font-weight: 400;
|
||
font-display: swap;
|
||
src:
|
||
local("Instrument Serif Italic"),
|
||
local("InstrumentSerif-Italic"),
|
||
url("/fonts/InstrumentSerif-400i.woff2") format("woff2");
|
||
}
|
||
|
||
/* Space Grotesk:英文技术感无衬线(变量字体,支持 wght 300-700) */
|
||
@font-face {
|
||
font-family: "Space Grotesk";
|
||
font-style: normal;
|
||
font-weight: 400 700;
|
||
font-display: swap;
|
||
src:
|
||
local("Space Grotesk"),
|
||
url("/fonts/SpaceGrotesk-Variable.woff2") format("woff2");
|
||
}
|
||
|
||
/* ============================================================
|
||
* 自托管字体:霞鹜文楷(LXGW WenKai)— 开源的日系/中文楷体
|
||
* 用于正文 / 人物对话 / 文学场景
|
||
* ============================================================ */
|
||
@font-face {
|
||
font-family: "LXGW WenKai";
|
||
font-style: normal;
|
||
font-weight: 300;
|
||
font-display: swap;
|
||
src:
|
||
local("LXGW WenKai Light"),
|
||
url("/fonts/LXGWWenKai-Light.woff2") format("woff2");
|
||
}
|
||
@font-face {
|
||
font-family: "LXGW WenKai";
|
||
font-style: normal;
|
||
font-weight: 400;
|
||
font-display: swap;
|
||
src:
|
||
local("LXGW WenKai"),
|
||
local("LXGW WenKai Regular"),
|
||
url("/fonts/LXGWWenKai-Regular.woff2") format("woff2");
|
||
}
|
||
@font-face {
|
||
font-family: "LXGW WenKai";
|
||
font-style: normal;
|
||
font-weight: 500;
|
||
font-display: swap;
|
||
src:
|
||
local("LXGW WenKai Medium"),
|
||
url("/fonts/LXGWWenKai-Medium.woff2") format("woff2");
|
||
}
|
||
|
||
/* 得意黑(Smiley Sans)— 开源现代圆体中文,适合标题/标签 */
|
||
@font-face {
|
||
font-family: "Smiley Sans";
|
||
font-style: oblique;
|
||
font-weight: 400;
|
||
font-display: swap;
|
||
src:
|
||
local("Smiley Sans Oblique"),
|
||
url("/fonts/SmileySans-Oblique.ttf.woff2") format("woff2");
|
||
}
|