From ed147326a3593c82845287f950428ad7384cfd34 Mon Sep 17 00:00:00 2001 From: noah Date: Thu, 16 Apr 2026 15:50:15 +0200 Subject: [PATCH] feat: redesign drop zone with glassmorphism card and ambient animations Floating gradient blobs drift slowly behind a frosted glass card. Icon continuously floats up/down, pills stagger in on mount, card and icon glow pink on drag. Scales cleanly across all device sizes. Co-Authored-By: Claude Sonnet 4.6 --- src/components/DropZone.tsx | 182 +++++++++++++++++++++++++++++------- 1 file changed, 146 insertions(+), 36 deletions(-) diff --git a/src/components/DropZone.tsx b/src/components/DropZone.tsx index bb541b8..6fc707d 100644 --- a/src/components/DropZone.tsx +++ b/src/components/DropZone.tsx @@ -15,7 +15,16 @@ interface DropZoneProps { onBrowse: () => void; } -const WORDS = ["Drop", "files", "here"]; +const FORMAT_PILLS = [ + { label: "JPG", color: "bg-pink/10 text-pink" }, + { label: "PDF", color: "bg-orange/10 text-orange" }, + { label: "MP4", color: "bg-purple/10 text-purple" }, + { label: "MP3", color: "bg-blue/10 text-blue" }, + { label: "SVG", color: "bg-teal/10 text-teal" }, + { label: "CSV", color: "bg-mint/10 text-mint" }, + { label: "DOCX", color: "bg-orange/10 text-orange" }, + { label: "+60", color: "bg-[#f0ede8] text-text-light" }, +]; export function DropZone({ isDragging, @@ -27,59 +36,160 @@ export function DropZone({ }: DropZoneProps) { return (
- {/* Poster headline */} -
- {WORDS.map((word, i) => ( - - {word} - - ))} -
- - {/* Browse button — small and understated */} + {/* Animated ambient blobs */} + + + + {/* Glass card */} + + {/* Floating icon */} + + + + + + + + {/* Heading + subtitle */} + +

+ {isDragging ? "Release to add" : "Drop files here"} +

+

+ {isDragging + ? "Your files are ready for transformation" + : "Images, documents, audio, video, data"} +

+
+ + {/* Format pills */} + {!isDragging && ( +
+ {FORMAT_PILLS.map(({ label, color }, i) => ( + + {label} + + ))} +
+ )} + + {/* Browse button */} - + Browse files -

+ {/* Trust signal */} + 70+ formats — 100% client-side -

+
);