mirror of
https://github.com/supermemoryai/supermemory.git
synced 2026-09-07 08:26:15 +00:00
style(mcp): align widget UI with Nova theme
This commit is contained in:
parent
99a8adaab5
commit
dd5451e361
16 changed files with 308 additions and 36 deletions
|
|
@ -1,4 +1,4 @@
|
|||
import { useEffect } from "react"
|
||||
import { type ReactNode, useEffect } from "react"
|
||||
import type { ViewMessage } from "../shared/types"
|
||||
import { useApplyHostTheme } from "./hooks/useApplyHostTheme"
|
||||
import { useLog } from "./hooks/useLog"
|
||||
|
|
@ -25,15 +25,56 @@ export function App() {
|
|||
}
|
||||
}, [state, log])
|
||||
|
||||
if (state.kind === "loading") return <Loading />
|
||||
if (state.kind === "error") return <ErrorView message={state.message} />
|
||||
if (state.kind === "loading") {
|
||||
return (
|
||||
<WidgetShell>
|
||||
<Loading />
|
||||
</WidgetShell>
|
||||
)
|
||||
}
|
||||
if (state.kind === "error") {
|
||||
return (
|
||||
<WidgetShell>
|
||||
<ErrorView message={state.message} />
|
||||
</WidgetShell>
|
||||
)
|
||||
}
|
||||
if (state.kind === "raw") {
|
||||
return (
|
||||
<ErrorView message="Received unrecognized response from server. Try again." />
|
||||
<WidgetShell>
|
||||
<ErrorView message="Received unrecognized response from server. Try again." />
|
||||
</WidgetShell>
|
||||
)
|
||||
}
|
||||
|
||||
return renderView(state.message, setView, setError)
|
||||
return <WidgetShell>{renderView(state.message, setView, setError)}</WidgetShell>
|
||||
}
|
||||
|
||||
function WidgetShell({ children }: { children: ReactNode }) {
|
||||
return (
|
||||
<div className="mcp-widget-shell">
|
||||
<div aria-hidden className="mcp-widget-glow" />
|
||||
<header aria-label="supermemory" className="mcp-widget-brand">
|
||||
<span aria-hidden className="mcp-widget-brand-mark">
|
||||
<svg role="img" viewBox="0 0 314 256">
|
||||
<path
|
||||
d="M313.728 100.982H197.297V0H159.68V109.567C159.68 121.205 164.284 132.381 172.466 140.615L267.535 236.283L294.134 209.517L223.917 138.858H313.75V101.004L313.728 100.982Z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
<path
|
||||
d="M19.616 46.5043L89.8323 117.163H0V155.017H116.431V255.999H154.048V146.432C154.048 134.795 149.444 123.618 141.262 115.384L46.2144 19.7383L19.616 46.5043Z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
</svg>
|
||||
</span>
|
||||
<span className="mcp-widget-brand-copy">
|
||||
<span className="mcp-widget-brand-name">supermemory</span>
|
||||
<span className="mcp-widget-brand-mode">MCP</span>
|
||||
</span>
|
||||
</header>
|
||||
<main className="mcp-widget-content">{children}</main>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
function renderView(
|
||||
|
|
|
|||
|
|
@ -85,9 +85,17 @@
|
|||
}
|
||||
|
||||
body {
|
||||
background: var(--bg-primary);
|
||||
background:
|
||||
radial-gradient(
|
||||
ellipse at 50% 112%,
|
||||
rgba(75, 160, 250, 0.34) 0%,
|
||||
rgba(20, 16, 255, 0.22) 28%,
|
||||
rgba(11, 17, 25, 0) 62%
|
||||
),
|
||||
linear-gradient(180deg, #0b1119 0%, #070b11 100%);
|
||||
color: var(--text-primary);
|
||||
font-family: var(--font-sans);
|
||||
letter-spacing: -0.01em;
|
||||
line-height: var(--leading-normal);
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
|
|
@ -107,14 +115,114 @@
|
|||
position: relative;
|
||||
}
|
||||
|
||||
.mcp-widget-shell {
|
||||
position: relative;
|
||||
isolation: isolate;
|
||||
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),
|
||||
radial-gradient(
|
||||
circle at 50% 108%,
|
||||
rgba(75, 160, 250, 0.22),
|
||||
transparent 42%
|
||||
),
|
||||
linear-gradient(180deg, #0b1119 0%, #070b11 100%);
|
||||
background-size:
|
||||
36px 36px,
|
||||
36px 36px,
|
||||
100% 100%,
|
||||
100% 100%;
|
||||
color: var(--text-primary);
|
||||
}
|
||||
|
||||
.mcp-widget-glow {
|
||||
position: absolute;
|
||||
right: -18%;
|
||||
bottom: -42%;
|
||||
left: -18%;
|
||||
z-index: -1;
|
||||
height: 70%;
|
||||
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%,
|
||||
transparent 74%
|
||||
);
|
||||
filter: blur(18px);
|
||||
opacity: 0.9;
|
||||
}
|
||||
|
||||
.mcp-widget-brand {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: var(--space-2);
|
||||
margin: var(--space-4) var(--page-header-px) 0;
|
||||
padding: 7px 10px 7px 8px;
|
||||
border: 1px solid var(--border);
|
||||
border-radius: var(--radius-lg);
|
||||
background: rgba(13, 18, 26, 0.78);
|
||||
backdrop-filter: blur(18px);
|
||||
box-shadow: var(--shadow-sm);
|
||||
}
|
||||
|
||||
.mcp-widget-brand-mark {
|
||||
display: grid;
|
||||
width: 26px;
|
||||
height: 26px;
|
||||
place-items: center;
|
||||
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);
|
||||
}
|
||||
|
||||
.mcp-widget-brand-mark svg {
|
||||
width: 17px;
|
||||
height: 14px;
|
||||
}
|
||||
|
||||
.mcp-widget-brand-copy {
|
||||
display: flex;
|
||||
min-width: 0;
|
||||
flex-direction: column;
|
||||
gap: 1px;
|
||||
}
|
||||
|
||||
.mcp-widget-brand-name {
|
||||
color: var(--text-primary);
|
||||
font-size: 12px;
|
||||
font-weight: 700;
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
.mcp-widget-brand-mode {
|
||||
color: var(--text-muted);
|
||||
font-size: 10px;
|
||||
font-weight: 500;
|
||||
line-height: 1.15;
|
||||
}
|
||||
|
||||
.mcp-widget-content {
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
/* Spinner — kept as global because primitives can't easily express a CSS animation */
|
||||
.spinner {
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
border: 2px solid var(--border);
|
||||
border: 2px solid rgba(255, 255, 255, 0.12);
|
||||
border-top-color: var(--accent);
|
||||
border-radius: 50%;
|
||||
animation: spin 0.8s linear infinite;
|
||||
box-shadow: 0 0 20px rgba(75, 160, 250, 0.42);
|
||||
}
|
||||
|
||||
@keyframes spin {
|
||||
|
|
@ -141,7 +249,20 @@
|
|||
* reads as a re-layout). The floor keeps the size continuous. */
|
||||
min-height: 280px;
|
||||
position: relative;
|
||||
background: var(--bg-primary);
|
||||
background:
|
||||
linear-gradient(rgba(75, 160, 250, 0.035) 1px, transparent 1px),
|
||||
linear-gradient(90deg, rgba(75, 160, 250, 0.035) 1px, transparent 1px),
|
||||
radial-gradient(
|
||||
circle at 50% 108%,
|
||||
rgba(75, 160, 250, 0.22),
|
||||
transparent 42%
|
||||
),
|
||||
var(--bg-primary);
|
||||
background-size:
|
||||
36px 36px,
|
||||
36px 36px,
|
||||
100% 100%,
|
||||
100% 100%;
|
||||
}
|
||||
|
||||
.graph-view.fullscreen {
|
||||
|
|
|
|||
|
|
@ -277,3 +277,103 @@
|
|||
--graph-control-border: #1a2333;
|
||||
}
|
||||
}
|
||||
|
||||
/* Nova widget theme
|
||||
*
|
||||
* PR-1120's widget screens run inside agent cells, so the light/dark host
|
||||
* theme can vary independently from the Supermemory product theme. Force the
|
||||
* MCP app surfaces onto Nova's dark product palette so all widget tools match
|
||||
* apps/web: DM Sans, dark cards, soft borders, and the #4ba0fa accent.
|
||||
*/
|
||||
:root,
|
||||
[data-theme="light"],
|
||||
[data-theme="dark"] {
|
||||
color-scheme: dark;
|
||||
|
||||
--accent-start: #369bfd;
|
||||
--accent-mid: #4ba0fa;
|
||||
--accent-end: #36fdfd;
|
||||
--accent-gradient: linear-gradient(
|
||||
94deg,
|
||||
var(--accent-start),
|
||||
var(--accent-end)
|
||||
);
|
||||
|
||||
--accent: #4ba0fa;
|
||||
--accent-foreground: #ffffff;
|
||||
--accent-hover: #369bfd;
|
||||
--accent-muted: rgba(75, 160, 250, 0.12);
|
||||
|
||||
--bg-primary: #0b1119;
|
||||
--bg-secondary: #101822;
|
||||
--bg-muted: #131b28;
|
||||
--bg-elevated: #1b1f24;
|
||||
--bg-overlay: rgba(13, 18, 26, 0.78);
|
||||
|
||||
--border: rgba(255, 255, 255, 0.12);
|
||||
--border-muted: rgba(255, 255, 255, 0.07);
|
||||
--border-accent: rgba(34, 97, 202, 0.45);
|
||||
|
||||
--text-primary: #fafafa;
|
||||
--text-secondary: #d0dae7;
|
||||
--text-muted: #a0aec4;
|
||||
--text-inverse: #0b1119;
|
||||
|
||||
--success: #4ade80;
|
||||
--success-muted: rgba(74, 222, 128, 0.14);
|
||||
--error: #fb7185;
|
||||
--error-muted: rgba(251, 113, 133, 0.14);
|
||||
--warning: #fbbf24;
|
||||
--warning-muted: rgba(251, 191, 36, 0.14);
|
||||
--info: #60a5fa;
|
||||
--info-muted: rgba(96, 165, 250, 0.14);
|
||||
--danger: #ef4444;
|
||||
|
||||
--font-sans:
|
||||
"DM Sans", ui-sans-serif, system-ui, -apple-system, "Segoe UI", sans-serif;
|
||||
--font-display:
|
||||
"DM Sans", ui-sans-serif, system-ui, -apple-system, "Segoe UI", sans-serif;
|
||||
--font-brand:
|
||||
"DM Sans", ui-sans-serif, system-ui, -apple-system, "Segoe UI", sans-serif;
|
||||
|
||||
--radius-sm: 4px;
|
||||
--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);
|
||||
|
||||
--graph-bg: #0b1119;
|
||||
--graph-doc-fill: #1b1f24;
|
||||
--graph-doc-stroke: rgba(255, 255, 255, 0.12);
|
||||
--graph-doc-inner: #0d121a;
|
||||
--graph-mem-fill: #0d2034;
|
||||
--graph-mem-fill-hover: #112840;
|
||||
--graph-mem-stroke: #4ba0fa;
|
||||
--graph-accent: #4ba0fa;
|
||||
--graph-text-primary: #fafafa;
|
||||
--graph-text-secondary: #d0dae7;
|
||||
--graph-text-muted: #a0aec4;
|
||||
--graph-edge-derives: #fbbf24;
|
||||
--graph-edge-updates: #4ba0fa;
|
||||
--graph-edge-extends: #36fdfd;
|
||||
--graph-mem-border-forgotten: #ef4444;
|
||||
--graph-mem-border-expiring: #f59e0b;
|
||||
--graph-mem-border-recent: #10b981;
|
||||
--graph-glow: #4ba0fa;
|
||||
--graph-icon: #4ba0fa;
|
||||
--graph-popover-bg: rgba(27, 31, 36, 0.94);
|
||||
--graph-popover-border: rgba(255, 255, 255, 0.12);
|
||||
--graph-popover-text-primary: #fafafa;
|
||||
--graph-popover-text-secondary: #d0dae7;
|
||||
--graph-popover-text-muted: #a0aec4;
|
||||
--graph-control-bg: rgba(13, 18, 26, 0.78);
|
||||
--graph-control-border: rgba(255, 255, 255, 0.12);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,9 +9,9 @@ import { cn } from "../lib/cn"
|
|||
const buttonVariants = cva(
|
||||
[
|
||||
"inline-flex items-center justify-center gap-2",
|
||||
"uppercase tracking-[0.075em]",
|
||||
"font-semibold",
|
||||
"rounded-[var(--radius-md)]",
|
||||
"transition-colors cursor-pointer",
|
||||
"transition-all cursor-pointer",
|
||||
"disabled:pointer-events-none disabled:opacity-50",
|
||||
"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--accent)]/20 focus-visible:ring-offset-2 focus-visible:ring-offset-[var(--bg-primary)]",
|
||||
"[&_svg:not([class*='size-'])]:size-4 shrink-0",
|
||||
|
|
@ -21,12 +21,13 @@ const buttonVariants = cva(
|
|||
variant: {
|
||||
primary: [
|
||||
"bg-[var(--accent)] text-[var(--accent-foreground)]",
|
||||
"hover:bg-[var(--accent)]/90",
|
||||
"shadow-[0_10px_28px_rgba(75,160,250,0.24)]",
|
||||
"hover:bg-[var(--accent-hover)] hover:shadow-[0_12px_32px_rgba(75,160,250,0.32)]",
|
||||
].join(" "),
|
||||
secondary: [
|
||||
"bg-transparent text-[var(--text-primary)]",
|
||||
"bg-[var(--bg-overlay)] text-[var(--text-primary)]",
|
||||
"border border-[var(--border)]",
|
||||
"hover:bg-[var(--bg-muted)]",
|
||||
"hover:bg-[var(--bg-muted)] hover:border-[var(--border-accent)]",
|
||||
].join(" "),
|
||||
ghost: [
|
||||
"text-[var(--text-primary)]",
|
||||
|
|
@ -38,7 +39,7 @@ const buttonVariants = cva(
|
|||
].join(" "),
|
||||
},
|
||||
size: {
|
||||
sm: "h-[var(--height-sm)] px-[var(--space-4)] text-[length:var(--text-xs)]",
|
||||
sm: "h-[var(--height-md)] px-[var(--space-4)] text-[length:var(--text-sm)]",
|
||||
icon: "size-[var(--height-sm)] p-0",
|
||||
},
|
||||
},
|
||||
|
|
|
|||
|
|
@ -7,14 +7,18 @@ import {
|
|||
import { cn } from "../lib/cn"
|
||||
|
||||
const cardStyles = cva(
|
||||
"text-left bg-bg-elevated border border-border rounded-lg p-4 transition-colors duration-150",
|
||||
[
|
||||
"text-left bg-bg-elevated/90 border border-border rounded-lg p-4",
|
||||
"shadow-md backdrop-blur transition-colors duration-150",
|
||||
].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",
|
||||
active: "cursor-pointer border-accent bg-accent-muted",
|
||||
active:
|
||||
"cursor-pointer border-border-accent bg-accent-muted shadow-[0_0_30px_rgba(75,160,250,0.16)]",
|
||||
},
|
||||
},
|
||||
defaultVariants: { variant: "default" },
|
||||
|
|
|
|||
|
|
@ -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)",
|
||||
"cursor-pointer transition-colors",
|
||||
"bg-[var(--bg-overlay)] cursor-pointer shadow-md backdrop-blur transition-colors",
|
||||
dragOver
|
||||
? "border-accent bg-accent-muted/30"
|
||||
: "border-border hover:bg-bg-muted/40",
|
||||
? "border-accent bg-accent-muted"
|
||||
: "border-border hover:bg-bg-muted/80",
|
||||
disabled && "pointer-events-none opacity-50",
|
||||
className,
|
||||
)}
|
||||
|
|
|
|||
|
|
@ -7,13 +7,13 @@ import { cn } from "../lib/cn"
|
|||
const inputVariants = cva(
|
||||
[
|
||||
"flex w-full",
|
||||
"bg-transparent text-[var(--text-primary)]",
|
||||
"bg-[var(--bg-overlay)] text-[var(--text-primary)]",
|
||||
"border border-[var(--border)]",
|
||||
"rounded-[var(--radius-lg)]",
|
||||
"placeholder:text-[var(--text-muted)]",
|
||||
"transition-colors",
|
||||
"hover:bg-[var(--text-muted)]/10",
|
||||
"focus-visible:outline-none focus-visible:shadow-[0_0_0_1px_var(--border)]",
|
||||
"hover:bg-[var(--bg-muted)]",
|
||||
"focus-visible:outline-none focus-visible:border-[var(--border-accent)] focus-visible:shadow-[0_0_0_1px_var(--border-accent)]",
|
||||
"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",
|
||||
|
|
|
|||
|
|
@ -16,9 +16,9 @@ const PopoverContent = forwardRef<
|
|||
align={align}
|
||||
className={cn(
|
||||
"z-50 w-72 p-(--space-4)",
|
||||
"bg-bg-elevated border border-border",
|
||||
"rounded-(--radius-md)",
|
||||
"shadow-md",
|
||||
"bg-bg-elevated/95 border border-border",
|
||||
"rounded-(--radius-lg)",
|
||||
"shadow-lg backdrop-blur",
|
||||
"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,
|
||||
|
|
|
|||
|
|
@ -6,15 +6,15 @@ import { cn } from "../lib/cn"
|
|||
// controls min-height via className.
|
||||
const textAreaClass = [
|
||||
"flex w-full",
|
||||
"bg-transparent text-[var(--text-primary)]",
|
||||
"bg-[var(--bg-overlay)] text-[var(--text-primary)]",
|
||||
"border border-[var(--border)]",
|
||||
"rounded-[var(--radius-lg)]",
|
||||
"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",
|
||||
"hover:bg-[var(--text-muted)]/10",
|
||||
"focus-visible:outline-none focus-visible:shadow-[0_0_0_1px_var(--border)]",
|
||||
"hover:bg-[var(--bg-muted)]",
|
||||
"focus-visible:outline-none focus-visible:border-[var(--border-accent)] focus-visible:shadow-[0_0_0_1px_var(--border-accent)]",
|
||||
"disabled:cursor-not-allowed disabled:opacity-50",
|
||||
"aria-invalid:border-[var(--error)] aria-invalid:ring-[var(--error)]",
|
||||
].join(" ")
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
<title>Supermemory MCP</title>
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
|
||||
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&family=Space+Grotesk:wght@500;600;700&display=swap" rel="stylesheet" />
|
||||
<link href="https://fonts.googleapis.com/css2?family=DM+Sans:opsz,wght@9..40,400;9..40,500;9..40,600;9..40,700&display=swap" rel="stylesheet" />
|
||||
</head>
|
||||
<body>
|
||||
<div id="app"></div>
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
<title>Supermemory MCP · Studio</title>
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
|
||||
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&family=Space+Grotesk:wght@500;600;700&display=swap" rel="stylesheet" />
|
||||
<link href="https://fonts.googleapis.com/css2?family=DM+Sans:opsz,wght@9..40,400;9..40,500;9..40,600;9..40,700&display=swap" rel="stylesheet" />
|
||||
</head>
|
||||
<body>
|
||||
<div id="studio"></div>
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ export function Confirmation({ containerTag }: Props) {
|
|||
return (
|
||||
<Stack
|
||||
align="center"
|
||||
className="px-(--page-header-px) py-(--space-10) text-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"
|
||||
gap="md"
|
||||
>
|
||||
<CheckCircle className="size-12 text-success" />
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ export function ErrorView({ message }: Props) {
|
|||
return (
|
||||
<Stack
|
||||
align="center"
|
||||
className="px-(--page-header-px) py-(--space-10) text-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"
|
||||
gap="md"
|
||||
>
|
||||
<WarningCircle className="size-12 text-error" />
|
||||
|
|
|
|||
|
|
@ -185,8 +185,13 @@ export function Graph({ documents, totalCount }: Props) {
|
|||
}, [mode, toggleFullscreen])
|
||||
|
||||
return (
|
||||
<div className="relative">
|
||||
<div className={cn("graph-view", mode === "fullscreen" && "fullscreen")}>
|
||||
<div className="relative px-(--page-header-px) pb-(--space-6) pt-(--space-4)">
|
||||
<div
|
||||
className={cn(
|
||||
"graph-view overflow-hidden rounded-lg border border-border shadow-lg",
|
||||
mode === "fullscreen" && "fullscreen rounded-none border-0",
|
||||
)}
|
||||
>
|
||||
{/* No remount on toggle. The CSS just resizes the container; the
|
||||
package's ResizeObserver re-lays-out and its node cache keeps
|
||||
positions stable, so expand/minimize is instant with no reload.
|
||||
|
|
|
|||
|
|
@ -82,7 +82,7 @@ export function Picker({
|
|||
|
||||
{/* Bounded, scrollable list — keeps a stable height so filtering or a
|
||||
long workspace list doesn't resize (jump) the whole widget. */}
|
||||
<div className="min-h-[220px] max-h-[60vh] overflow-y-auto pr-1">
|
||||
<div className="min-h-[220px] max-h-[60vh] overflow-y-auto pr-1 scrollbar-thin">
|
||||
{filtered.length === 0 ? (
|
||||
<p className="py-(--space-6) text-center text-(length:--text-sm) text-text-muted">
|
||||
No workspaces match “{query}”.
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ export function Success(props: Props) {
|
|||
return (
|
||||
<Stack
|
||||
align="center"
|
||||
className="px-(--page-header-px) py-(--space-10) text-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"
|
||||
gap="md"
|
||||
>
|
||||
<CheckCircle className="size-12 text-success" />
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue