shadimage
roiui
itemcard-image-sectionsource: ok · hit

Card Image Section

A section with 4 image cards in a masonry layout.

npx shadcn add "https://roiui.com/r/card-image-section.json"
free

Where it goes

gallery

Tags auto-generated by rules on 9/24/2026 — empty means no evidence, not lack of support.

Dependencies

Bundle weight · light

Registry dependencies

https://roiui.com/r/button.jsonhttps://roiui.com/r/card.json

Files4 · source cached 10/14/2026, 3:23:08 PM

registry/brook/blocks/card-image-section/page.tsx
"use client";
import { CardImageSection } from "./card-image-section";
import data from "./data.json";

export default function Page() {
  return <CardImageSection data={data} />;
}
registry/brook/blocks/card-image-section/components/card-image-section.tsx
import { ArrowPointer, Button } from "../../ui/button/button";
import { Card, CardContent, CardDescription, CardFooter, CardImage, CardTitle } from "../../ui/card/card";
import styles from "./card-image-section.module.css";

type CardData = {
  id: number;
  imageSrc: string;
  alt: string;
  title: string;
  description: string;
  href?: string;
};

type CardImageSectionProps = {
  data: {
    caption: string;
    heading: string;
    description: string;
    cards: CardData[];
  };
};

export function CardImageSection({ data }: CardImageSectionProps) {
  return (
    <section className={styles.section}>
      <header className={styles.header}>
        <span className={styles.caption}>{data.caption}</span>
        <h2 className={styles.heading}>{data.heading}</h2>
        <p className={styles.description}>{data.description}</p>
      </header>

      <div className={styles.grid}>
        {data.cards.map((card) => (
          <Card className={styles.card} key={card.id} variant="lift">
            <CardImage alt={card.alt} className={styles.cardImage} src={card.imageSrc} />

            <CardContent>
              <CardTitle className={styles.cardTitle}>{card.title}</CardTitle>
              <CardDescription>{card.description}</CardDescription>
            </CardContent>

            <CardFooter>
              <Button className={styles.linkButton} render={<a href={card.href ?? "#"} />} size="sm" variant="link">
                Learn More
                <ArrowPointer />
              </Button>
            </CardFooter>
          </Card>
        ))}
      </div>
    </section>
  );
}
registry/brook/blocks/card-image-section/components/card-image-section.module.css
.section {
  width: 100%;
  max-width: 900px;
  margin: 0 auto;
  padding: 48px 24px;
}

.header {
  text-align: left;
  margin-bottom: 48px;
}

.caption {
  display: block;
  font-size: var(--font-size-sm);
  font-weight: 500;
  color: var(--accent);
  text-transform: uppercase;
  letter-spacing: 0.05em;
  margin-bottom: 12px;
}

.heading {
  font-size: clamp(1.75rem, 4vw, 2.5rem);
  font-weight: 600;
  color: var(--foreground);
  margin: 0 0 16px 0;
  letter-spacing: -0.02em;
  line-height: 1.2;
}

.description {
  font-size: var(--font-size-base);
  color: var(--muted-foreground);
  margin: 0;
  max-width: 600px;
  line-height: 1.6;
}

.grid {
  columns: 2;
  column-gap: 24px;
}

.card {
  break-inside: avoid;
  margin-bottom: 24px;
  border-radius: 20px;
  max-width: 100%;
  transform: translateZ(0);
}

.card:first-child {
  margin-top: 120px;
}

.cardImage {
  border-radius: 12px;
  width: auto;
}

.cardTitle {
  margin: 0;
}

.card [data-slot="card-content"] {
  gap: 0.75rem;
}

.linkButton {
  padding-left: 0;
}

@media (max-width: 640px) {
  .section {
    padding: 32px 16px;
  }

  .header {
    margin-bottom: 32px;
  }

  .grid {
    columns: 1;
  }

  .card {
    margin-bottom: 16px;
    border-radius: 16px;
  }

  .card:first-child {
    margin-top: 0;
  }

  .cardImage {
    border-radius: 8px;
  }

  .cardTitle {
    font-size: 1.125rem;
    line-height: 1.3;
  }
}
registry/brook/blocks-shared-files/card-image-section/data.json
{
  "caption": "What We Offer",
  "heading": "Four Pillars of Excellence",
  "description": "Discover the foundational elements that drive our approach to creating exceptional digital experiences.",
  "cards": [
    {
      "id": 1,
      "imageSrc": "/p-01.svg",
      "alt": "Feature 1 illustration",
      "title": "Feature 1",
      "description": "Add a description here to explain what this feature offers and why it matters to your users."
    },
    {
      "id": 2,
      "imageSrc": "/p-02.svg",
      "alt": "Feature 2 illustration",
      "title": "Feature 2",
      "description": "Add a description here to explain what this feature offers and why it matters to your users."
    },
    {
      "id": 3,
      "imageSrc": "/p-03.svg",
      "alt": "Feature 3 illustration",
      "title": "Feature 3",
      "description": "Add a description here to explain what this feature offers and why it matters to your users."
    },
    {
      "id": 4,
      "imageSrc": "/p-04.svg",
      "alt": "Feature 4 illustration",
      "title": "Feature 4",
      "description": "Add a description here to explain what this feature offers and why it matters to your users."
    }
  ]
}

More from roiui

Browse all components in this library →