Align MCP widget cards with web theme

This commit is contained in:
Ishaan Gupta 2026-07-02 18:59:40 +05:30
parent c811b40091
commit d5d0cb70bb
16 changed files with 65 additions and 63 deletions

View file

@ -20,22 +20,24 @@ export function WorkspaceCard({
return (
<Card
as="button"
className="w-full"
className="min-h-[116px] w-full p-3"
onClick={() => onClick(containerTag.containerTag)}
variant={active ? "active" : "interactive"}
>
<Stack gap="sm">
<Stack className="h-full" gap="sm">
<Stack align="center" direction="row" gap="sm" justify="between">
<span className="flex min-w-0 items-center gap-(--space-2)">
{containerTag.emoji ? (
<span aria-hidden className="text-base leading-none">
{containerTag.emoji}
</span>
) : (
<Package className="size-4 shrink-0 text-text-secondary" />
)}
<span className="grid size-7 shrink-0 place-items-center rounded-md bg-[#0D121A] ring-1 ring-[#161F2C] transition-colors group-hover:ring-[#3374FF]/40">
{containerTag.emoji ? (
<span aria-hidden className="text-base leading-none">
{containerTag.emoji}
</span>
) : (
<Package className="size-4 text-text-secondary" />
)}
</span>
<span
className="truncate text-(length:--text-sm) font-semibold text-text-primary"
className="truncate text-(length:--text-sm) font-medium text-text-primary"
style={{ fontFamily: "var(--font-brand)" }}
>
{name}
@ -43,11 +45,11 @@ export function WorkspaceCard({
</span>
{active ? <Check className="size-4 shrink-0 text-accent" /> : null}
</Stack>
<div className="truncate font-mono text-(length:--text-xs) text-text-muted">
<div className="truncate font-mono text-[13px] text-text-muted">
{containerTag.containerTag}
</div>
{(containerTag.documentCount > 0 || containerTag.memoryCount > 0) && (
<div className="flex items-center gap-(--space-3) text-(length:--text-xs) text-text-muted">
<div className="mt-auto flex items-center gap-(--space-2) text-(length:--text-xs) text-text-muted">
<span>
{containerTag.documentCount} doc
{containerTag.documentCount === 1 ? "" : "s"}

View file

@ -14,6 +14,9 @@
--color-bg-muted: var(--bg-muted);
--color-bg-elevated: var(--bg-elevated);
--color-bg-overlay: var(--bg-overlay);
--color-bg-panel: var(--bg-panel);
--color-bg-control: var(--bg-control);
--color-bg-control-hover: var(--bg-control-hover);
--color-border: var(--border);
--color-border-muted: var(--border-muted);
@ -95,7 +98,7 @@
linear-gradient(180deg, #0b1119 0%, #070b11 100%);
color: var(--text-primary);
font-family: var(--font-sans);
letter-spacing: -0.01em;
letter-spacing: 0;
line-height: var(--leading-normal);
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
@ -121,11 +124,11 @@
min-height: 280px;
overflow: hidden;
background:
linear-gradient(rgba(75, 160, 250, 0.035) 1px, transparent 1px),
linear-gradient(90deg, rgba(75, 160, 250, 0.035) 1px, transparent 1px),
linear-gradient(rgba(75, 160, 250, 0.04) 1px, transparent 1px),
linear-gradient(90deg, rgba(75, 160, 250, 0.04) 1px, transparent 1px),
radial-gradient(
circle at 50% 108%,
rgba(75, 160, 250, 0.22),
rgba(75, 160, 250, 0.18),
transparent 42%
),
linear-gradient(180deg, #0b1119 0%, #070b11 100%);
@ -182,14 +185,14 @@
pointer-events: none;
background: radial-gradient(
ellipse at 50% 48%,
rgba(255, 255, 255, 0.34) 0%,
rgba(71, 168, 253, 0.42) 11%,
rgba(0, 153, 255, 0.32) 28%,
rgba(20, 16, 255, 0.28) 48%,
rgba(255, 255, 255, 0.22) 0%,
rgba(71, 168, 253, 0.3) 12%,
rgba(0, 153, 255, 0.22) 28%,
rgba(20, 16, 255, 0.18) 48%,
transparent 74%
);
filter: blur(18px);
opacity: 0.9;
filter: blur(20px);
opacity: 0.78;
}
.mcp-widget-shell-graph .mcp-widget-glow {
@ -202,9 +205,9 @@
gap: var(--space-2);
margin: var(--space-4) var(--page-header-px) 0;
padding: 7px 10px 7px 8px;
border: 1px solid var(--border);
border: 1px solid #263348;
border-radius: var(--radius-lg);
background: rgba(13, 18, 26, 0.78);
background: rgba(8, 11, 15, 0.92);
backdrop-filter: blur(18px);
box-shadow: var(--shadow-sm);
}
@ -217,9 +220,7 @@
color: var(--accent);
border-radius: var(--radius-md);
background: #080b0f;
box-shadow:
inset 1.5px 1.5px 4.5px rgba(0, 0, 0, 0.7),
inset 0 1px 1px rgba(255, 255, 255, 0.03);
box-shadow: inset 1.5px 1.5px 4.5px rgba(0, 0, 0, 0.7);
}
.mcp-widget-brand-mark svg {

View file

@ -305,19 +305,20 @@
--bg-primary: #0b1119;
--bg-secondary: #101822;
--bg-muted: #131b28;
--bg-elevated: #1b1f24;
--bg-elevated: #080b0f;
--bg-overlay: rgba(13, 18, 26, 0.78);
--bg-control: #0d121a;
--bg-control-hover: #111923;
--bg-panel: #101822;
--bg-control: #080b0f;
--bg-control-hover: #0d121a;
--border: rgba(255, 255, 255, 0.12);
--border-muted: rgba(255, 255, 255, 0.07);
--border-control: rgba(255, 255, 255, 0.14);
--border-accent: rgba(34, 97, 202, 0.45);
--border: #263348;
--border-muted: #161f2c;
--border-control: #263348;
--border-accent: rgba(75, 160, 250, 0.5);
--text-primary: #fafafa;
--text-secondary: #d0dae7;
--text-muted: #a0aec4;
--text-muted: #8b8b8b;
--text-inverse: #0b1119;
--success: #4ade80;
@ -341,12 +342,9 @@
--radius-md: 6px;
--radius-lg: 8px;
--shadow-sm:
0 2px 10px rgba(0, 0, 0, 0.18), inset 0 1px 1px rgba(255, 255, 255, 0.06);
--shadow-md:
0 10px 30px rgba(0, 0, 0, 0.28), inset 0 1px 1px rgba(255, 255, 255, 0.08);
--shadow-lg:
0 20px 60px rgba(0, 0, 0, 0.42), inset 0 1px 1px rgba(255, 255, 255, 0.08);
--shadow-sm: 0 2px 12px rgba(0, 0, 0, 0.2);
--shadow-md: 0 12px 34px rgba(0, 0, 0, 0.28);
--shadow-lg: 0 20px 54px rgba(0, 0, 0, 0.38);
--graph-bg: #0b1119;
--graph-doc-fill: #1b1f24;

View file

@ -27,7 +27,7 @@ const buttonVariants = cva(
secondary: [
"bg-[var(--bg-control)] text-[var(--text-primary)]",
"border border-[var(--border-control)]",
"hover:bg-[var(--bg-control-hover)] hover:border-[var(--border-accent)]",
"hover:bg-[var(--bg-control-hover)] hover:border-[#3374FF]/50",
].join(" "),
ghost: [
"text-[var(--text-primary)]",
@ -94,7 +94,7 @@ export const Button = forwardRef<HTMLButtonElement, ButtonProps>(
{shortcut && !loading ? (
<span
className={cn(
"text-[0.8em] tracking-[0.1em]",
"text-[0.8em]",
variant === "primary" || variant === "danger"
? "opacity-60"
: variant === "ghost"

View file

@ -8,17 +8,18 @@ import { cn } from "../lib/cn"
const cardStyles = cva(
[
"text-left bg-bg-elevated border border-border rounded-lg p-4",
"shadow-md transition-colors duration-150",
"group relative overflow-hidden text-left",
"rounded-lg border border-[#0D121A] bg-bg-elevated p-4",
"transition-all duration-200",
].join(" "),
{
variants: {
variant: {
default: "",
interactive:
"cursor-pointer hover:bg-bg-muted focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-accent/20 focus-visible:ring-offset-2 focus-visible:ring-offset-bg-primary",
"cursor-pointer hover:border-[#3374FF]/50 hover:bg-bg-control-hover focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-accent/20 focus-visible:ring-offset-2 focus-visible:ring-offset-bg-primary",
active:
"cursor-pointer border-border-accent bg-accent-muted shadow-[0_0_30px_rgba(75,160,250,0.16)]",
"cursor-pointer border-[#2261CA]/70 bg-[#00173C] shadow-[0_0_28px_rgba(75,160,250,0.18)]",
},
},
defaultVariants: { variant: "default" },

View file

@ -9,7 +9,7 @@ const chipStyles = cva(
selected: {
true: "bg-accent-muted border-accent text-accent",
false:
"bg-bg-elevated border-border text-text-secondary hover:border-border-accent hover:bg-bg-muted",
"bg-bg-elevated border-[#0D121A] text-text-secondary hover:border-[#3374FF]/50 hover:bg-bg-control-hover",
},
},
defaultVariants: { selected: false },

View file

@ -14,7 +14,7 @@ export function Field({ label, hint, error, className, children }: Props) {
<div className={cn("flex flex-col gap-1.5", className)}>
{label ? (
// biome-ignore lint/a11y/noLabelWithoutControl: generic field wrapper where children provide the input
<label className="text-xs font-medium text-text-secondary uppercase tracking-wide">
<label className="text-xs font-medium uppercase text-text-secondary">
{label}
</label>
) : null}

View file

@ -58,10 +58,10 @@ export function FileUpload({
"flex min-h-[180px] flex-col items-center justify-center gap-(--space-3)",
"py-(--space-12) px-(--space-6)",
"border-2 border-dashed rounded-(--radius-lg)",
"bg-[var(--bg-control)] cursor-pointer shadow-md transition-colors",
"bg-[var(--bg-control)] cursor-pointer shadow-sm transition-all",
dragOver
? "border-accent bg-accent-muted"
: "border-[var(--border-control)] hover:bg-[var(--bg-control-hover)]",
: "border-[var(--border-control)] hover:border-[#3374FF]/50 hover:bg-[var(--bg-control-hover)]",
disabled && "pointer-events-none opacity-50",
className,
)}

View file

@ -11,9 +11,9 @@ const inputVariants = cva(
"border border-[var(--border-control)]",
"rounded-[var(--radius-lg)]",
"placeholder:text-[var(--text-muted)]",
"transition-colors",
"transition-all",
"hover:bg-[var(--bg-control-hover)]",
"focus-visible:outline-none focus-visible:border-[var(--border-accent)] focus-visible:shadow-[0_0_0_1px_var(--border-accent)]",
"focus-visible:outline-none focus-visible:border-[var(--border-accent)] focus-visible:shadow-[0_0_0_1px_var(--border-accent),0_0_24px_rgba(75,160,250,0.12)]",
"disabled:cursor-not-allowed disabled:opacity-50",
"aria-invalid:border-[var(--error)] aria-invalid:ring-[var(--error)]",
"file:border-0 file:bg-transparent file:text-[length:var(--text-sm)] file:font-medium",

View file

@ -18,7 +18,7 @@ const PopoverContent = forwardRef<
"z-50 w-72 p-(--space-4)",
"bg-bg-elevated border border-border",
"rounded-(--radius-lg)",
"shadow-lg",
"shadow-lg backdrop-blur-xl",
"data-[state=open]:animate-in data-[state=open]:fade-in-0 data-[state=open]:zoom-in-95",
"data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95",
className,

View file

@ -11,9 +11,9 @@ const textAreaClass = [
"px-[var(--space-3)] py-[var(--space-2)]",
"text-[length:var(--text-sm)] leading-normal font-sans",
"placeholder:text-[var(--text-muted)]",
"transition-colors resize-y",
"transition-all resize-y",
"hover:bg-[var(--bg-control-hover)]",
"focus-visible:outline-none focus-visible:border-[var(--border-accent)] focus-visible:shadow-[0_0_0_1px_var(--border-accent)]",
"focus-visible:outline-none focus-visible:border-[var(--border-accent)] focus-visible:shadow-[0_0_0_1px_var(--border-accent),0_0_24px_rgba(75,160,250,0.12)]",
"disabled:cursor-not-allowed disabled:opacity-50",
"aria-invalid:border-[var(--error)] aria-invalid:ring-[var(--error)]",
].join(" ")

View file

@ -9,7 +9,7 @@ export function Confirmation({ containerTag }: Props) {
return (
<Stack
align="center"
className="mx-(--page-header-px) my-(--space-6) rounded-lg border border-border bg-bg-elevated/80 px-(--page-header-px) py-(--space-10) text-center shadow-lg backdrop-blur"
className="mx-(--page-header-px) my-(--space-6) rounded-lg border border-border bg-[var(--bg-panel)] px-(--page-header-px) py-(--space-10) text-center shadow-md"
gap="md"
>
<CheckCircle className="size-12 text-success" />

View file

@ -9,7 +9,7 @@ export function ErrorView({ message }: Props) {
return (
<Stack
align="center"
className="mx-(--page-header-px) my-(--space-6) rounded-lg border border-border bg-bg-elevated/80 px-(--page-header-px) py-(--space-10) text-center shadow-lg backdrop-blur"
className="mx-(--page-header-px) my-(--space-6) rounded-lg border border-border bg-[var(--bg-panel)] px-(--page-header-px) py-(--space-10) text-center shadow-md"
gap="md"
>
<WarningCircle className="size-12 text-error" />

View file

@ -73,11 +73,11 @@ export function Save({
title="Add Memory"
/>
<div className="px-(--page-header-px) pb-(--space-6)">
<div className="rounded-(--radius-lg) border border-border bg-bg-elevated p-(--space-4) shadow-lg">
<div className="rounded-(--radius-lg) border border-border bg-[var(--bg-panel)] p-(--space-4) shadow-md">
<Stack gap="lg">
<Field label="Memory">
<TextArea
className="min-h-40"
className="min-h-40 shadow-sm"
onChange={(e) => setContent(e.target.value)}
placeholder="Enter content to save as a memory…"
value={content}

View file

@ -21,7 +21,7 @@ export function Success(props: Props) {
return (
<Stack
align="center"
className="mx-(--page-header-px) my-(--space-6) rounded-lg border border-border bg-bg-elevated/80 px-(--page-header-px) py-(--space-10) text-center shadow-lg backdrop-blur"
className="mx-(--page-header-px) my-(--space-6) rounded-lg border border-border bg-[var(--bg-panel)] px-(--page-header-px) py-(--space-10) text-center shadow-md"
gap="md"
>
<CheckCircle className="size-12 text-success" />

View file

@ -78,10 +78,10 @@ export function Upload({ activeTag, writableTags, onAdvance, onError }: Props) {
title="Upload File"
/>
<div className="px-(--page-header-px) pb-(--space-6)">
<div className="rounded-(--radius-lg) border border-border bg-bg-elevated p-(--space-4) shadow-lg">
<div className="rounded-(--radius-lg) border border-border bg-[var(--bg-panel)] p-(--space-4) shadow-md">
<Stack gap="lg">
{file ? (
<div className="flex items-center justify-between gap-(--space-3) rounded-(--radius-lg) border border-[var(--border-control)] bg-[var(--bg-control)] p-(--space-3)">
<div className="flex items-center justify-between gap-(--space-3) rounded-(--radius-lg) border border-[var(--border-control)] bg-[var(--bg-control)] p-(--space-3) shadow-sm">
<div className="flex min-w-0 items-center gap-(--space-3)">
<FileText className="size-5 shrink-0 text-text-secondary" />
<div className="flex min-w-0 flex-col">