# Bento Grid 03 - Automation Platform

> An automation-focused bento layout pairing a workflow canvas visual with feature highlights covering visual workflow building, AI intelligence, real-time execution, and tool integrations.

A shadcn/ui block from the [@shadcn-space](https://shadcnspace.com) registry, listed on [shadcn.exchange](https://shadcn.exchange/r/shadcn-space/bento-grid-03).

- Page, with a live preview: https://shadcn.exchange/r/shadcn-space/bento-grid-03
- Screenshot: https://abzjhwgwpdpz7ua5.public.blob.vercel-storage.com/shots/shadcn-space/bento-grid-03-light-59b34a5a95df6f0f.png
- Registry item: https://shadcnspace.com/r/bento-grid-03.json
- Listed: 2026-10-13, source last changed 2026-10-13

## Install

```bash
npx shadcn@latest add https://shadcnspace.com/r/bento-grid-03.json
```

Run it in a project that has shadcn/ui set up. It adds the files below and installs what they depend on.

## Dependencies

- npm packages: `lucide-react`
- Registry items: `badge`

## Files

### `src/components/shadcn-space/blocks/bento-grid-03/page.tsx`

```tsx
import BentoGrid03 from "@/components/shadcn-space/blocks/bento-grid-03";

const Page = () => {
  return <BentoGrid03 />;
};

export default Page;
```

### `src/components/shadcn-space/blocks/bento-grid-03/index.tsx`

```tsx
import { BentoGridHeader } from "@/components/shadcn-space/blocks/bento-grid-03/bento-grid-header";
import { FeatureGrid } from "@/components/shadcn-space/blocks/bento-grid-03/feature-grid";

const BentoGrid03 = () => {
  return (
    <section className="relative py-10 md:py-20 w-full overflow-hidden">
      {/* Background Vertical Lines extending full height of the section */}
      <div className="absolute inset-0 pointer-events-none" aria-hidden="true">
        <div className="h-full max-w-7xl mx-auto px-4 lg:px-8 xl:px-16">
          <div className="h-full w-full border-x border-border" />
        </div>
      </div>

      {/* Header section with screen-wide bottom border */}
      <div className="w-full border-b border-border">
        <div className="max-w-7xl mx-auto px-4 lg:px-8 xl:px-16">
          <BentoGridHeader />
        </div>
      </div>

      {/* Feature grid section with screen-wide bottom border */}
      <div className="w-full border-b border-border">
        <div className="max-w-7xl mx-auto px-4 lg:px-8 xl:px-16">
          <FeatureGrid />
        </div>
      </div>
    </section>
  );
};

export default BentoGrid03;
```

### `src/components/shadcn-space/blocks/bento-grid-03/bento-grid-header.tsx`

```tsx
import { Badge } from "@/components/ui/badge";

export function BentoGridHeader() {
  return (
    <div className="flex flex-col items-center gap-3 px-6 py-12 text-center">
      <Badge variant="outline" className="h-7 px-3 py-1 text-sm font-normal">
        Overview
      </Badge>
      <h2 className="text-4xl md:text-5xl font-medium text-foreground">
        One Automation Platform
      </h2>
      <p className="max-w-134.5 text-base text-muted-foreground">
        Our team is committed to redefining digital experiences through
        innovative web solutions while fostering a diverse and collaborative
        environment.
      </p>
    </div>
  );
}
```

### `src/components/shadcn-space/blocks/bento-grid-03/feature-grid.tsx`

```tsx
import { Clock, Link2, Rocket, Share2 } from "lucide-react";
import { WorkflowTagCloud } from "@/components/shadcn-space/blocks/bento-grid-03/workflow-tag-cloud";

const leftFeatures = [
  {
    icon: Share2,
    title: "Visual workflow engine",
    description:
      "Build automation sequences on a drag-and-drop canvas. Connect triggers, conditions, and actions across your stack in minutes.",
  },
  {
    icon: Rocket,
    title: "AI workflow intelligence",
    description:
      "Harness AI to suggest workflow improvements, auto-complete missing steps, and predict failures before they occur.",
  },
];

const rightFeatures = [
  {
    icon: Clock,
    title: "Real-time execution",
    description:
      "Run thousands of simultaneous workflows with sub-second latency. Monitor live runs and debug instantly.",
  },
  {
    icon: Link2,
    title: "Connected tool ecosystem",
    description:
      "Integrate with 1,000+ apps out of the box from Slack and GitHub to Salesforce, Stripe, and more.",
  },
];

function FeatureItem({
  icon: Icon,
  title,
  description,
}: {
  icon: typeof Share2;
  title: string;
  description: string;
}) {
  return (
    <div className="flex flex-1 flex-col justify-between gap-10 p-8">
      <Icon className="size-6 text-foreground" />
      <div className="flex flex-col gap-1">
        <p className="text-lg font-medium text-foreground">{title}</p>
        <p className="text-sm text-muted-foreground">{description}</p>
      </div>
    </div>
  );
}

export function FeatureGrid() {
  return (
    <div className="grid grid-cols-1 lg:grid-cols-3">
      <div className="flex flex-col divide-y divide-border border-b border-border lg:border-r lg:border-b-0">
        {leftFeatures.map((feature) => (
          <FeatureItem key={feature.title} {...feature} />
        ))}
      </div>

      <div className="relative aspect-square sm:aspect-video lg:aspect-384/562 xl:aspect-384/452 overflow-hidden border-b border-border lg:border-r lg:border-b-0">
        <img
          src="https://images.shadcnspace.com/assets/bento-grid/bento-grid-03-bg.webp"
          alt="Automation workflow canvas connecting teams across the organization"
          className="size-full object-cover"
        />
        <WorkflowTagCloud />
      </div>

      <div className="flex flex-col divide-y divide-border">
        {rightFeatures.map((feature) => (
          <FeatureItem key={feature.title} {...feature} />
        ))}
      </div>
    </div>
  );
}
```

### `src/components/shadcn-space/blocks/bento-grid-03/workflow-tag-cloud.tsx`

```tsx
import {
  Building2,
  ClipboardList,
  Code,
  Layers,
  Megaphone,
  Package,
  Palette,
  Rocket,
  TrendingUp,
  User,
  Wrench,
  type LucideIcon,
} from "lucide-react";
import { Marquee } from "@/components/shadcn-space/animations/marquee";
import { Badge } from "@/components/ui/badge";

const rows: { icon: LucideIcon; label: string }[][] = [
  [
    { icon: Wrench, label: "Engineers" },
    { icon: TrendingUp, label: "Sales" },
    { icon: Megaphone, label: "Marketing" },
    { icon: User, label: "HR" },
  ],
  [
    { icon: Building2, label: "Enterprises" },
    { icon: ClipboardList, label: "Project Managers" },
    { icon: Code, label: "Developers" },
    { icon: Palette, label: "Designers" },
  ],
  [
    { icon: Layers, label: "Product Team" },
    { icon: Rocket, label: "Founders" },
    { icon: Package, label: "Product Team" },
    { icon: Wrench, label: "Engineers" },
  ],
];

function TagPill({ icon: Icon, label }: { icon: LucideIcon; label: string }) {
  return (
    <Badge
      variant="outline"
      className="flex h-10 shrink-0 items-center gap-1.5 whitespace-nowrap rounded-full border-white/20 px-4 text-sm font-medium text-white backdrop-blur-sm"
    >
      <Icon className="size-4" />
      {label}
    </Badge>
  );
}

export function WorkflowTagCloud() {
  return (
    <div className="pointer-events-none absolute inset-0 flex flex-col justify-center gap-6 overflow-hidden py-6">
      {rows.map((row, index) => (
        <Marquee
          key={index}
          reverse={index % 2 === 1}
          className="[--duration:25s] [--gap:0.75rem] p-0"
        >
          {row.map((tag, tagIndex) => (
            <TagPill key={`${tag.label}-${tagIndex}`} {...tag} />
          ))}
        </Marquee>
      ))}
    </div>
  );
}
```

### `src/components/shadcn-space/animations/marquee.tsx`

```tsx
import { ComponentPropsWithoutRef } from "react";
 
import { cn } from "@/lib/utils";
 
interface MarqueeProps extends ComponentPropsWithoutRef<"div"> {
  className?: string;
  /**
   * Whether to reverse the animation direction
   * @default false
   */
  reverse?: boolean;
  /**
   * Whether to pause the animation on hover
   * @default false
   */
  pauseOnHover?: boolean;
  /**
   * Content to be displayed in the marquee
   */
  children: React.ReactNode;
  /**
   * Whether to animate vertically instead of horizontally
   * @default false
   */
  vertical?: boolean;
  /**
   * Number of times to repeat the content
   * @default 4
   */
  repeat?: number;
}
 
export function Marquee({
  className,
  reverse = false,
  pauseOnHover = false,
  children,
  vertical = false,
  repeat = 4,
  ...props
}: MarqueeProps) {
  return (
    <>
      <style>
        {`
          @keyframes marquee {
            from {
              transform: translateX(0);
            }
            to {
              transform: translateX(calc(-100% - var(--gap)));
            }
          }
 
          @keyframes marquee-vertical {
            from {
              transform: translateY(0);
            }
            to {
              transform: translateY(calc(-100% - var(--gap)));
            }
          }
 
          @keyframes scroll {
            to {
              transform: translate(calc(-50% - 0.5rem));
            }
          }
 
          .animate-marquee {
            animation: marquee var(--duration) linear infinite;
          }
 
          .animate-marquee-vertical {
            animation: marquee-vertical var(--duration) linear infinite;
          }
 
          .animate-reverse {
            animation-direction: reverse !important;
          }
 
          .pause-on-hover:hover .animate-marquee,
          .pause-on-hover:hover .animate-marquee-vertical {
            animation-play-state: paused !important;
          }
 
          .animate-scroll {
            animation: scroll var(--animation-duration, 40s) var(--animation-direction, forwards) linear infinite;
          }
        `}
      </style>
      <div
        {...props}
        className={cn(
          "group flex gap-(--gap) overflow-hidden p-2 [--duration:40s] [--gap:1rem]",
          {
            "flex-row": !vertical,
            "flex-col": vertical,
            "pause-on-hover": pauseOnHover,
          },
          className,
        )}
      >
        {Array(repeat)
          .fill(0)
          .map((_, i) => (
            <div
              key={i}
              className={cn("flex shrink-0 justify-around gap-(--gap)", {
                "animate-marquee flex-row": !vertical,
                "animate-marquee-vertical flex-col": vertical,
                "animate-reverse": reverse,
              })}
            >
              {children}
            </div>
          ))}
      </div>
    </>
  );
}
```
