diff --git a/bun.lockb b/bun.lockb
index b858f82f..dc015bea 100644
Binary files a/bun.lockb and b/bun.lockb differ
diff --git a/src/data/contents/blocks/bento-10/bento-10.mdx b/src/data/contents/blocks/bento-10/bento-10.mdx
new file mode 100644
index 00000000..3c534fc3
--- /dev/null
+++ b/src/data/contents/blocks/bento-10/bento-10.mdx
@@ -0,0 +1,23 @@
+---
+title: Bento 10
+slug: bento-10
+category: bento
+description: A vibrant service marketplace bento layout featuring bold color blocks,
+ role-based listings, and quick action cards. Combining playful visuals with
+ structured information like pricing, availability, and profiles, it delivers
+ a highly scannable and engaging interface for discovering and connecting with
+ local service providers.
+image: 'https://assets.watermelon.sh/components/bento-10.webp'
+video: 'https://assets.watermelon.sh/components/bento-10.mp4'
+featured: false
+comingSoon: false
+dependencies:
+ - motion/react
+ - lucide-react
+ - react-icons
+ - clsx
+ - tailwind-merge
+install:
+ - 'npx shadcn@latest add https://registry.watermelon.sh/r/bento-10.json'
+componentNumber: 5
+---
diff --git a/src/data/contents/blocks/bento-10/demo.tsx b/src/data/contents/blocks/bento-10/demo.tsx
new file mode 100644
index 00000000..73001bac
--- /dev/null
+++ b/src/data/contents/blocks/bento-10/demo.tsx
@@ -0,0 +1,6 @@
+
+import BentoGrid10 from '.';
+
+export default function BentoGrid10Demo() {
+ return ;
+}
diff --git a/src/data/contents/blocks/bento-10/index.tsx b/src/data/contents/blocks/bento-10/index.tsx
new file mode 100644
index 00000000..00208498
--- /dev/null
+++ b/src/data/contents/blocks/bento-10/index.tsx
@@ -0,0 +1,504 @@
+'use client';
+import React from 'react';
+import { motion } from 'framer-motion';
+import { Card, CardContent } from '@/components/base-ui/card';
+
+import { FaHeart } from 'react-icons/fa6';
+import { IoSearch } from 'react-icons/io5';
+import { FaUserAlt } from 'react-icons/fa';
+import { FaGift } from 'react-icons/fa';
+import { RiMessage2Fill } from 'react-icons/ri';
+
+
+
+type IconProps = {
+ className?: string;
+};
+
+const PatternIconLarge = ({ className }: IconProps) => {
+ return (
+
+
+
+
+
+
+
+
+
+ );
+};
+const PatternIconWide = ({ className }: IconProps) => {
+ return (
+
+
+
+
+
+
+
+
+
+ );
+};
+ const PatternIconWide2 = ({ className }: IconProps) => {
+ return (
+
+
+
+
+
+
+
+
+
+ );
+};
+ const PatternIconWide3 = ({ className }: IconProps) => {
+ return (
+
+
+
+
+
+
+
+
+
+ );
+};
+
+
+export const PatternIconWide4 = ({ className }: IconProps) => {
+ return (
+
+
+
+
+
+
+
+
+
+ );
+};
+
+// type Props = {
+// className?: string;
+// };
+
+// const PatternIcon = ({ className }: Props) => {
+// return (
+//
+//
+//
+//
+//
+
+//
+//
+
+//
+//
+// );
+// };
+const icons = [FaHeart,IoSearch,FaUserAlt,FaGift,RiMessage2Fill,PatternIconLarge]
+
+const container = {
+ hidden: { opacity: 0 },
+ show: {
+ opacity: 1,
+ transition: { staggerChildren: 0.1 },
+ },
+};
+
+const item = {
+ hidden: { y: 20, opacity: 0 },
+ show: { y: 0, opacity: 1 },
+};
+
+export default function BentoGrid10() {
+ return (
+
+
+
+
+
+
+
+ Got a task in mind?
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {icons.map((Icon, i) => (
+
+ ))}
+
+
+
+
+
+ $
+ 165
+
+
+
+ Mechanic
+
+
+ No surprises. See an estimated cost before the final price through
+ the app.
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Brand idea
+
+
+ Right
+
+ Skills for
+
+ You
+
+
+ Welcome to Helper
+
+
+
+ );
+}
+
+function BentoItem({ children, className }: { children?: React.ReactNode; className: string }) {
+ return (
+
+
+
+ {children}
+
+
+
+ );
+}
+
+function WorkerCard({ name, rating, job, src }: { name: string; rating: string; job: string; src: string }) {
+ return (
+
+
+
+
+
+
+ {name}
+
+
+ {rating} / {job}
+
+
+
+ Contact Now
+
+
+ );
+}
+
+type IconType = React.ComponentType<{ className?: string }>;
+
+function TaskTag({
+ label,
+ count,
+ Icon,
+}: {
+ label: string;
+ count: string;
+ Icon: IconType;
+}) {
+ return (
+
+
+
+ {label}
+
+
+ {count}
+
+
+ );
+}
+
+function LogoIcon(props: React.SVGProps) {
+ return (
+
+
+
+
+
+
+ );
+}
+
+function CalendarIcon(props: React.SVGProps) {
+ return (
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ );
+}
diff --git a/src/data/contents/blocks/bento-11/bento-11.mdx b/src/data/contents/blocks/bento-11/bento-11.mdx
new file mode 100644
index 00000000..45282cac
--- /dev/null
+++ b/src/data/contents/blocks/bento-11/bento-11.mdx
@@ -0,0 +1,25 @@
+---
+title: Bento 11
+slug: bento-11
+category: bento
+description: A modern productivity-focused bento layout combining testimonials, task
+ scheduling, and data exploration into a unified interface. Featuring subtle
+ gradients, interactive charts, and real-time task controls, it delivers a
+ clean and functional experience for managing workflows, monitoring progress,
+ and collaborating across users in a dark, polished environment.
+image: 'https://assets.watermelon.sh/components/bento-11.webp'
+video: 'https://assets.watermelon.sh/components/bento-11.mp4'
+featured: false
+comingSoon: false
+dependencies:
+ - motion/react
+ - lucide-react
+ - react-icons
+ - clsx
+ - tailwind-merge
+install:
+ - 'npx shadcn@latest add https://registry.watermelon.sh/r/bento-11.json'
+componentNumber: 5
+---
+
+
diff --git a/src/data/contents/blocks/bento-11/demo.tsx b/src/data/contents/blocks/bento-11/demo.tsx
new file mode 100644
index 00000000..8444bb96
--- /dev/null
+++ b/src/data/contents/blocks/bento-11/demo.tsx
@@ -0,0 +1,6 @@
+
+import BentoGrid11 from '.';
+
+export default function BentoGrid11Demo() {
+ return ;
+}
diff --git a/src/data/contents/blocks/bento-11/index.tsx b/src/data/contents/blocks/bento-11/index.tsx
new file mode 100644
index 00000000..137ab51b
--- /dev/null
+++ b/src/data/contents/blocks/bento-11/index.tsx
@@ -0,0 +1,560 @@
+'use client';
+import React from 'react';
+import { Card, CardContent, CardHeader } from '@/components/base-ui/card';
+import { Button } from '@/components/ui/button';
+import { Bell } from 'lucide-react';
+import { motion, type Transition, type Variants } from 'framer-motion';
+import { useState } from 'react';
+
+import {
+ LineChart,
+ Line,
+ XAxis,
+ YAxis,
+ Tooltip,
+ ResponsiveContainer,
+} from 'recharts';
+
+function MailIcon(props: React.SVGProps) {
+ return (
+
+
+
+
+ );
+}
+
+function CrownIcon(props: React.SVGProps) {
+ return (
+
+
+
+ );
+}
+function CalendarAddIcon(props: React.SVGProps) {
+ return (
+
+
+
+
+ );
+}
+
+function ShieldSmileIcon(props: React.SVGProps) {
+ return (
+
+
+
+ );
+}
+const BentoCard = ({
+ children,
+ className,
+}: {
+ children: React.ReactNode;
+ className?: string;
+}) => (
+
+ {children}
+
+);
+
+const reviews = [
+ {
+ name: 'Sai Abhishek Mishra',
+ date: '11, Apr 2024',
+ location: 'Mumbai, India',
+ review:
+ 'Sanjay is a remarkable Product Designer, renowned for his exceptional UI skills and creating Awwwards-worthy websites. I highly recommend Sanjay for any Product Designer role that requires a talented and dedicated professional with a focus on UI skills.',
+ },
+ {
+ name: 'Courtney Henry',
+ date: '11, Feb 2024',
+ location: 'Iceland',
+ review:
+ 'Courtney is a remarkable Product Designer, renowned for his exceptional UI skills and creating Awwwards-worthy websites. I highly recommend Sanjay for any Product Designer role that requires a talented and dedicated professional with a focus on UI skills',
+ },
+];
+
+const containerVariants: Variants = {
+ initial: { y: 0 },
+ hover: { y: -150 },
+};
+
+const cardVariants: Variants = {
+ active: { x: 0, opacity: 1 },
+ inactive: { x: 20, opacity: 0.8 },
+};
+
+function ReviewsCard() {
+ const duplicated = [...reviews, ...reviews, ...reviews];
+ const [active, setActive] = useState(0);
+ const [hovered, setHovered] = useState(false);
+
+ return (
+
+
+
+
+
+ Testimonials
+
+
+
+
+ Reviews Showcase
+
+
+
+ {
+ setHovered(true);
+ setActive((p) => (p + 1) % duplicated.length);
+ }}
+ onMouseLeave={() => {
+ setHovered(false);
+ setActive((p) => (p - 1 + duplicated.length) % duplicated.length);
+ }}
+ >
+
+
+
+
+
+ {duplicated.map((review, i) => {
+ const state = i === active ? 'active' : 'inactive';
+
+ return (
+
+
+
+ {review.name}
+
+
+
+ {review.date}
+
+
+
+
+ {review.location}
+
+
+
+
+
+ {review.review}
+
+
+ );
+ })}
+
+
+
+
+ );
+}
+
+function SchedulerCard() {
+ const size = 180;
+ const stroke = 6;
+ const radius = (size - stroke) / 2;
+ const circumference = 2 * Math.PI * radius;
+ const progress = 0.75;
+ const offset = circumference * (1 - progress);
+
+ const container: Variants = {
+ hidden: {},
+ show: {
+ transition: {
+ staggerChildren: 0.2,
+ delayChildren: 0,
+ },
+ },
+ };
+
+ const textItem: Variants = {
+ hidden: {
+ opacity: 0,
+ y: 10,
+ scale: 0.9,
+ filter: 'blur(4px)',
+ },
+ show: {
+ opacity: 1,
+ y: 0,
+ scale: 1,
+ filter: 'blur(0px)',
+ transition: {
+ duration: 0.3,
+ ease: 'easeOut',
+ },
+ },
+ };
+
+ return (
+
+
+
+ Tasks Scheduler. {' '}
+
+ Get your methods invoked at a certain time or intervals.
+
+
+
+
+
+ The filler text we know today has been altered over the years. In fact
+ "Lorem" isn’t actually a word. It is suggested that the text starts
+ somewhere in classical Latin literature where there was a passage that
+ contained the word “Do-lorem”.contained the word “Do-lorem”.word word
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 09:16
+
+
+
+
+ 11:51
+
+
+
+
+
+
+ );
+}
+const transition: Transition = {
+ duration: 0.7,
+ ease: [0.65, 0, 0.35, 1],
+};
+
+const user1: Variants = {
+ initial: {
+ x: 0,
+ y: 0,
+ },
+ hover: {
+ x: 60,
+ y: -40,
+ transition,
+ },
+};
+
+const user2: Variants = {
+ initial: {
+ x: 0,
+ y: 0,
+ },
+ hover: {
+ x: -80,
+ y: 50,
+ transition,
+ },
+};
+
+function CardTable() {
+ return (
+
+
+
+
+ Multi-users. {' '}
+
+ Each end-user has his own state enabling multi-user support.
+
+
+
+
+
+
+
+
+ City
+ Status
+
+
+
+
+
+ New York
+ Cancelled
+
+
+ Singapore
+ Idle
+
+
+ India
+ Active
+
+
+ San Rafael
+ Progress
+
+
+
+
+
+
+ User 2
+
+
+
+ User 1
+
+
+
+ );
+}
+
+const data = [
+ { day: 'MON', sales: 10 },
+ { day: 'TUE', sales: 18 },
+ { day: 'WED', sales: 35 },
+ { day: 'THU', sales: 22 },
+ { day: 'FRI', sales: 30 },
+];
+
+function DatasetCard() {
+ return (
+
+
+
+
+ Explore datasets with TalkToTaipy.
+ {' '}
+
+ Leverage the LLM-based application to explore datasets using natural
+ languages.
+
+
+
+
+
+
+
+ Enter your prompt here
+
+
+ plot sales by product in chart
+
+
+
+
+ Sales by Product
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ MON
+ TUE
+ WED
+ THU
+ FRI
+
+
+
+
+ );
+}
+
+const BentoGrid11 = () => {
+ return (
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Let's Work Together
+
+ Let's Make Magic Happen Together!
+
+
+
+
+
+ Email Me
+
+
+ {' '}
+ Schedule a Call
+
+
+
+
+
+
+
+
+
+ Long jobs. {' '}
+
+ Run heavy tasks in the background without slowing down
+ experience.
+
+
+
+
+
+ Run the task
+
+
+
+
+
+
+
+ );
+};
+
+export default BentoGrid11;
diff --git a/src/data/contents/blocks/bento-12/bento-12.mdx b/src/data/contents/blocks/bento-12/bento-12.mdx
new file mode 100644
index 00000000..14d7ade5
--- /dev/null
+++ b/src/data/contents/blocks/bento-12/bento-12.mdx
@@ -0,0 +1,24 @@
+---
+title: Bento 12
+slug: bento-12
+category: bento
+description:
+ A high-performance fitness dashboard bento layout featuring bold data
+ visualizations, progress tracking, and motivational insights. With glowing
+ accent charts, dynamic activity metrics, and focused workout highlights, it
+ delivers an energetic and modern interface designed to keep users engaged,
+ informed, and consistently improving.
+image: 'https://assets.watermelon.sh/components/bento-12.webp'
+video: 'https://assets.watermelon.sh/components/bento-12.mp4'
+featured: false
+comingSoon: false
+dependencies:
+ - motion/react
+ - lucide-react
+ - react-icons
+ - clsx
+ - tailwind-merge
+install:
+ - 'npx shadcn@latest add https://registry.watermelon.sh/r/bento-12.json'
+componentNumber: 5
+---
diff --git a/src/data/contents/blocks/bento-12/demo.tsx b/src/data/contents/blocks/bento-12/demo.tsx
new file mode 100644
index 00000000..91415999
--- /dev/null
+++ b/src/data/contents/blocks/bento-12/demo.tsx
@@ -0,0 +1,8 @@
+
+import BentoGrid12 from '.'
+
+export default function BentoGrid12Demo () {
+ return (
+
+ )
+}
diff --git a/src/data/contents/blocks/bento-12/index.tsx b/src/data/contents/blocks/bento-12/index.tsx
new file mode 100644
index 00000000..874b5d3e
--- /dev/null
+++ b/src/data/contents/blocks/bento-12/index.tsx
@@ -0,0 +1,603 @@
+'use client';
+import { AnimatePresence, motion, type Variants } from 'framer-motion';
+import {
+ Card,
+ CardHeader,
+ CardTitle,
+ CardDescription,
+ CardContent,
+} from '@/components/base-ui/card';
+import { cn } from '@/lib/utils';
+import { useEffect, useState } from 'react';
+import { GiJumpingRope } from 'react-icons/gi';
+import { TbTreadmill } from 'react-icons/tb';
+import { GrYoga } from 'react-icons/gr';
+import { GiMeditation } from 'react-icons/gi';
+
+const BASE_DELAY = 0.3;
+
+const BentoCard = ({
+ title,
+ description,
+ children,
+ className,
+ ...props
+}: {
+ title?: React.ReactElement;
+ description?: React.ReactElement;
+ children?: React.ReactNode;
+ className?: string;
+}) => (
+
+ {(title || description) && (
+
+ {title && {title} }
+ {description && (
+
+ {description}
+
+ )}
+
+ )}
+
+ {children}
+
+
+);
+
+const PatternIcon10 = ({ className }: IconProps) => {
+ return (
+
+
+
+
+
+
+
+
+
+
+
+ );
+};
+
+type IconProps = {
+ className?: string;
+};
+
+const PatternIconSmall = ({ className }: IconProps) => {
+ return (
+
+
+
+
+
+
+
+
+
+ );
+};
+
+const PatternIconSmall2 = ({ className }: IconProps) => {
+ return (
+
+
+
+
+
+
+
+
+
+ );
+};
+const PatternIconSmall3 = ({ className }: IconProps) => {
+ return (
+
+
+
+
+
+
+
+
+
+ );
+};
+
+const yearlyData = [140, 170, 110, 80, 135, 190, 135];
+const monthlyData = [80, 120, 70, 50, 95, 140, 100];
+const CHART_HEIGHT = 220;
+const BAR_WIDTH = 50;
+const GAP = 14;
+const labelsYear = ['JAN', 'FEB', 'MAR', 'APR', 'MAY', 'JUN', 'JUL'];
+const BarGraphCard = () => {
+ const [isYear, setIsYear] = useState(true);
+
+ useEffect(() => {
+ const interval = setInterval(() => {
+ setIsYear((prev) => !prev);
+ }, 3000);
+
+ return () => clearInterval(interval);
+ }, []);
+
+ const data = isYear ? yearlyData : monthlyData;
+ const labels = labelsYear;
+
+ return (
+
+ Outwork Yesterday
+
+ }
+ description={
+
+ Track your stats and see how you stack up.
+
+ }
+ >
+
+
+
+ Monthly Graph
+
+
+
+
+
+ {isYear ? '2026' : '2025'}
+
+
+
+
+
+ {/* CHART */}
+
+
+
+
+
+
+
+
+
+ {data.map((height, i) => {
+ const x = i * (BAR_WIDTH + GAP);
+
+ return (
+
+ );
+ })}
+
+
+ {/* LABELS */}
+
+ {labels.map((label, i) => (
+
+ {label}
+
+ ))}
+
+
+
+
+ );
+};
+const dots = [
+ { x: '50%', y: '10%', icon: PatternIconSmall3 },
+ { x: '50%', y: '90%', icon: PatternIconSmall2 },
+ { x: '-10%', y: '30%', icon: PatternIconSmall },
+ { x: '-10%', y: '70%', icon: GiJumpingRope },
+ { x: '15%', y: '50%', icon: TbTreadmill },
+ { x: '110%', y: '30%', icon: GrYoga },
+ { x: '110%', y: '70%', icon: GiMeditation },
+ { x: '85%', y: '50%', icon: GiJumpingRope },
+];
+const delays = dots.map(() => BASE_DELAY + Math.random() * 0.8);
+const cardVariants: Variants = {
+ hidden: { opacity: 0, y: 20 },
+ visible: {
+ opacity: 1,
+ y: 0,
+ transition: { duration: 0.6, ease: [0.22, 1, 0.36, 1] },
+ },
+ hover: {
+ scale: 1.02,
+ },
+};
+
+const lineVariants: Variants = {
+ hidden: { pathLength: 0, opacity: 0 },
+ visible: {
+ pathLength: 0.5,
+ opacity: 1,
+ transition: { duration: 1.6, ease: 'easeInOut' },
+ },
+ hover: {
+ pathLength: 1,
+ opacity: 1,
+ transition: { duration: 1, ease: 'easeInOut' },
+ },
+};
+
+const containerVariants: Variants = {
+ hidden: {},
+ visible: { transition: { staggerChildren: 0.12 } },
+};
+
+const avatarVariants: Variants = {
+ hidden: { x: 60, opacity: 0 },
+ visible: (i) => ({
+ x: 0,
+ opacity: 1,
+ transition: {
+ delay: BASE_DELAY + i * 0.07,
+ duration: 0.5,
+ ease: [0.22, 1, 0.36, 1],
+ },
+ }),
+};
+const images = [
+ 'https://randomuser.me/api/portraits/men/32.jpg',
+ 'https://randomuser.me/api/portraits/women/44.jpg',
+ 'https://randomuser.me/api/portraits/men/78.jpg',
+ 'https://randomuser.me/api/portraits/women/40.jpg',
+];
+const BentoGrid12 = () => {
+ return (
+
+
+
+ Train Smarter
+
+ See Results Faster
+
+ }
+ description={
+
+ Sync your health data to merge expert workouts with your personal
+ biometrics. Every rep, run, and ring closed, visualized.
+
+ }
+ >
+
+
+
+
+ 83k
+
+
+
+ ACTIVITY
+
+
+ USERS
+
+
+
+
+ {[0, 2, 4, 6, 8, 10].map((val) => (
+
+ ))}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Find Your Flow
+
+ }
+ >
+
+
+ {/* CENTER NODE */}
+
+
+ {dots.map((dot, i) => (
+
+
+
+ ))}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Never the Same Workout Twice
+
+
+
+
+ Train with
+
+ the Elite
+
+ }
+ >
+
+ {images.map((img, i) => (
+
+
+
+
+
+ ))}
+
+
+
+
+
+ );
+};
+
+export default BentoGrid12;
diff --git a/src/data/contents/blocks/bento-13/bento-13.mdx b/src/data/contents/blocks/bento-13/bento-13.mdx
new file mode 100644
index 00000000..029f9a0c
--- /dev/null
+++ b/src/data/contents/blocks/bento-13/bento-13.mdx
@@ -0,0 +1,25 @@
+---
+title: Bento 13
+slug: bento-13
+category: bento
+description: >-
+ A clean financial dashboard bento layout focused on wealth management and
+ growth insights. Featuring soft gradients, intuitive charts, and modular
+ cards for planning, investments, and community support, it delivers a calm
+ and structured interface for tracking finances, making informed decisions,
+ and visualizing progress over time.
+image: 'https://assets.watermelon.sh/components/bento-13.webp'
+video: 'https://assets.watermelon.sh/components/bento-13.mp4'
+featured: false
+comingSoon: false
+dependencies:
+ - motion/react
+ - lucide-react
+ - react-icons
+ - clsx
+ - tailwind-merge
+install:
+ - 'npx shadcn@latest add https://registry.watermelon.sh/r/bento-13.json'
+componentNumber: 5
+---
+
diff --git a/src/data/contents/blocks/bento-13/demo.tsx b/src/data/contents/blocks/bento-13/demo.tsx
new file mode 100644
index 00000000..b8f74132
--- /dev/null
+++ b/src/data/contents/blocks/bento-13/demo.tsx
@@ -0,0 +1,6 @@
+
+import BentoGrid13 from '.';
+
+export default function BentoGrid13Demo() {
+ return ;
+}
diff --git a/src/data/contents/blocks/bento-13/index.tsx b/src/data/contents/blocks/bento-13/index.tsx
new file mode 100644
index 00000000..11192ad2
--- /dev/null
+++ b/src/data/contents/blocks/bento-13/index.tsx
@@ -0,0 +1,636 @@
+import { useState } from 'react';
+import { cn } from '@/lib/utils';
+import {
+ motion,
+ MotionConfig,
+ useSpring,
+ useTransform,
+ type Variants,
+} from 'motion/react';
+import { useEffect } from 'react';
+import {
+ Card,
+ CardContent,
+ CardDescription,
+ CardHeader,
+ CardTitle,
+} from '@/components/base-ui/card';
+
+import { AiOutlineDollarCircle } from 'react-icons/ai';
+import { FaLock } from 'react-icons/fa6';
+
+type AnimatedNumberProps = {
+ value: number;
+ className?: string;
+ springOptions?: Parameters[1];
+ as?: 'span' | 'div' | 'p';
+ decimals?: number;
+ prefix?: string;
+ suffix?: string;
+};
+
+const MotionMap = {
+ span: motion.span,
+ div: motion.div,
+ p: motion.p,
+};
+
+export function AnimatedNumber({
+ value,
+ className,
+ springOptions,
+ as = 'span',
+ decimals = 0,
+ prefix = '',
+ suffix = '',
+}: AnimatedNumberProps) {
+ const MotionComponent = MotionMap[as] || motion.span;
+
+ const spring = useSpring(value, {
+ stiffness: 120,
+ damping: 20,
+ ...springOptions,
+ });
+
+ const display = useTransform(spring, (current) => {
+ const formatted = current.toFixed(decimals);
+ const number = Number(formatted).toLocaleString();
+ return `${prefix}${number}${suffix}`;
+ });
+
+ useEffect(() => {
+ spring.set(value);
+ }, [spring, value]);
+
+ return (
+
+ {display}
+
+ );
+}
+const phoneVariants: Variants = {
+ initial: { y: 100 },
+ hover: {
+ y: 20,
+ transition: {
+ duration: 0.4,
+ ease: [0.65, 0, 0.35, 1],
+ staggerChildren: 0.03,
+ delayChildren: 0.05,
+ },
+ },
+};
+
+const hiddenItem: Variants = {
+ initial: { opacity: 0, y: 20 },
+ hover: {
+ opacity: 1,
+ y: 0,
+ transition: {
+ duration: 0.45,
+ ease: [0.65, 0, 0.35, 1],
+ },
+ },
+};
+
+const progressVariants: Variants = {
+ initial: { strokeDashoffset: 230 },
+ hover: {
+ strokeDashoffset: 75.36,
+ transition: {
+ duration: 0.45,
+ ease: [0.65, 0, 0.35, 1],
+ },
+ },
+};
+
+const barVariants: Variants = {
+ initial: { scaleY: 0.5 },
+ hover: {
+ scaleY: 1,
+ transition: {
+ duration: 0.45,
+ ease: [0.65, 0, 0.35, 1],
+ },
+ },
+};
+
+const images = [
+ 'https://randomuser.me/api/portraits/men/32.jpg',
+ 'https://randomuser.me/api/portraits/women/44.jpg',
+ 'https://randomuser.me/api/portraits/men/78.jpg',
+ 'https://randomuser.me/api/portraits/women/40.jpg',
+ 'https://randomuser.me/api/portraits/men/13.jpg',
+ 'https://randomuser.me/api/portraits/women/17.jpg',
+];
+
+const FinancialWellnessCard = () => {
+ const [isHovering, setIsHovering] = useState(false);
+
+ return (
+
+ setIsHovering(true)}
+ onMouseLeave={() => setIsHovering(false)}
+ className="relative col-span-1 flex flex-col items-center overflow-hidden rounded-3xl border border-white/5 bg-[#1a1a1a] px-6 pt-8 text-center md:col-span-3"
+ >
+
+
+
+ Financial Wellness
+
+
+
+ Gain control of your spending with intuitive tracking and
+ categorization.
+
+
+
+
+
+
+
+
+
+
+ Welcome Back!
+
+
Hi, Choudary Aoun
+
+
+
+
+
+
+
+ {[1, 2, 3, 4].map((i) => (
+
+ ))}
+
+
+
+
+ Projects
+
+
+
+
+
+
+
+
+
+
+ {[60, 80, 65, 95, 100, 40, 85, 50, 95, 45, 80, 70].map(
+ (h, i) => (
+
+ ),
+ )}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ On Discussed
+
+
+ 07
+
+
+
+
+
+
+
+
+ );
+};
+
+const containerVariants: Variants = {
+ initial: {
+ transition: {
+ staggerChildren: 0.04,
+ staggerDirection: -1,
+ },
+ },
+ hover: {
+ transition: {
+ staggerChildren: 0.06,
+ },
+ },
+};
+
+const barVariants2: Variants = {
+ initial: {
+ scaleY: 0.6,
+ },
+ hover: {
+ scaleY: 1,
+ },
+};
+const trophyVariants: Variants = {
+ hover: {
+ rotate: [0, -12, 12, -10, 10, -6, 6, 0],
+ scale: 1.15,
+ transition: {
+ scale:{
+ duration:0.2,
+ ease: 'easeInOut'
+ },
+ duration: 0.7,
+ ease: 'easeInOut',
+ },
+ },
+};
+
+const InvestmentGrowthCard = () => {
+ const data = [140, 230, 205, 290, 245, 220, 170];
+ const months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul'];
+
+ return (
+
+
+
+
+ Investment Growth
+
+
+
+ Explore diverse portfolios and watch your wealth flourish with
+ expert guidance.
+
+
+
+
+
+
+
+ Leaderboard
+
+
+
+ Last 28 days
+
+
+
+
+ {data.map((height, i) => (
+
+
+
+
+ {months[i]}
+
+
+ ))}
+
+
+
+
+ );
+};
+
+const BentoGrid13 = () => {
+ const [value, setValue] = useState(0);
+
+ const itemVariants = {
+ hidden: { },
+ visible: { },
+
+ };
+
+ const TrophyItemVariants = {
+ hidden: {},
+ visible: {},
+ hoveer: {}
+ };
+
+
+ return (
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Financial Planning
+
+
+ Set goals and receive strategies for a secure future.
+
+
+
+
+
+
+
+
+ {images.map((i) => (
+
+
+
+ ))}
+
+
+
+ Community Support
+
+
+ Visit and share money to your friends instantly!
+
+
+
+
+
+
+
+
+
+
+
+
+ Expand & Save
+
+
+ Collect points and spends on growth.
+
+
+
+
+
+ setValue(250)}
+ className="col-span-1 flex flex-col items-center relative justify-center gap-1 rounded-3xl border border-white/5 bg-[#1a1a1a] p-8 text-center md:col-span-2 "
+ >
+
+
+
+
+ $
+
+ K
+
+
+
+
+ Secure Transaction
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Expert Advice
+
+
+ Access tailored financial recommendations!
+
+
+
+
+
+
+ );
+};
+
+export default BentoGrid13;
diff --git a/src/data/contents/blocks/bento-15/bento-15.mdx b/src/data/contents/blocks/bento-15/bento-15.mdx
new file mode 100644
index 00000000..00128fad
--- /dev/null
+++ b/src/data/contents/blocks/bento-15/bento-15.mdx
@@ -0,0 +1,24 @@
+---
+title: Bento 15
+slug: bento-15
+category: bento
+description: >-
+ A sleek startup-focused bento layout highlighting growth, global reach, and
+ investment opportunities. Featuring minimal dark aesthetics, subtle data
+ visualizations, and brand integrations, it communicates scale and credibility
+ while guiding users through building, funding, and expanding modern tech
+ ventures.
+image: 'https://assets.watermelon.sh/components/bento-15.webp'
+video: 'https://assets.watermelon.sh/components/bento-15.mp4'
+featured: false
+comingSoon: false
+dependencies:
+ - motion/react
+ - lucide-react
+ - react-icons
+ - clsx
+ - tailwind-merge
+install:
+ - 'npx shadcn@latest add https://registry.watermelon.sh/r/bento-15.json'
+componentNumber: 5
+---
diff --git a/src/data/contents/blocks/bento-15/demo.tsx b/src/data/contents/blocks/bento-15/demo.tsx
new file mode 100644
index 00000000..5e6f3244
--- /dev/null
+++ b/src/data/contents/blocks/bento-15/demo.tsx
@@ -0,0 +1,6 @@
+
+import BentoGrid15 from '.';
+
+export default function BentoGrid15Demo() {
+ return ;
+}
diff --git a/src/data/contents/blocks/bento-15/index.tsx b/src/data/contents/blocks/bento-15/index.tsx
new file mode 100644
index 00000000..dc1a0d25
--- /dev/null
+++ b/src/data/contents/blocks/bento-15/index.tsx
@@ -0,0 +1,606 @@
+'use client';
+import React, { useState } from 'react';
+import { motion } from 'framer-motion';
+import { FiMail } from 'react-icons/fi';
+import { Check, ChevronRight } from 'lucide-react';
+import {
+ Card,
+ CardTitle,
+ CardDescription,
+ CardContent,
+ CardFooter,
+} from '@/components/base-ui/card';
+
+const Logo = ({ width = 111, height = 35, ...props }) => {
+ return (
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ );
+};
+
+function Logo2(props: React.SVGProps) {
+ return (
+
+
+
+
+
+
+
+
+
+
+
+ );
+}
+const Logo3 = ({ width = 117, height = 28, ...props }) => {
+ return (
+
+
+
+
+
+
+
+
+
+
+
+
+ );
+};
+
+type LogoProps = React.SVGProps;
+
+export const MetaLogo = (props: LogoProps) => (
+
+
+
+
+
+);
+
+export const Logo100TB = (props: LogoProps) => (
+
+
+
+
+);
+
+export const AmazonLogo = (props: LogoProps) => (
+
+
+
+
+);
+
+export const BehanceLogo = (props: LogoProps) => (
+
+
+
+
+);
+
+const COMPANIES = [Logo, Logo2, Logo3];
+const LOGOS = [MetaLogo, AmazonLogo, BehanceLogo, Logo100TB];
+
+const dots = [
+ { t: '8%', l: '37%' },
+ { t: '25%', l: '22%' },
+ { t: '47%', l: '52%' },
+ { t: '52%', l: '33%' },
+ { t: '22%', l: '65%' },
+ { t: '60%', l: '77%' },
+];
+
+ const enterDelays = dots.map(() => Math.random() * 0.8);
+ const exitDelays = dots.map(() => Math.random() * 0.8);
+
+function Card4() {
+ const [hovered, setHovered] = useState(false);
+
+ return (
+ setHovered(true)}
+ onHoverEnd={() => setHovered(false)}
+ className="col-span-12 md:col-span-4"
+ >
+
+
+
+
+
+ {dots.map((pos, i) => (
+
+ ))}
+
+
+
+
+
+ Build a global portfolio
+
+
+ Grew 30,000+ strong global design community!!
+
+
+
+
+ );
+}
+export function Card3() {
+ return (
+
+
+
+
+
+
+
+ {[...Array(10)].map((_, i) => (
+
+ {i}
+
+ ))}
+
+ {[...Array(12)].map((_, i) => (
+
+ {i + 1}
+
+ ))}
+
+
+
+
+
+
+
+ Bootstrapped and grow
+
+
+ Turn your side hustle into a company
+
+
+
+
+ );
+}
+const swipeVariants = {
+ initial: { x: 5 },
+ hover: { x: 225 },
+};
+
+const checkVariants = {
+ initial: { scale: 0, opacity: 0 },
+ hover: { scale: 1, opacity: 1 },
+};
+function Card5() {
+ return (
+
+
+
+
+
+
+
+
+
+
New Account
+
user@mail.com
+
+
+
+
+
+
+
+
+
+
+
+
+
+ AC
+
+
+
Alex costa
+
user@mail.com
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Swipe to fund
+
+
+
+
+
+
+ Invest in tech startups
+
+
+ Place my own bets on startups
+
+
+
+
+ );
+}
+const BentoGrid15 = () => {
+ const containerVariants = {
+ hidden: { opacity: 0 },
+ visible: {
+ opacity: 1,
+ transition: { staggerChildren: 0.1 },
+ },
+ };
+
+ const itemVariants = {
+ hidden: { y: 20, opacity: 0 },
+ visible: { y: 0, opacity: 1 },
+ };
+
+ return (
+
+
+
+
+
+ {COMPANIES.map((Logo, i) => (
+
+ ))}
+
+
+
+ 50+ high growth copanies
+
+
+ Gain control of your spending with intuitive tracking and
+ categorization.
+
+
+
+
+
+
+
+
+ {LOGOS.map((Logo, i) => (
+
+ ))}
+
+
+
+ Taught designer from big tech
+
+
+ Gain control of your spending with intuitive tracking and
+ categorization.
+
+
+
+
+
+
+
+
+
+
+
+
+ );
+};
+
+export default BentoGrid15;
diff --git a/src/data/contents/blocks/bento-17/bento-17.mdx b/src/data/contents/blocks/bento-17/bento-17.mdx
new file mode 100644
index 00000000..dbb919c0
--- /dev/null
+++ b/src/data/contents/blocks/bento-17/bento-17.mdx
@@ -0,0 +1,24 @@
+---
+title: Bento 17
+slug: bento-17
+category: bento
+description: >-
+ A modern SaaS-focused bento layout featuring rich data insights, seamless
+ integrations, and user engagement tools. With soft purple gradients,
+ interactive charts, and modular sections for support and communication, it
+ delivers a polished and intuitive interface for managing growth, workflows,
+ and customer interactions.
+image: 'https://assets.watermelon.sh/components/bento-17.webp'
+video: 'https://assets.watermelon.sh/components/bento-17.mp4'
+featured: false
+comingSoon: false
+dependencies:
+ - motion/react
+ - lucide-react
+ - react-icons
+ - clsx
+ - tailwind-merge
+install:
+ - 'npx shadcn@latest add https://registry.watermelon.sh/r/bento-17.json'
+componentNumber: 5
+---
diff --git a/src/data/contents/blocks/bento-17/demo.tsx b/src/data/contents/blocks/bento-17/demo.tsx
new file mode 100644
index 00000000..294571ac
--- /dev/null
+++ b/src/data/contents/blocks/bento-17/demo.tsx
@@ -0,0 +1,6 @@
+
+import BentoGrid17 from '.';
+
+export default function BentoGrid17Demo() {
+ return ;
+}
diff --git a/src/data/contents/blocks/bento-17/index.tsx b/src/data/contents/blocks/bento-17/index.tsx
new file mode 100644
index 00000000..b7371ec6
--- /dev/null
+++ b/src/data/contents/blocks/bento-17/index.tsx
@@ -0,0 +1,659 @@
+'use client';
+import React, { useState } from 'react';
+import { motion, useAnimation, type Variants } from 'framer-motion';
+import {
+ Card,
+ CardContent,
+ CardDescription,
+ CardFooter,
+ CardHeader,
+ CardTitle,
+} from '@/components/base-ui/card';
+import { IoIosSearch } from 'react-icons/io';
+import { TbBellRingingFilled } from 'react-icons/tb';
+import { IoChatbubbleEllipsesSharp } from 'react-icons/io5';
+
+import type { SVGProps } from 'react';
+
+const GlowEllipse = (props?: React.SVGProps) => {
+ return (
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ );
+};
+
+const data = [190, 130, 145, 190, 145, 120, 170];
+
+function ChartsCard() {
+ const [hovered, setHovered] = useState(false);
+
+ const containerVariants: Variants = {
+ initial: { transition: { staggerChildren: 0.08, staggerDirection: -1 } },
+ hover: {
+ transition: {
+ staggerChildren: 0.08,
+ },
+ },
+ };
+
+ const barVariants: Variants = {
+ initial: { scaleY: 0.75 },
+ hover: {
+ scaleY: 1,
+ transition: {
+ duration: 0.45,
+ ease: 'easeOut',
+ },
+ },
+ };
+
+ return (
+ setHovered(true)}
+ onHoverEnd={() => setHovered(false)}
+ onTapStart={() => setHovered(true)}
+ onTap={() => setTimeout(() => setHovered(false), 1000)}
+ initial="initial"
+ animate={hovered ? 'hover' : 'initial'}
+ className="col-span-1 row-span-1 md:col-span-4 md:row-span-2"
+ >
+
+
+
+
+
+
+ Monthly Growth Report
+
+
+
+
+
+ Access powerful data to help grow your business
+
+
+
+
+
+
+
+
+
+ Monthly Income
+
+
$ 68,700
+
+
+
+ Last 28 days
+
+
+
+
+ {data.map((height, i) => (
+
+
+
+ ))}
+
+
+
+
+ );
+}
+
+function NewsletterCard({ itemVariants }: { itemVariants: Variants }) {
+ const controls = useAnimation();
+ const handles = useAnimation();
+
+ const startSelection = async () => {
+ await controls.start({
+ opacity: 1,
+ width: '100%',
+ height: '100%',
+ transition: { duration: 0.35, ease: 'easeOut' },
+ });
+
+ handles.start({
+ opacity: 1,
+ scale: 1,
+ transition: { duration: 0.15 },
+ });
+ };
+
+ const resetSelection = () => {
+ handles.start({ opacity: 0, scale: 0 });
+
+ controls.start({
+ opacity: 0,
+ width: 0,
+ height: 0,
+ transition: { duration: 0.2 },
+ });
+ };
+
+ return (
+ setTimeout(resetSelection, 1500)}
+ className="col-span-1 row-span-1 md:col-span-4 md:row-span-2"
+ >
+
+
+
+
+
+
+ Customize Newsletter
+
+
+
+
+
+ We made it simple to create weekly newsletters
+
+
+
+
+
+
+
+
+
+
+
+ To: All Contact
+
+
+
+ Subject: Exciting updates are on the way!!
+
+
+
+
+
+
+ Monthly updates
+
+
+
+
+ {[
+ '-top-[3px] -left-[3px]',
+ '-top-[3px] -right-[3px]',
+ '-bottom-[3px] -left-[3px]',
+ '-bottom-[3px] -right-[3px]',
+ ].map((pos, idx) => (
+
+ ))}
+
+
+
+
+ Font: Plus Jakarta Sans
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ );
+}
+
+function IntegrationCard({ itemVariants }: { itemVariants: Variants }) {
+ const icons = [Notion, Slack, Figma, Paper];
+ const controls = useAnimation();
+
+ const iconVariants: Variants = {
+ hidden: {
+ opacity: 1,
+ filter: 'grayscale(100%) blur(1px) ',
+ },
+ visible: (i: number) => ({
+ opacity: 1,
+ filter: 'grayscale(0%) blur(0px) ',
+ transition: {
+ delay: i * 0.2,
+ duration: 0.45,
+ ease: 'easeOut',
+ },
+ }),
+ };
+
+ const handleHover = async () => controls.start('visible');
+ const handleHoverEnd = async () => controls.start('hidden');
+
+ return (
+ setTimeout(handleHoverEnd, 1500)}
+ className="col-span-1 row-span-1 md:col-span-4"
+ >
+
+
+
+
+
+
+ Awesome Integration
+
+
+
+
+
+ Work with your favorite tools
+
+
+
+
+
+
+ {icons.map((Icon, i) => (
+
+
+
+
+
+ ))}
+
+
+
+ {Array(6)
+ .fill(null)
+ .map((_, i) => (
+
+ ))}
+
+
+
+ );
+}
+
+const BentoGrid17 = () => {
+ const containerVariants: Variants = {
+ hidden: { opacity: 0 },
+ visible: {
+ opacity: 1,
+ transition: { staggerChildren: 0.1 },
+ },
+ };
+
+ const itemVariants: Variants = {
+ hidden: { y: 20, opacity: 0 },
+ visible: {
+ y: 0,
+ opacity: 1,
+ transition: { duration: 0.5, ease: 'easeOut' },
+ },
+ };
+
+ return (
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Community Support
+
+
+
+
+ 24/7 fast team support
+
+
+
+
+
+
+
+
+ Hey! there i am here to help. 👋
+
+
+
+
+
+
+
+
+
+ );
+};
+type IconProps = {
+ className?: string;
+};
+
+const PatternIcon = ({ className }: IconProps) => {
+ return (
+
+
+
+
+
+
+
+
+
+
+ );
+};
+
+const PatternIcon2 = ({ className }: IconProps) => {
+ return (
+
+
+
+
+
+
+
+
+
+
+ );
+};
+
+
+const PatternIcon3 = ({ className }: IconProps) => {
+ return (
+
+
+
+
+
+
+
+
+
+
+ );
+};
+
+const PatternIcon4 = ({ className }: IconProps) => {
+ return (
+
+
+
+
+
+
+
+
+
+
+ );
+};
+
+const Notion = (props: SVGProps) => (
+
+
+
+
+);
+
+const Figma = (props: SVGProps) => (
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+);
+
+const Slack = (props: SVGProps) => (
+
+
+
+
+
+
+
+
+);
+
+const Paper = (props: SVGProps) => (
+
+
+
+);
+
+export default BentoGrid17;
diff --git a/src/data/contents/blocks/bento-8/bento-8.mdx b/src/data/contents/blocks/bento-8/bento-8.mdx
new file mode 100644
index 00000000..9d585c02
--- /dev/null
+++ b/src/data/contents/blocks/bento-8/bento-8.mdx
@@ -0,0 +1,23 @@
+---
+title: Bento 8
+slug: bento-8
+category: bento
+description: A premium dark-themed bento layout showcasing intelligent personalization,
+ privacy-first design, and content discovery. Featuring glowing gradients,
+ soft ambient lighting, and interactive elements like tag filtering and user
+ identity selection, it blends elegant visuals with purposeful UX to create a
+ refined, futuristic dashboard experience.
+image: 'https://assets.watermelon.sh/components/bento-8.webp'
+video: 'https://assets.watermelon.sh/components/bento-8.mp4'
+featured: false
+comingSoon: false
+dependencies:
+ - motion/react
+ - lucide-react
+ - react-icons
+ - clsx
+ - tailwind-merge
+install:
+ - 'npx shadcn@latest add https://registry.watermelon.sh/r/bento-8.json'
+componentNumber: 5
+---
diff --git a/src/data/contents/blocks/bento-8/demo.tsx b/src/data/contents/blocks/bento-8/demo.tsx
new file mode 100644
index 00000000..df0476af
--- /dev/null
+++ b/src/data/contents/blocks/bento-8/demo.tsx
@@ -0,0 +1,6 @@
+
+import BentoGrid8 from '.';
+
+export default function BentoGrid8Demo() {
+ return ;
+}
diff --git a/src/data/contents/blocks/bento-8/index.tsx b/src/data/contents/blocks/bento-8/index.tsx
new file mode 100644
index 00000000..36fcfb80
--- /dev/null
+++ b/src/data/contents/blocks/bento-8/index.tsx
@@ -0,0 +1,550 @@
+'use client';
+import React from 'react';
+import { motion } from 'framer-motion';
+import { clsx, type ClassValue } from 'clsx';
+import { twMerge } from 'tailwind-merge';
+import { Card, CardContent, CardFooter } from '@/components/base-ui/card';
+
+function cn(...inputs: ClassValue[]) {
+ return twMerge(clsx(inputs));
+}
+
+const BentoCard = ({ children, className, title, description }: { children?: React.ReactNode; className?: string; title: string; description: string }) => (
+
+
+ {children}
+
+
+
+
+ {title}
+
+
+
+ {description}
+
+
+
+);
+
+const GlowingOrb = ({
+ color,
+ className,
+}: {
+ color: string;
+ className?: string;
+}) => (
+
+);
+
+const KeysList = () => {
+ return (
+
+ {Array(18)
+ .fill(0)
+ .map((_, i) => (
+
+ ))}
+
+ );
+};
+
+export default function BentoGrid8() {
+ return (
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ );
+}
+
+function ArrowIcon(props: React.SVGProps) {
+ return (
+
+
+
+ );
+}
+
+const GetInfoButton = () => {
+ return (
+
+ );
+};
+
+const BentoSource = () => {
+ const [isHovering, setIsHovering] = React.useState(false);
+
+ return (
+ setIsHovering(true)}
+ onMouseLeave={() => setIsHovering(false)}
+ >
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Kyle
+
+
+
+
+
+
+
+
+
+ Become the Source
+
+
+
+ AI-distilled insights, ready to share. Elevate your voice in any
+ conversation.
+
+
+
+ );
+};
+
+const interests1 = [
+ 'Developer',
+ 'Founder',
+ 'Engineer',
+ 'Writer',
+ 'Marketer',
+ 'Product',
+ 'Creator',
+ 'Researcher',
+ 'Artist',
+ 'Builder',
+ 'Strategist',
+];
+
+const interests2 = [
+ 'Developer',
+ 'Founder',
+ 'Engineer',
+ 'Designer',
+ 'Writer',
+ 'Marketer',
+ 'Product',
+ 'Creator',
+ 'Researcher',
+ 'Artist',
+ 'Builder',
+ 'Strategist',
+];
+
+const interests3 = [
+ 'Developer',
+ 'Founder',
+ 'Engineer',
+ 'Writer',
+ 'Marketer',
+ 'Product',
+ 'Creator',
+ 'Researcher',
+ 'Artist',
+ 'Builder',
+ 'Strategist',
+];
+
+function InterestsMarquee() {
+ return (
+
+ );
+}
+
+const Row = ({
+ reverse = false,
+ items,
+}: {
+ reverse?: boolean;
+ items: string[];
+}) => {
+ const loopItems = [...items, ...items];
+
+ return (
+
+
+ {loopItems.map((item, i) => (
+
+
+ {item}
+
+ ))}
+
+
+ );
+};
+
+const AuroraSvgBackground = () => {
+ return (
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ );
+};
diff --git a/src/data/contents/blocks/bento-9/bento-9.mdx b/src/data/contents/blocks/bento-9/bento-9.mdx
new file mode 100644
index 00000000..5546ffe6
--- /dev/null
+++ b/src/data/contents/blocks/bento-9/bento-9.mdx
@@ -0,0 +1,24 @@
+---
+title: Bento 9
+slug: bento-9
+category: bento
+description: A robust monitoring-focused bento layout designed for incident tracking and
+ system reliability. Featuring real-time alerts, post-mortem timelines, and
+ proactive outage prevention, it combines structured data visualization with
+ a clean dark interface to deliver clarity, control, and fast diagnostics for
+ modern infrastructure workflows.
+image: 'https://assets.watermelon.sh/components/bento-9.webp'
+video: 'https://assets.watermelon.sh/components/bento-9.mp4'
+featured: false
+comingSoon: false
+dependencies:
+ - motion/react
+ - lucide-react
+ - react-icons
+ - clsx
+ - tailwind-merge
+install:
+ - 'npx shadcn@latest add https://registry.watermelon.sh/r/bento-9.json'
+componentNumber: 5
+---
+
diff --git a/src/data/contents/blocks/bento-9/demo.tsx b/src/data/contents/blocks/bento-9/demo.tsx
new file mode 100644
index 00000000..ed9592e0
--- /dev/null
+++ b/src/data/contents/blocks/bento-9/demo.tsx
@@ -0,0 +1,6 @@
+
+import BentoGrid9 from '.';
+
+export default function BentoGrid9Demo() {
+ return ;
+}
diff --git a/src/data/contents/blocks/bento-9/index.tsx b/src/data/contents/blocks/bento-9/index.tsx
new file mode 100644
index 00000000..886876cf
--- /dev/null
+++ b/src/data/contents/blocks/bento-9/index.tsx
@@ -0,0 +1,794 @@
+'use client';
+import { useEffect, useState, type ReactElement, type SVGProps } from 'react';
+import {
+ animate,
+ AnimatePresence,
+ motion,
+ stagger,
+ useAnimate,
+ useMotionValue,
+} from 'framer-motion';
+import { Card, CardContent, CardFooter } from '@/components/base-ui/card';
+import { FaLongArrowAltDown } from 'react-icons/fa';
+import { FaCircleChevronDown } from 'react-icons/fa6';
+import { MdOutlineBarChart } from 'react-icons/md';
+import { IoMdGlobe } from 'react-icons/io';
+const DoubleCheck = ({ className }: { className?: string }) => {
+ return (
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ );
+};
+const colors = {
+ bg: 'bg-zinc-950',
+ cardBg: 'bg-zinc-900',
+ border: 'border-zinc-800',
+ textMain: 'text-zinc-100',
+ textSub: 'text-zinc-400',
+ textMuted: 'text-zinc-500',
+ statusUp: 'bg-sky-500',
+ statusDown: 'bg-rose-500',
+ accent: 'text-sky-400',
+ highlightBg: 'bg-zinc-800',
+ faintBg: 'bg-zinc-800/50',
+ outline: 'border-zinc-700',
+ faintOutline: 'border-zinc-800',
+};
+
+const containerVariants = {
+ hidden: { opacity: 0 },
+ visible: {
+ opacity: 1,
+ transition: {
+ staggerChildren: 0.1,
+ delayChildren: 0.2,
+ },
+ },
+};
+
+type Incident = {
+ id: string;
+ message: string;
+ region: string;
+};
+
+type ChatIncidentProps = {
+ text: string;
+ incidents: Incident[];
+};
+
+export const ChatIncident = ({ text, incidents }: ChatIncidentProps) => {
+ const [typed, setTyped] = useState('');
+ const [scope, animate] = useAnimate();
+
+ useEffect(() => {
+ let isMounted = true;
+
+ const run = async () => {
+ while (isMounted) {
+ // reset
+ setTyped('');
+
+ for (let i = 0; i <= text.length; i++) {
+ await new Promise((r) => setTimeout(r, 40));
+ if (!isMounted) return;
+ setTyped(text.slice(0, i));
+ }
+
+ await new Promise((r) => setTimeout(r, 500));
+
+ await animate(
+ '[data-item]',
+ { opacity: [0, 1], y: [-20, 0], filter: ['blur(4px)', 'blur(0px)'] },
+ {
+ duration: 0.3,
+ delay: stagger(0.15),
+ },
+ );
+
+ await new Promise((r) => setTimeout(r, 5000));
+
+ await animate(
+ '[data-item]',
+ { opacity: [1, 0], filter: ['blur(0px)', 'blur(4px)'] },
+ {
+ duration: 0.3,
+ delay: stagger(0.15, { from: 'last' }),
+ },
+ );
+
+ setTyped('');
+
+ await new Promise((r) => setTimeout(r, 500));
+ }
+ };
+
+ run();
+
+ return () => {
+ isMounted = false;
+ };
+ }, [text, animate]);
+
+ return (
+
+
+
+
+
+
+
+ {typed}
+
+ {typed.length < text.length && (
+
+ |
+
+ )}
+
+
+
+
+ {incidents.map((item) => (
+
+
+
+
+
+
+
{item.message}
+
+
+
+ {item.region}
+
+
+
+ ))}
+
+
+ );
+};
+const Card3_BrowserMock = () => (
+
+
+
+
+
+
+ allpine.com
+
+
+
+
+
+
+
+ ←
+ →
+ ↻
+
+ www.corestack.com
+
+
+
+
+
connection is secure
+
+ Your information is private when
+ it is seen on this site
+
+
+
+
+);
+
+const data = [
+ { name: 'tesla.com', type: 'Peer certificate cannot be authenticated' },
+ { name: 'around.co', type: 'Peer certificate cannot be authenticated' },
+];
+
+export const Card4_IncidentsMock = () => {
+ const [visible, setVisible] = useState(true);
+
+ useEffect(() => {
+ const interval = setInterval(() => {
+ setVisible(false);
+ setTimeout(() => setVisible(true), 1200);
+ }, 5000);
+
+ return () => clearInterval(interval);
+ }, []);
+
+ return (
+
+
+
+
+
+
+ 10 similar incidents
+
+
+ 15 may 2025 at 06:04am
+
+
+
+
+
+
+
+ {visible &&
+ data.map((item, i) => (
+
+
+
+
+
+ {item.name}
+
+
+ {item.type}
+
+
+
+ ))}
+
+
+
+
+
+ );
+};
+
+const Notion = (props: SVGProps) => (
+
+
+
+
+);
+
+const Figma = (props: SVGProps) => (
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+);
+
+const Slack = (props: SVGProps) => (
+
+
+
+
+
+
+
+
+);
+
+const Paper = (props: SVGProps) => (
+
+
+
+);
+
+const React = (props: SVGProps) => (
+
+
+
+
+
+
+
+
+
+
+);
+
+const Vercel = (props: SVGProps) => (
+
+
+
+);
+
+const GitHub = (props: SVGProps) => (
+
+
+
+);
+
+const Cursor = (props: SVGProps) => (
+
+
+
+);
+
+type IconType = (props: SVGProps) => ReactElement;
+
+const stacks1: IconType[] = [Figma, Vercel, Slack, Paper];
+const stacks2: IconType[] = [GitHub, React, Notion, Cursor];
+export const Card5_StackMock = () => {
+ return (
+
+ );
+};
+
+const Row = ({
+ items,
+ reverse = false,
+}: {
+ items: IconType[];
+ reverse?: boolean;
+}) => {
+ const loop = [...items, ...items];
+
+ return (
+
+
+ {loop.map((Icon, i) => (
+
+
+
+ ))}
+
+
+ );
+};
+
+const backups = [
+ { id: '1', label: 'managed database backup' },
+ { id: '2', label: 'new database backup' },
+ { id: '3', label: 'core database backup' },
+];
+
+type Item = {
+ id: string;
+ label: string;
+};
+
+type BackupListProps = {
+ items: Item[];
+};
+
+export const BackupList = ({ items }: BackupListProps) => {
+ const ITEM_HEIGHT = 60;
+ const VISIBLE = 3;
+
+ const loop = [...items, ...items, ...items];
+
+ const [index, setIndex] = useState(0);
+
+ const y = useMotionValue(0);
+
+ useEffect(() => {
+ const interval = setInterval(() => {
+ setIndex((prev) => prev + 1);
+ }, 3000);
+
+ return () => clearInterval(interval);
+ }, []);
+
+ useEffect(() => {
+ const normalizedIndex = index % items.length;
+
+ animate(y, -normalizedIndex * ITEM_HEIGHT, {
+ type: 'spring',
+ bounce: 0,
+ duration: 1,
+ });
+ }, [index, items.length, y]);
+
+ const centerOffset = Math.floor(VISIBLE / 2);
+ const centerIndex = (index + centerOffset) % items.length;
+
+ return (
+
+
+
+
+ {loop.map((item, i) => {
+ const realIndex = i % items.length;
+ const active = realIndex === centerIndex;
+
+ return (
+
+
+
+
+
+
+ {item.label}
+
+
+ );
+ })}
+
+
+ );
+};
+
+const tabs = ['Response', 'Screenshot', 'Monitor'];
+
+function IncidentsCard1() {
+ const [active, setActive] = useState(0);
+
+ useEffect(() => {
+ const interval = setInterval(() => {
+ setActive((prev) => (prev + 1) % tabs.length);
+ }, 3000);
+
+ return () => clearInterval(interval);
+ }, []);
+
+ return (
+
+
+
+
Incidents
+
+
+
+
+
+
+
+ allpine.com/status
+
+
+ Up. Checked every 25 sec
+
+
+
+
+ {/* tabs */}
+
+
+ {tabs.map((tab, i) => (
+
+ {active === i && (
+
+ )}
+
+ {tab}
+
+ ))}
+
+
+
+ );
+}
+
+const BentoGrid9 = () => {
+ return (
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ );
+};
+
+function BentoCard({
+ title,
+ description,
+ children,
+}: {
+ title: string;
+ description: string;
+ children: React.ReactNode;
+}) {
+ return (
+
+
+ {children}
+
+
+ {title}
+ {description}
+
+
+ );
+}
+
+export default BentoGrid9;