Refine Lovart home visual spacing

This commit is contained in:
134 2026-06-11 17:51:18 +08:00
parent 4fe91d442e
commit 86c09ae375
6 changed files with 46 additions and 46 deletions

View File

@ -1488,14 +1488,14 @@ export function LovartHome({
sizeClassName,
"object-contain",
options?.active
? "brightness-0 opacity-85 dark:invert dark:opacity-95"
: "brightness-0 opacity-60 dark:invert dark:opacity-70"
? "brightness-0 opacity-90 dark:invert dark:opacity-95"
: "brightness-0 opacity-88 dark:invert dark:opacity-72"
)}
fallbackClassName={cn(
sizeClassName,
options?.active
? "text-[#111827] dark:text-white"
: "text-[#6b7280] dark:text-white/62"
? "text-[#202020] dark:text-white"
: "text-[#202020] dark:text-white/72"
)}
/>
);
@ -1532,7 +1532,7 @@ export function LovartHome({
const SelectedThemeIcon = selectedThemeOption.icon;
return (
<div className="min-h-svh overflow-x-hidden bg-[#f4f4f4] text-[#171717] dark:bg-[#0a0a0c] dark:text-zinc-100 [&_button]:cursor-pointer [&_input]:cursor-pointer [&_textarea]:cursor-pointer [&_img]:cursor-pointer [&_a]:cursor-pointer [&_[role=button]]:cursor-pointer">
<div className="min-h-svh overflow-x-hidden bg-white text-[#171717] dark:bg-[#0a0a0c] dark:text-zinc-100 [&_button]:cursor-pointer [&_input]:cursor-pointer [&_textarea]:cursor-pointer [&_img]:cursor-pointer [&_a]:cursor-pointer [&_[role=button]]:cursor-pointer">
<BrandTopBar
contentClassName="pl-[98px]"
logo={displayLogo}

View File

@ -24,18 +24,18 @@ export function LovartFeaturedGallery({
setActiveCategory,
}: LovartFeaturedGalleryProps) {
return (
<section ref={featuredSectionRef} className="mt-[166px]">
<section ref={featuredSectionRef} className="mt-[70px]">
<h2 className="text-[18px] font-semibold leading-none tracking-[-0.01em] text-[#1f1f1f] dark:text-white">
灵感发现
</h2>
<div className="mt-[20px] flex flex-wrap items-center gap-x-[28px] gap-y-2">
<div className="mt-[18px] flex flex-wrap items-center gap-x-[24px] gap-y-2">
{categories.map((category) => (
<button
key={category}
type="button"
onClick={() => setActiveCategory(category)}
className={`h-[34px] rounded-[8px] px-[16px] text-[14px] font-normal leading-none transition ${
className={`h-[30px] rounded-[8px] px-[13px] text-[13px] font-normal leading-none transition ${
activeCategory === category
? "bg-[#f2f2f2] text-[#202020] dark:bg-[#24242a] dark:text-white"
: "text-[#5f5f5f] hover:bg-[#f7f7f7] hover:text-[#202020] dark:text-white/55 dark:hover:bg-[#17171b]"
@ -64,25 +64,25 @@ export function LovartFeaturedGallery({
alt={item.prompt || "灵感图"}
className="block h-auto w-full rounded-[6px] bg-[#e8e8e8] object-cover transition-transform duration-300 ease-out will-change-transform group-hover:scale-[1.01] dark:bg-[#1b1c20]"
/>
<div className="mt-[8px] flex h-[24px] items-center justify-between text-[12px] font-normal leading-none text-[#b8b8b8] dark:text-white/45">
<div className="flex min-w-0 items-center gap-[7px] pr-2">
<span className="flex h-[18px] w-[18px] shrink-0 items-center justify-center overflow-hidden rounded-full bg-[#d8d8d8] text-[9px] font-medium text-white">
<div className="mt-[8px] flex h-[22px] items-center justify-between text-[11px] font-normal leading-none text-[#b8b8b8] dark:text-white/45">
<div className="flex min-w-0 items-center gap-[6px] pr-2">
<span className="flex h-[16px] w-[16px] shrink-0 items-center justify-center overflow-hidden rounded-full bg-[#d8d8d8] text-[8px] font-medium text-white">
{(item.user?.name || "C").slice(0, 1).toUpperCase()}
</span>
<span className="line-clamp-1 text-[16px] font-normal leading-none text-[#4b4b4b] dark:text-white/80">
<span className="line-clamp-1 text-[13px] font-normal leading-none text-[#4b4b4b] dark:text-white/80">
{item.user?.name || "创作者"}
</span>
</div>
<div className="inline-flex shrink-0 items-center gap-[8px] text-[12px] leading-none">
<div className="inline-flex shrink-0 items-center gap-[7px] text-[11px] leading-none">
<span className="inline-flex items-center gap-[4px]">
<PlayCircle className="h-[12px] w-[12px]" strokeWidth={2} />
<PlayCircle className="h-[11px] w-[11px]" strokeWidth={2} />
{(1200 + index * 37).toLocaleString()}
</span>
<span className="inline-flex items-center gap-[4px]">
<Heart className="h-[12px] w-[12px]" strokeWidth={2} />
<Heart className="h-[11px] w-[11px]" strokeWidth={2} />
{(20 + (index % 9) * 11).toLocaleString()}
</span>
<Gem className="h-[12px] w-[12px]" strokeWidth={2} />
<Gem className="h-[11px] w-[11px]" strokeWidth={2} />
</div>
</div>
</button>

View File

@ -111,12 +111,12 @@ export function LovartHeroComposer({
{heroSubtitleText || "懂你的设计代理,帮你搞定一切"}
</p>
<div className="mx-auto mt-6 w-full max-w-[780px] rounded-[22px] border border-black/10 bg-white px-4 pb-3 pt-4 shadow-[0_10px_24px_rgba(0,0,0,0.05)] dark:border-white/10 dark:bg-[#141416] dark:shadow-[0_18px_50px_rgba(0,0,0,0.35)]">
<div className="mx-auto mt-[34px] w-full max-w-[990px] rounded-[22px] border border-[#e1e4e8] bg-white px-[24px] pb-[12px] pt-[18px] shadow-[0_10px_26px_rgba(0,0,0,0.06)] dark:border-white/10 dark:bg-[#141416] dark:shadow-[0_18px_50px_rgba(0,0,0,0.35)]">
<Textarea
value={prompt}
onChange={(event) => setPrompt(event.target.value)}
placeholder={composerPlaceholder}
className="min-h-[76px] resize-none border-0 bg-transparent px-1 text-[12px] shadow-none focus-visible:ring-0 dark:text-white dark:placeholder:text-white/35"
className="min-h-[78px] resize-none border-0 bg-transparent px-0 !text-[16px] leading-[1.4] text-[#20242a] shadow-none placeholder:text-[#b8b8b8] focus-visible:ring-0 md:!text-[16px] dark:text-white dark:placeholder:text-white/35"
/>
{files.length > 0 && (
@ -136,10 +136,10 @@ export function LovartHeroComposer({
</div>
)}
<div className="flex items-center justify-between border-t border-black/8 pt-3 dark:border-white/8">
<div className="flex min-h-[54px] items-center justify-between pt-[12px]">
<div className="flex min-w-0 flex-1 items-center gap-4">
<label className="inline-flex h-9 w-9 cursor-pointer items-center justify-center rounded-full text-[#20242a] hover:bg-black/5 dark:text-white/72 dark:hover:bg-white/8">
<Plus className="h-5 w-5" />
<Plus className="h-5 w-5" strokeWidth={1.9} />
<input
type="file"
accept="image/*"
@ -166,7 +166,7 @@ export function LovartHeroComposer({
onClick={onStartAgentMode}
title="开启 Agent 模式"
>
<Lightbulb className="block h-5 w-5" />
<Lightbulb className="block h-5 w-5" strokeWidth={1.9} />
</button>
<Select value={selectedModelId} onValueChange={onModelChange}>
<SelectTrigger
@ -175,7 +175,7 @@ export function LovartHeroComposer({
title="选择模型"
>
<div className="flex h-9 w-9 items-center justify-center">
<Box className="block h-5 w-5" />
<Box className="block h-5 w-5" strokeWidth={1.9} />
</div>
</SelectTrigger>
<SelectContent
@ -210,30 +210,30 @@ export function LovartHeroComposer({
<Button
onClick={onSubmit}
disabled={isSubmitting || (!prompt.trim() && files.length === 0)}
className="h-11 w-11 rounded-full bg-[#eeeeef] p-0 text-[#b9bec7] hover:bg-[#e7e7e8] hover:text-[#8f96a3] dark:bg-white/10 dark:text-white/40 dark:hover:bg-white/16"
className="h-11 w-11 rounded-full bg-[#eeeeef] p-0 text-[#c9cdd4] hover:bg-[#e7e7e8] hover:text-[#8f96a3] dark:bg-white/10 dark:text-white/40 dark:hover:bg-white/16"
>
{isSubmitting ? (
<Loader2 className="h-4.5 w-4.5 animate-spin" />
) : (
<ArrowUp className="h-5 w-5" />
<ArrowUp className="h-5 w-5" strokeWidth={1.8} />
)}
</Button>
</div>
</div>
</div>
<div className="mt-4 flex flex-wrap items-center justify-center gap-1.5">
<div className="mt-[22px] flex flex-wrap items-center justify-center gap-x-[12px] gap-y-[12px]">
{visiblePromptTags.map((tag) => (
<button
key={tag.label}
type="button"
className={`inline-flex items-center gap-1.5 rounded-full border px-3 py-1 text-[12px] ${
className={`inline-flex h-[36px] items-center gap-1.5 rounded-full border px-[13px] text-[14px] font-normal ${
tag.highlighted
? "border-[#ffb15f] bg-[#fff4e7] text-[#ff8c1f] dark:border-[#8b6330] dark:bg-[#38270f] dark:text-[#ffbe6b]"
: "border-black/15 bg-white text-black/70 dark:border-white/10 dark:bg-[#141416] dark:text-white/70"
}`}
>
<tag.icon className="h-3 w-3" />
<tag.icon className="h-3.5 w-3.5" />
{tag.label}
</button>
))}

View File

@ -29,9 +29,9 @@ export function LovartProjectsSection({
return (
<section
ref={projectSectionRef}
className={isProjectsOnlyView ? "mt-6" : "mt-[46px]"}
className={isProjectsOnlyView ? "mt-6" : "mt-[86px]"}
>
<div className="mb-[32px] flex items-center justify-between">
<div className="mb-[76px] flex items-center justify-between">
<h2 className="text-[26px] font-semibold leading-none tracking-[-0.01em] text-[#1f1f1f] dark:text-white">
{isProjectsOnlyView ? "所有项目" : "最近项目"}
</h2>
@ -47,16 +47,16 @@ export function LovartProjectsSection({
) : null}
</div>
<div className="grid grid-cols-1 gap-x-[16px] gap-y-[36px] md:grid-cols-2 lg:grid-cols-5">
<div className="grid grid-cols-1 items-start gap-x-[16px] gap-y-[36px] md:grid-cols-2 lg:grid-cols-5">
<button
type="button"
onClick={onCreateProject}
className="group cursor-pointer text-left"
className="group block w-full cursor-pointer appearance-none bg-transparent p-0 text-left"
>
<div className="flex aspect-[16/9] items-center justify-center rounded-[10px] border border-dashed border-[#d4d4d4] bg-[#f7f7f7] transition group-hover:border-[#bdbdbd] group-hover:bg-[#f3f3f3] dark:border-white/15 dark:bg-[#18191d]">
<div className="flex aspect-[16/9] items-center justify-center rounded-[10px] border border-dashed border-[#d8d8d8] bg-[#f4f4f4] transition group-hover:border-[#c8c8c8] group-hover:bg-[#f2f2f2] dark:border-white/15 dark:bg-[#18191d]">
<span className="text-[34px] font-light leading-none text-[#8e8e8e]">+</span>
</div>
<div className="mt-[22px] text-[22px] font-normal leading-none tracking-[-0.01em] text-[#202020] dark:text-white">
<div className="mt-[35px] text-[22px] font-normal leading-none tracking-[-0.01em] text-[#202020] dark:text-white">
新建项目
</div>
</button>
@ -71,7 +71,7 @@ export function LovartProjectsSection({
onClick={() => onOpenProject(item.id)}
className="block w-full cursor-pointer text-left"
>
<div className="aspect-[16/9] overflow-hidden rounded-[10px] border border-[#dfdfdf] bg-[#f5f5f5] dark:border-white/10 dark:bg-[#1b1c20]">
<div className="aspect-[16/9] overflow-hidden rounded-[10px] border border-[#dddddd] bg-[#f4f4f4] dark:border-white/10 dark:bg-[#1b1c20]">
{item.thumbnail ? (
<img
src={item.thumbnail}
@ -82,7 +82,7 @@ export function LovartProjectsSection({
<div className="h-full w-full" />
)}
</div>
<div className="mt-[22px] truncate text-[22px] font-normal leading-none tracking-[-0.01em] text-[#202020] dark:text-white">
<div className="mt-[35px] truncate text-[22px] font-normal leading-none tracking-[-0.01em] text-[#202020] dark:text-white">
{item.title || "Untitled"}
</div>
<div className="mt-[13px] text-[16px] font-normal leading-none text-[#8e8e8e] dark:text-white/35">

View File

@ -88,9 +88,9 @@ export function LovartSidebar({
"rounded-[24px] border border-black/8 bg-white/96 p-2.5 text-[#111827] shadow-[0_24px_64px_rgba(15,23,42,0.12)] backdrop-blur-xl dark:border-white/10 dark:bg-[#141416]/96 dark:text-white dark:shadow-[0_24px_64px_rgba(0,0,0,0.42)]";
const sidebarButtonClass = (active = false) =>
[
"group flex h-11 w-11 shrink-0 items-center justify-center rounded-[11px] text-gray-800 transition-colors hover:bg-black/5 dark:text-white dark:hover:bg-white/10",
"group flex h-9 w-9 shrink-0 items-center justify-center rounded-[11px] text-[#202020] transition-colors hover:bg-[#f5f5f5] dark:text-white dark:hover:bg-white/10",
active
? "bg-black/5 text-gray-950 dark:bg-white/10 dark:text-white"
? "bg-[#f5f5f5] text-[#202020] dark:bg-white/10 dark:text-white"
: "",
]
.filter(Boolean)
@ -164,19 +164,19 @@ export function LovartSidebar({
return (
<aside
className={[
"fixed bottom-0 left-0 top-0 z-[100] hidden w-[62px] flex-col items-center border-r shadow-sm backdrop-blur-sm lg:flex",
"fixed bottom-0 left-0 top-0 z-[100] hidden w-[62px] flex-col items-center border-r lg:flex",
isDark
? "border-white/10 bg-black/90"
: "border-gray-200 bg-white/90",
? "border-white/10 bg-black"
: "border-[#e9e9e9] bg-white",
].join(" ")}
>
<TooltipProvider delayDuration={120}>
<div className="flex h-full w-full flex-col items-center overflow-y-auto overflow-x-hidden px-2 pb-4 pt-[22px] [-ms-overflow-style:none] [scrollbar-width:none] [&::-webkit-scrollbar]:hidden">
<div className="flex h-full w-full flex-col items-center overflow-y-auto overflow-x-hidden px-2 pb-4 pt-[15px] [-ms-overflow-style:none] [scrollbar-width:none] [&::-webkit-scrollbar]:hidden">
<Tooltip>
<TooltipTrigger asChild>
<button
type="button"
className="flex h-9 w-9 shrink-0 items-center justify-center rounded-full transition-opacity hover:opacity-80"
className="flex h-8 w-8 shrink-0 items-center justify-center rounded-full transition-opacity hover:opacity-80"
onClick={onHome}
title={siteName}
>
@ -185,14 +185,14 @@ export function LovartSidebar({
src={siteLogo}
alt={siteName}
className={[
"h-9 w-9 rounded-full object-cover",
"h-8 w-8 rounded-full object-cover",
shouldInvertLogo ? "brightness-0 invert" : "",
]
.filter(Boolean)
.join(" ")}
/>
) : (
<span className="flex h-9 w-9 items-center justify-center rounded-full bg-black text-[14px] font-semibold text-white dark:bg-white dark:text-black">
<span className="flex h-8 w-8 items-center justify-center rounded-full bg-black text-[13px] font-semibold text-white dark:bg-white dark:text-black">
{siteName.slice(0, 1).toUpperCase()}
</span>
)}
@ -201,7 +201,7 @@ export function LovartSidebar({
<TooltipContent side="right">{siteName}</TooltipContent>
</Tooltip>
<div className="mt-8 flex w-full flex-col items-center gap-1">
<div className="mt-6 flex w-full flex-col items-center gap-[18px]">
{isEnabled("newProject") ? (
<Tooltip>
<TooltipTrigger asChild>

View File

@ -41,7 +41,7 @@ export function BrandTopBar({
<header
className={cn(
positionClass,
"h-[68px] bg-[#f4f4f4]/90 backdrop-blur dark:bg-[#0a0a0c]/90",
"h-[68px] bg-white/90 backdrop-blur dark:bg-[#0a0a0c]/90",
className
)}
>