fix: Style

This commit is contained in:
2026-03-11 17:43:37 +01:00
parent fc58dcdaa2
commit 0b8c18a43f
3 changed files with 40 additions and 35 deletions

View File

@@ -10,11 +10,7 @@ import {
MenubarItem, MenubarItem,
MenubarMenu, MenubarMenu,
MenubarSeparator, MenubarSeparator,
MenubarTrigger, MenubarTrigger
MenubarSub,
MenubarSubTrigger,
MenubarSubContent,
MenubarCheckboxItem,
} from '@/components/ui/menubar' } from '@/components/ui/menubar'
import { Kbd, KbdGroup } from '@/components/ui/kbd' import { Kbd, KbdGroup } from '@/components/ui/kbd'
import { usePlatform } from '@/app/kosmos/KosmosContext' import { usePlatform } from '@/app/kosmos/KosmosContext'
@@ -135,8 +131,20 @@ export function CanvasMenubar({
<ArrowLeft className="size-4" /> <ArrowLeft className="size-4" />
</Link> </Link>
<MenubarMenu> <MenubarMenu>
<MenubarTrigger className="font-medium">Project</MenubarTrigger> <MenubarTrigger className="font-normal text-muted-foreground">Project</MenubarTrigger>
<MenubarContent> <MenubarContent>
{projectId && (
<>
<MenubarItem
onClick={() => setIsRenamingProject(true)}
className="gap-2"
>
<Pencil className="h-4 w-4" />
Rename
</MenubarItem>
<MenubarSeparator />
</>
)}
<MenubarItem onClick={onImport} className="gap-2"> <MenubarItem onClick={onImport} className="gap-2">
<FolderOpen className="h-4 w-4" /> <FolderOpen className="h-4 w-4" />
Import Import
@@ -145,22 +153,10 @@ export function CanvasMenubar({
<Download className="h-4 w-4" /> <Download className="h-4 w-4" />
Export Export
</MenubarItem> </MenubarItem>
{projectId && (
<>
<MenubarSeparator />
<MenubarItem
onClick={() => setIsRenamingProject(true)}
className="gap-2"
>
<Pencil className="h-4 w-4" />
Rename
</MenubarItem>
</>
)}
</MenubarContent> </MenubarContent>
</MenubarMenu> </MenubarMenu>
<MenubarMenu> <MenubarMenu>
<MenubarTrigger className="font-medium">Edit</MenubarTrigger> <MenubarTrigger className="font-normal text-muted-foreground">Edit</MenubarTrigger>
<MenubarContent> <MenubarContent>
<MenubarItem onClick={undo} disabled={!canUndo} className="gap-2"> <MenubarItem onClick={undo} disabled={!canUndo} className="gap-2">
<Undo2 className="h-4 w-4" /> <Undo2 className="h-4 w-4" />
@@ -217,7 +213,7 @@ export function CanvasMenubar({
</MenubarContent> </MenubarContent>
</MenubarMenu> </MenubarMenu>
<MenubarMenu> <MenubarMenu>
<MenubarTrigger className="font-medium">View</MenubarTrigger> <MenubarTrigger className="font-normal text-muted-foreground">View</MenubarTrigger>
<MenubarContent> <MenubarContent>
{onFitView && ( {onFitView && (
<MenubarItem onClick={onFitView} className="gap-2"> <MenubarItem onClick={onFitView} className="gap-2">
@@ -250,11 +246,11 @@ export function CanvasMenubar({
} }
}} }}
onBlur={handleRenameBlur} onBlur={handleRenameBlur}
className="h-7 text-sm font-medium text-center" className="h-7 text-sm font-medium text-center font-serif"
aria-label="Project name" aria-label="Project name"
/> />
) : ( ) : (
<span className="pointer-events-none truncate text-sm font-medium text-foreground"> <span className="pointer-events-none truncate text-sm font-medium text-foreground font-serif">
{projectName ?? 'Untitled'} {projectName ?? 'Untitled'}
</span> </span>
)} )}

View File

@@ -8,7 +8,7 @@ export function KeromaPage() {
return ( return (
<div className="relative flex flex-1 flex-col min-h-0 p-4"> <div className="relative flex flex-1 flex-col min-h-0 p-4">
<div className="flex flex-wrap items-center gap-3"> <div className="flex flex-wrap items-center gap-3">
<h1 className="p-3 scroll-m-20 text-4xl font-extrabold tracking-tight text-balance"> <h1 className="p-3 scroll-m-20 text-4xl font-extrabold tracking-tight text-balance font-serif">
Keroma Keroma
</h1> </h1>
</div> </div>

View File

@@ -110,6 +110,19 @@ function getGraphCounts(projectId: string): { nodes: number; edges: number } {
type NodeLike = { id: string; position?: { x: number; y: number } } type NodeLike = { id: string; position?: { x: number; y: number } }
type EdgeLike = { id?: string; source: string; target: string } type EdgeLike = { id?: string; source: string; target: string }
/** Shared grid style for empty thumbnail, non-empty thumbnail SVG, and New project placeholder. */
const THUMBNAIL_GRID = {
baseFill: 'hsl(var(--muted) / 0.4)',
dotFill: 'hsl(var(--muted-foreground) / 0.06)',
size: 8,
} as const
const thumbnailGridStyle: React.CSSProperties = {
backgroundColor: THUMBNAIL_GRID.baseFill,
backgroundImage: `radial-gradient(circle, ${THUMBNAIL_GRID.dotFill} 1px, transparent 1px)`,
backgroundSize: `${THUMBNAIL_GRID.size}px ${THUMBNAIL_GRID.size}px`,
}
/** Renders a minimal SVG preview of the graph from storage, or a placeholder. */ /** Renders a minimal SVG preview of the graph from storage, or a placeholder. */
function GraphThumbnail({ projectId, className }: { projectId: string; className?: string }) { function GraphThumbnail({ projectId, className }: { projectId: string; className?: string }) {
const stored = loadGraphFromStorage(projectId) const stored = loadGraphFromStorage(projectId)
@@ -123,11 +136,7 @@ function GraphThumbnail({ projectId, className }: { projectId: string; className
return ( return (
<div <div
className={`flex h-full w-full flex-col items-center justify-center gap-1 text-muted-foreground ${className ?? ''}`} className={`flex h-full w-full flex-col items-center justify-center gap-1 text-muted-foreground ${className ?? ''}`}
style={{ style={thumbnailGridStyle}
backgroundImage: 'radial-gradient(circle, currentColor 1px, transparent 1px)',
backgroundSize: '8px 8px',
backgroundColor: 'hsl(var(--muted) / 0.5)',
}}
aria-hidden aria-hidden
> >
<Network className="size-8" /> <Network className="size-8" />
@@ -164,11 +173,11 @@ function GraphThumbnail({ projectId, className }: { projectId: string; className
aria-hidden aria-hidden
> >
<defs> <defs>
<pattern id={dotGridPatternId} width={8} height={8} patternUnits="userSpaceOnUse"> <pattern id={dotGridPatternId} width={THUMBNAIL_GRID.size} height={THUMBNAIL_GRID.size} patternUnits="userSpaceOnUse">
<circle cx={1} cy={1} r={0.6} fill="hsl(var(--muted-foreground) / 0.2)" /> <circle cx={THUMBNAIL_GRID.size / 2} cy={THUMBNAIL_GRID.size / 2} r={1} fill={THUMBNAIL_GRID.dotFill} />
</pattern> </pattern>
</defs> </defs>
<rect width={200} height={120} fill="hsl(var(--muted) / 0.4)" /> <rect width={200} height={120} fill={THUMBNAIL_GRID.baseFill} />
<rect width={200} height={120} fill={`url(#${dotGridPatternId})`} /> <rect width={200} height={120} fill={`url(#${dotGridPatternId})`} />
{validEdges.slice(0, 50).map((e, i) => { {validEdges.slice(0, 50).map((e, i) => {
const a = nodeById.get(e.source)!.position! const a = nodeById.get(e.source)!.position!
@@ -493,7 +502,7 @@ export function ProjectsPage() {
<div className="relative flex min-h-0 flex-1 flex-col gap-4 p-4 overflow-auto"> <div className="relative flex min-h-0 flex-1 flex-col gap-4 p-4 overflow-auto">
<TooltipProvider> <TooltipProvider>
<div className="flex flex-wrap items-center gap-3"> <div className="flex flex-wrap items-center gap-3">
<h1 className="p-3 scroll-m-20 text-4xl font-extrabold tracking-tight text-balance"> <h1 className="p-3 scroll-m-20 text-4xl font-extrabold tracking-tight text-balance font-serif">
Hi, Demiurge Hi, Demiurge
</h1> </h1>
</div> </div>
@@ -569,7 +578,7 @@ export function ProjectsPage() {
}} }}
aria-label="Create new project" aria-label="Create new project"
> >
<div className="flex aspect-video w-full shrink-0 items-center justify-center bg-muted/30"> <div className="flex aspect-video w-full shrink-0 items-center justify-center" style={thumbnailGridStyle}>
<Plus className="size-12 text-muted-foreground" /> <Plus className="size-12 text-muted-foreground" />
</div> </div>
<div className="flex flex-1 flex-col gap-1 p-3"> <div className="flex flex-1 flex-col gap-1 p-3">
@@ -794,7 +803,7 @@ export function ProjectsPage() {
}} }}
aria-label="Create new project" aria-label="Create new project"
> >
<div className="flex aspect-video w-full shrink-0 items-center justify-center bg-muted/30"> <div className="flex aspect-video w-full shrink-0 items-center justify-center" style={thumbnailGridStyle}>
<Plus className="size-12 text-muted-foreground" /> <Plus className="size-12 text-muted-foreground" />
</div> </div>
<div className="flex flex-1 flex-col gap-1 p-3"> <div className="flex flex-1 flex-col gap-1 p-3">
@@ -852,7 +861,7 @@ export function ProjectsPage() {
<div className="flex flex-1 flex-col gap-1 p-3"> <div className="flex flex-1 flex-col gap-1 p-3">
<div className="flex items-center gap-2"> <div className="flex items-center gap-2">
<Icon className="size-4 shrink-0 text-muted-foreground" /> <Icon className="size-4 shrink-0 text-muted-foreground" />
<span className="truncate font-medium">{project.name}</span> <span className="truncate font-medium font-serif">{project.name}</span>
</div> </div>
<Tooltip> <Tooltip>
<TooltipTrigger asChild> <TooltipTrigger asChild>