fix(ui): refine surface palette and states

This commit is contained in:
Jiayuan Zhang
2026-07-11 13:26:47 +08:00
parent 14ed33b9fd
commit 0fb9bb458c
6 changed files with 18 additions and 15 deletions

View File

@@ -16,13 +16,13 @@
color-scheme: light;
}
.landing-light {
--app-shell: oklch(0.955 0.002 286.32);
--page-canvas: oklch(0.98 0.001 286.32);
--app-shell: oklch(0.964435 0.001327 286.375);
--page-canvas: oklch(0.988087 0 0);
--surface: oklch(1 0 0);
--surface-foreground: oklch(0.141 0.005 285.823);
--surface-raised: oklch(1 0 0);
--surface-hover: oklch(0.967 0.001 286.375);
--surface-selected: oklch(0.95 0.014 255);
--surface-selected: oklch(0.95 0.002 286.375);
--surface-selected-foreground: oklch(0.141 0.005 285.823);
--surface-border: oklch(0.92 0.004 286.32);
--surface-shadow: 0 1px 2px rgb(15 23 42 / 0.04), 0 1px 1px rgb(15 23 42 / 0.03);

View File

@@ -32,9 +32,9 @@ Surface 系统描述的是容器之间的关系,不是把每一段内容都包
规则:
- Page Canvas 是默认内容面。需要分组时先用间距和分割线,只有独立操作或独立信息块才使用 Surface。
- 浅色模式中,`page-canvas` 必须与纯白 `surface` 保持可见但克制的明度差(当前为 `0.98``1.00`;不能只靠 border 区分设置组和页面背景。`app-shell` 与 sidebar 再各退后一级,形成由外向内逐步变亮的层级
- 浅色模式中,`app-shell` 与 sidebar 使用 `#f3f3f4``page-canvas` 使用 `#fbfbfb`Card 使用 `#ffffff`;不能只靠 border 区分设置组和页面背景。三者形成接近 Linear 的克制层级,由外向内逐步变亮。
- Card 使用 `bg-surface border-surface-border shadow-[var(--surface-shadow)]`;浮层使用 `bg-surface-raised ring-surface-border shadow-[var(--floating-shadow)]`
- `surface-hover` 只表示指针经过;`surface-selected` 表示持续选中。选中项 hover 时必须保留 `surface-selected`,不能退回 hover 状态。
- `surface-hover` 只表示指针经过;`surface-selected` 表示持续选中,并保持中性灰,不额外叠加 brand 色。选中项 hover 时必须保留 `surface-selected`,不能退回 hover 状态。
- focus 一律使用 `focus-visible` ring。不要用阴影、尺寸变化或品牌大面积填充代替键盘焦点。
- 不为 light / dark mode 手写一组平行 class。基础 surface token 已按主题解析,并通过 `color-scheme` 同步原生控件。

View File

@@ -64,13 +64,13 @@
/* Surface system: the app shell is the quiet outer frame; the page canvas
is where lists, boards, and conversations live; surfaces are reserved
for bounded content groups; raised surfaces are ephemeral overlays. */
--app-shell: oklch(0.955 0.002 286.32);
--page-canvas: oklch(0.98 0.001 286.32);
--app-shell: oklch(0.964435 0.001327 286.375);
--page-canvas: oklch(0.988087 0 0);
--surface: oklch(1 0 0);
--surface-foreground: oklch(0.141 0.005 285.823);
--surface-raised: oklch(1 0 0);
--surface-hover: oklch(0.967 0.001 286.375);
--surface-selected: oklch(0.95 0.014 255);
--surface-selected: oklch(0.95 0.002 286.375);
--surface-selected-foreground: oklch(0.141 0.005 285.823);
--surface-border: oklch(0.92 0.004 286.32);
--surface-shadow: 0 1px 2px rgb(15 23 42 / 0.04), 0 1px 1px rgb(15 23 42 / 0.03);
@@ -104,7 +104,7 @@
--chart-4: oklch(0.85 0.06 255);
--chart-5: oklch(0.92 0.03 255);
--radius: 0.625rem;
--sidebar: oklch(0.97 0.002 286.32);
--sidebar: oklch(0.964435 0.001327 286.375);
--sidebar-foreground: oklch(0.141 0.005 285.823);
--sidebar-primary: oklch(0.21 0.006 285.885);
--sidebar-primary-foreground: oklch(0.985 0 0);
@@ -136,7 +136,7 @@
--surface-foreground: oklch(0.985 0 0);
--surface-raised: oklch(0.235 0.007 285.885);
--surface-hover: oklch(0.274 0.006 286.033);
--surface-selected: oklch(0.3 0.038 255);
--surface-selected: oklch(0.3 0.006 286.033);
--surface-selected-foreground: oklch(0.985 0 0);
--surface-border: oklch(1 0 0 / 10%);
--surface-shadow: 0 1px 2px rgb(0 0 0 / 0.2), 0 1px 1px rgb(0 0 0 / 0.16);

View File

@@ -365,7 +365,7 @@ export function ChatInput({
<div
{...(uploadEnabled ? dropZoneProps : {})}
className={cn(
"relative mx-auto flex min-h-16 max-h-40 w-full max-w-4xl flex-col rounded-lg border border-surface-border bg-surface pb-9 transition-[border-color,box-shadow] focus-within:border-brand focus-within:ring-2 focus-within:ring-brand/20",
"relative mx-auto flex min-h-16 max-h-40 w-full max-w-4xl flex-col rounded-lg border border-surface-border bg-surface pb-9 transition-[border-color,box-shadow] focus-within:border-brand focus-within:ring-2 focus-within:ring-ring/20",
// Visual + interaction lock when there's no agent. We don't
// toggle ContentEditor's editable mode (Tiptap can't switch
// cleanly post-mount, and the prop has been removed); instead

View File

@@ -164,7 +164,7 @@ export const BoardCardContent = memo(function BoardCardContent({
const showRightMeta = !!showStartDate || !!showDueDate || !!showChildProgress || showUpdatedHint;
return (
<div className="rounded-lg border-[0.5px] border-surface-border bg-surface py-3 px-2.5 shadow-[var(--surface-shadow)] transition-colors group-hover/card:border-brand/30 group-hover/card:bg-surface-hover group-data-[popup-open]/card:border-brand/30 group-data-[popup-open]/card:bg-surface-hover">
<div className="rounded-lg border-[0.5px] border-surface-border bg-surface py-3 px-2.5 shadow-[var(--surface-shadow)] transition-colors group-hover/card:border-foreground/15 group-hover/card:bg-surface-hover group-data-[popup-open]/card:border-foreground/15 group-data-[popup-open]/card:bg-surface-hover">
{/* Row 1: priority + identifier (left), agent activity + assignee (right) */}
<div className="flex items-center justify-between gap-2">
<div className="flex items-center gap-1.5 min-w-0">

View File

@@ -76,6 +76,9 @@ const LEGACY_WORKSPACE_TAB_REDIRECTS: Record<string, string> = {
lark: "integrations",
};
const SETTINGS_TAB_TRIGGER_CLASS =
"h-8 shrink-0 px-2.5 hover:bg-surface-hover data-active:!bg-surface-selected data-active:!text-surface-selected-foreground data-active:hover:!bg-surface-selected md:!w-full md:px-2 md:after:hidden";
export interface ExtraSettingsTab {
value: string;
label: string;
@@ -146,7 +149,7 @@ export function SettingsPage({ extraAccountTabs }: SettingsPageProps = {}) {
<TabsTrigger
key={key}
value={key}
className="h-8 shrink-0 px-2.5 hover:bg-surface-hover data-active:!bg-surface-selected data-active:!text-surface-selected-foreground data-active:hover:!bg-surface-selected data-active:after:bg-brand md:!w-full md:px-2"
className={SETTINGS_TAB_TRIGGER_CLASS}
>
<Icon className="h-4 w-4" />
{t(($) => $.page.tabs[key])}
@@ -157,7 +160,7 @@ export function SettingsPage({ extraAccountTabs }: SettingsPageProps = {}) {
<TabsTrigger
key={tab.value}
value={tab.value}
className="h-8 shrink-0 px-2.5 hover:bg-surface-hover data-active:!bg-surface-selected data-active:!text-surface-selected-foreground data-active:hover:!bg-surface-selected data-active:after:bg-brand md:!w-full md:px-2"
className={SETTINGS_TAB_TRIGGER_CLASS}
>
<tab.icon className="h-4 w-4" />
{tab.label}
@@ -174,7 +177,7 @@ export function SettingsPage({ extraAccountTabs }: SettingsPageProps = {}) {
<TabsTrigger
key={key}
value={WORKSPACE_TAB_VALUES[key]}
className="h-8 shrink-0 px-2.5 hover:bg-surface-hover data-active:!bg-surface-selected data-active:!text-surface-selected-foreground data-active:hover:!bg-surface-selected data-active:after:bg-brand md:!w-full md:px-2"
className={SETTINGS_TAB_TRIGGER_CLASS}
>
<Icon className="h-4 w-4" />
{t(($) => $.page.tabs[key])}