feat(ui): refine gem-blue acrylic palette and focus borders
Derive the gem-blue palette with OKLCH tonal and complementary-color rules while preserving acrylic opacity, blur and surface hierarchy. Darker focus tokens exposed stacked field rings, fallback outlines and persistent basemap selection rings. Keep fallback focus styles in the base layer and use one themed field boundary or inset card stroke. Preserve keyboard focus, invalid states and native input semantics. Add browser regression coverage for pointer and keyboard focus, all basemap presentations, narrow layouts and rendered contrast. Validation in an isolated checkout: pnpm lint, pnpm typecheck, pnpm test (393 tests), focused browser suites and pnpm build.
This commit is contained in:
@@ -6,19 +6,19 @@ import { cn } from "@/shared/ui/cn";
|
||||
export type WorkbenchTone = "neutral" | "info" | "success" | "warning" | "danger" | "teal";
|
||||
|
||||
const sectionTone: Record<WorkbenchTone, string> = {
|
||||
neutral: "bg-slate-100 text-slate-600",
|
||||
info: "bg-blue-50 text-blue-700",
|
||||
neutral: "bg-[var(--surface-control)] text-slate-600",
|
||||
info: "bg-[var(--action-soft)] text-[var(--action-blue-hover)]",
|
||||
success: "bg-emerald-50 text-emerald-700",
|
||||
warning: "bg-amber-50 text-amber-700",
|
||||
warning: "bg-[var(--status-warning-soft)] text-[var(--status-warning-foreground)]",
|
||||
danger: "bg-rose-50 text-rose-700",
|
||||
teal: "bg-cyan-50 text-cyan-800"
|
||||
};
|
||||
|
||||
const noticeTone: Record<Exclude<WorkbenchTone, "teal">, string> = {
|
||||
neutral: "border-slate-300 bg-slate-50 text-slate-700",
|
||||
info: "border-blue-500 bg-blue-50/80 text-blue-950",
|
||||
neutral: "border-[var(--surface-border)] bg-[var(--surface-reading)] text-slate-700",
|
||||
info: "border-[var(--action-blue)] bg-[var(--action-soft)]/80 text-[var(--action-blue-pressed)]",
|
||||
success: "border-emerald-500 bg-emerald-50/80 text-emerald-950",
|
||||
warning: "border-amber-500 bg-amber-50/90 text-amber-950",
|
||||
warning: "border-[var(--status-warning-mark)] bg-[var(--status-warning-soft)]/90 text-[var(--status-warning-foreground)]",
|
||||
danger: "border-rose-500 bg-rose-50/90 text-rose-950"
|
||||
};
|
||||
|
||||
@@ -53,12 +53,12 @@ export function WorkbenchSection({
|
||||
return (
|
||||
<section
|
||||
className={cn(
|
||||
"overflow-hidden rounded-[14px] border border-slate-200/90 bg-[var(--surface-reading)] shadow-[0_1px_2px_rgba(15,23,42,0.06)]",
|
||||
"overflow-hidden rounded-[14px] border border-[var(--surface-divider)]/90 bg-[var(--surface-reading)] shadow-[0_1px_2px_rgba(15,23,42,0.06)]",
|
||||
className
|
||||
)}
|
||||
{...props}
|
||||
>
|
||||
<div className="flex min-h-14 items-start gap-3 border-b border-slate-200/75 px-3.5 py-3">
|
||||
<div className="flex min-h-14 items-start gap-3 border-b border-[var(--surface-divider)]/75 bg-[var(--surface-control)] px-3.5 py-3">
|
||||
{icon ? (
|
||||
<span className={cn("mt-0.5 grid size-7 shrink-0 place-items-center rounded-lg", sectionTone[tone])}>
|
||||
{icon}
|
||||
@@ -69,7 +69,7 @@ export function WorkbenchSection({
|
||||
<h3 className="text-[13px] font-semibold leading-5 text-slate-900">{title}</h3>
|
||||
{meta}
|
||||
</div>
|
||||
{description ? <p className="mt-0.5 text-xs leading-5 text-slate-500">{description}</p> : null}
|
||||
{description ? <p className="mt-0.5 text-xs leading-5 text-[var(--ink-muted)]">{description}</p> : null}
|
||||
</div>
|
||||
{actions ? <div className="flex shrink-0 items-center gap-1">{actions}</div> : null}
|
||||
</div>
|
||||
@@ -125,10 +125,10 @@ export function WorkbenchEmptyState({
|
||||
className?: string;
|
||||
}) {
|
||||
return (
|
||||
<div className={cn("rounded-xl border border-dashed border-slate-300 bg-slate-50/70 px-4 py-5 text-center", className)}>
|
||||
{icon ? <span className="mx-auto grid size-8 place-items-center rounded-full bg-white text-slate-500 shadow-xs">{icon}</span> : null}
|
||||
<div className={cn("rounded-xl border border-dashed border-[var(--surface-border)] bg-[var(--surface-reading)]/70 px-4 py-5 text-center", className)}>
|
||||
{icon ? <span className="mx-auto grid size-8 place-items-center rounded-full bg-[var(--surface-reading)] text-[var(--ink-muted)] shadow-xs">{icon}</span> : null}
|
||||
<p className={cn("text-xs font-semibold text-slate-700", icon && "mt-2")}>{title}</p>
|
||||
{description ? <p className="mx-auto mt-1 max-w-72 text-[11px] leading-5 text-slate-500">{description}</p> : null}
|
||||
{description ? <p className="mx-auto mt-1 max-w-72 text-[11px] leading-5 text-[var(--ink-muted)]">{description}</p> : null}
|
||||
{action ? <div className="mt-3 flex justify-center">{action}</div> : null}
|
||||
</div>
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user