From a6b79a797241b0a70fa3347a55a5f3780cfb75bb Mon Sep 17 00:00:00 2001 From: ashim-hq Date: Thu, 23 Apr 2026 17:45:51 +0800 Subject: [PATCH] fix: redesign bento grid with hero AI card, fix navbar icon bug, suppress hydration warning --- apps/landing/src/app/layout.tsx | 2 +- apps/landing/src/components/bento-grid.tsx | 233 +++++++++++++-------- apps/landing/src/components/navbar.tsx | 29 +-- 3 files changed, 163 insertions(+), 101 deletions(-) diff --git a/apps/landing/src/app/layout.tsx b/apps/landing/src/app/layout.tsx index 85af1c47..5ac0be34 100644 --- a/apps/landing/src/app/layout.tsx +++ b/apps/landing/src/app/layout.tsx @@ -36,7 +36,7 @@ export const metadata: Metadata = { export default function RootLayout({ children }: { children: React.ReactNode }) { return ( - + {children} diff --git a/apps/landing/src/components/bento-grid.tsx b/apps/landing/src/components/bento-grid.tsx index 9be3e92a..4f1c65ea 100644 --- a/apps/landing/src/components/bento-grid.tsx +++ b/apps/landing/src/components/bento-grid.tsx @@ -1,4 +1,5 @@ import { + Brain, Crop, Droplets, FileType, @@ -10,73 +11,6 @@ import { } from "lucide-react"; import { FadeIn } from "./fade-in"; -const categories = [ - { - name: "Essentials", - count: 5, - tools: "Resize, Crop, Rotate, Convert, Compress", - color: "#3B82F6", - icon: Crop, - span: "md:col-span-1 md:row-span-1", - }, - { - name: "AI Tools", - count: 14, - tools: "Background Removal, Upscaling, OCR, Face Detection, Colorization, Object Eraser", - color: "#F59E0B", - icon: Sparkles, - span: "md:col-span-1 md:row-span-2", - }, - { - name: "Optimization", - count: 6, - tools: "Web Optimize, Metadata, Bulk Rename, Favicon", - color: "#10B981", - icon: Zap, - span: "md:col-span-1 md:row-span-1", - }, - { - name: "Adjustments", - count: 3, - tools: "Colors, Sharpening, Replace Color", - color: "#8B5CF6", - icon: SlidersHorizontal, - span: "md:col-span-1 md:row-span-1", - }, - { - name: "Watermark & Overlay", - count: 4, - tools: "Text Watermark, Image Watermark, Text Overlay, Composition", - color: "#EF4444", - icon: Droplets, - span: "md:col-span-1 md:row-span-1", - }, - { - name: "Utilities", - count: 7, - tools: "Image Info, Compare, Duplicates, Color Palette, QR Code", - color: "#6366F1", - icon: Wrench, - span: "md:col-span-1 md:row-span-1", - }, - { - name: "Layout & Composition", - count: 4, - tools: "Collage, Stitch, Split, Border & Frame", - color: "#EC4899", - icon: LayoutGrid, - span: "md:col-span-1 md:row-span-1", - }, - { - name: "Format & Conversion", - count: 4, - tools: "SVG to Raster, Vectorize, GIF Tools, PDF to Image", - color: "#14B8A6", - icon: FileType, - span: "md:col-span-1 md:row-span-1", - }, -]; - export function BentoGrid() { return (
@@ -90,32 +24,157 @@ export function BentoGrid() {

-
- {categories.map((cat, i) => ( - -
+
+ {/* AI Tools — hero card, spans 2 cols + 2 rows */} + +
+
+ +
+
- -

{cat.name}

- - {cat.count} + + + 14 models
-

{cat.tools}

+

AI Tools

+

+ Background removal, upscaling, OCR, face detection, colorization, object eraser, + noise removal, and more — all running locally on your hardware. +

+
+ {[ + "Remove BG", + "Upscale", + "OCR", + "Face Blur", + "Colorize", + "Denoise", + "Restore", + ].map((tag) => ( + + {tag} + + ))} +
- - ))} +
+
+ + {/* Essentials */} + + + + + {/* Optimization */} + + + + + {/* Adjustments */} + + + + + {/* Watermark & Overlay */} + + + + + {/* Utilities — wider card */} + + + + + {/* Layout & Composition */} + + + + + {/* Format & Conversion */} + + +
); } + +function Card({ + name, + count, + tools, + color, + icon: Icon, +}: { + name: string; + count: number; + tools: string; + color: string; + icon: React.ComponentType<{ size?: number; className?: string; style?: React.CSSProperties }>; +}) { + return ( +
+
+
+ +
+ + {count} + +
+

{name}

+

{tools}

+
+ ); +} diff --git a/apps/landing/src/components/navbar.tsx b/apps/landing/src/components/navbar.tsx index 16e8b7a3..9a48c315 100644 --- a/apps/landing/src/components/navbar.tsx +++ b/apps/landing/src/components/navbar.tsx @@ -24,19 +24,22 @@ export function Navbar() {
- {links.map((link) => ( - - {link.icon && } - {link.label} - - ))} + {links.map((item) => { + const Icon = item.icon; + return ( + + {Icon && } + {item.label} + + ); + })}