style: enhance UI with modern glassmorphism, animations and refined spacing

This commit is contained in:
Your Name
2025-12-19 15:11:42 +08:00
parent 691c7e34bf
commit 5f71b2783f
4 changed files with 49 additions and 29 deletions
+20 -9
View File
@@ -208,11 +208,11 @@
}
.animate-fade-in {
animation: fadeIn 0.3s ease-out forwards;
animation: fadeIn 0.4s cubic-bezier(0.16, 1, 0.3, 1) forwards;
}
.animate-slide-in-right {
animation: slideInRight 0.3s ease-out forwards;
animation: slideInRight 0.4s cubic-bezier(0.16, 1, 0.3, 1) forwards;
}
/* Message bubble animations */
@@ -228,22 +228,33 @@
}
.animate-message-in {
animation: messageIn 0.25s ease-out forwards;
animation: messageIn 0.35s cubic-bezier(0.16, 1, 0.3, 1) forwards;
}
/* Subtle floating shadow for cards */
.shadow-soft {
box-shadow:
0 1px 2px oklch(0.23 0.02 260 / 0.04),
0 4px 12px oklch(0.23 0.02 260 / 0.06),
0 8px 24px oklch(0.23 0.02 260 / 0.04);
0 2px 4px oklch(0.23 0.02 260 / 0.02),
0 6px 12px oklch(0.23 0.02 260 / 0.03),
0 12px 24px oklch(0.23 0.02 260 / 0.03);
}
.shadow-soft-lg {
box-shadow:
0 2px 4px oklch(0.23 0.02 260 / 0.04),
0 8px 20px oklch(0.23 0.02 260 / 0.08),
0 16px 40px oklch(0.23 0.02 260 / 0.06);
0 4px 8px oklch(0.23 0.02 260 / 0.03),
0 12px 24px oklch(0.23 0.02 260 / 0.05),
0 24px 48px oklch(0.23 0.02 260 / 0.04);
}
/* Gradient borders */
.border-gradient-primary {
position: relative;
background:
linear-gradient(var(--background), var(--background)) padding-box,
linear-gradient(135deg, oklch(0.55 0.18 265), oklch(0.6 0.2 290))
border-box;
border: 2px solid transparent;
border-radius: var(--radius);
}
/* Gradient text utility */
+19 -11
View File
@@ -294,6 +294,7 @@ export function ChatInput({
const { validFiles, errors } = validateFiles(
supportedFiles,
files.length,
imageSupported,
)
showValidationErrors(errors)
if (validFiles.length > 0) {
@@ -344,7 +345,7 @@ export function ChatInput({
/>
{/* Action bar */}
<div className="flex items-center justify-between px-3 py-2 border-t border-border/50">
<div className="flex items-center justify-between px-3 py-2 border-t border-border/50 bg-muted/20 rounded-b-2xl">
{/* Left actions */}
<div className="flex items-center gap-1">
<ButtonWithTooltip
@@ -371,18 +372,18 @@ export function ChatInput({
<Tooltip>
<TooltipTrigger asChild>
<div className="flex items-center gap-1.5">
<div className="flex items-center gap-1.5 px-2 py-1 rounded-md hover:bg-muted/50 transition-colors">
<Switch
id="minimal-style"
checked={minimalStyle}
onCheckedChange={onMinimalStyleChange}
className="scale-75"
className="scale-75 data-[state=checked]:bg-primary"
/>
<label
htmlFor="minimal-style"
className={`text-xs cursor-pointer select-none ${
className={`text-xs cursor-pointer select-none font-medium ${
minimalStyle
? "text-primary font-medium"
? "text-primary"
: "text-muted-foreground"
}`}
>
@@ -390,7 +391,7 @@ export function ChatInput({
</label>
</div>
</TooltipTrigger>
<TooltipContent side="top">
<TooltipContent side="top" className="text-xs">
Use minimal for faster generation (no colors)
</TooltipContent>
</Tooltip>
@@ -405,7 +406,7 @@ export function ChatInput({
onClick={() => onToggleHistory(true)}
disabled={isDisabled || diagramHistory.length === 0}
tooltipContent="Diagram history"
className="h-8 w-8 p-0 text-muted-foreground hover:text-foreground"
className="h-8 w-8 p-0 text-muted-foreground hover:text-foreground transition-colors"
>
<History className="h-4 w-4" />
</ButtonWithTooltip>
@@ -417,7 +418,7 @@ export function ChatInput({
onClick={() => setShowSaveDialog(true)}
disabled={isDisabled}
tooltipContent="Save diagram"
className="h-8 w-8 p-0 text-muted-foreground hover:text-foreground"
className="h-8 w-8 p-0 text-muted-foreground hover:text-foreground transition-colors"
>
<Download className="h-4 w-4" />
</ButtonWithTooltip>
@@ -444,7 +445,7 @@ export function ChatInput({
? "Upload file (image, PDF, text)"
: "Upload file (PDF, text)"
}
className="h-8 w-8 p-0 text-muted-foreground hover:text-foreground"
className="h-8 w-8 p-0 text-muted-foreground hover:text-foreground transition-colors"
>
<ImageIcon className="h-4 w-4" />
</ButtonWithTooltip>
@@ -463,9 +464,16 @@ export function ChatInput({
<Button
type="submit"
disabled={isDisabled || !input.trim()}
disabled={
isDisabled ||
(!input.trim() && files.length === 0)
}
size="sm"
className="h-8 px-4 rounded-xl font-medium shadow-sm"
className={`h-8 px-4 rounded-xl font-medium shadow-sm transition-all duration-300 ${
input.trim() || files.length > 0
? "bg-primary text-primary-foreground hover:bg-primary/90 hover:scale-105"
: "bg-muted text-muted-foreground opacity-70"
}`}
aria-label={
isDisabled ? "Sending..." : "Send message"
}
+5 -5
View File
@@ -1006,15 +1006,15 @@ export function ChatMessageDisplay({
return (
<div
key={`${message.id}-content-${group.startIndex}`}
className={`px-4 py-3 text-sm leading-relaxed ${
className={`px-5 py-3.5 text-sm leading-7 shadow-sm transition-all duration-300 ${
message.role ===
"user"
? "bg-primary text-primary-foreground rounded-2xl rounded-br-md shadow-sm"
? "bg-primary text-primary-foreground rounded-[20px] rounded-br-md ml-12"
: message.role ===
"system"
? "bg-destructive/10 text-destructive border border-destructive/20 rounded-2xl rounded-bl-md"
: "bg-muted/60 text-foreground rounded-2xl rounded-bl-md"
} ${message.role === "user" && isLastUserMessage && onEditMessage ? "cursor-pointer hover:opacity-90 transition-opacity" : ""} ${groupIndex > 0 ? "mt-3" : ""}`}
? "bg-destructive/5 text-destructive border border-destructive/10 rounded-xl rounded-bl-md mr-12"
: "bg-background border border-border/50 text-foreground rounded-[20px] rounded-bl-md mr-12 shadow-soft"
} ${message.role === "user" && isLastUserMessage && onEditMessage ? "cursor-pointer hover:brightness-110" : ""} ${groupIndex > 0 ? "mt-2" : ""}`}
role={
message.role ===
"user" &&
+5 -4
View File
@@ -1266,18 +1266,18 @@ Continue from EXACTLY where you stopped.`,
// Collapsed view (desktop only)
if (!isVisible && !isMobile) {
return (
<div className="h-full flex flex-col items-center pt-4 bg-card border border-border/30 rounded-xl">
<div className="h-full flex flex-col items-center pt-4 bg-card border border-border/30 rounded-xl shadow-sm transition-all duration-300 ease-in-out">
<ButtonWithTooltip
tooltipContent="Show chat panel (Ctrl+B)"
variant="ghost"
size="icon"
onClick={onToggleVisibility}
className="hover:bg-accent transition-colors"
className="hover:bg-accent transition-colors rounded-xl"
>
<PanelRightOpen className="h-5 w-5 text-muted-foreground" />
</ButtonWithTooltip>
<div
className="text-sm font-medium text-muted-foreground mt-8 tracking-wide"
className="text-sm font-medium text-muted-foreground mt-8 tracking-wide opacity-80"
style={{
writingMode: "vertical-rl",
transform: "rotate(180deg)",
@@ -1291,7 +1291,8 @@ Continue from EXACTLY where you stopped.`,
// Full view
return (
<div className="h-full flex flex-col bg-card shadow-soft animate-slide-in-right rounded-xl border border-border/30 relative">
<div className="h-full flex flex-col bg-card/80 backdrop-blur-sm shadow-soft animate-slide-in-right rounded-xl border border-border/40 relative overflow-hidden transition-all duration-300">
<div className="absolute inset-0 bg-gradient-to-b from-background/50 to-transparent pointer-events-none" />
<Toaster
position="bottom-center"
richColors