# Content 11

> A billing overview split with a dashboard preview card and two feature highlights, built for the app-shell preset.

A shadcn/ui block from the [@flx](https://ui.flexnative.com) registry, listed on [shadcn.exchange](https://shadcn.exchange/r/flx/content-11).

- Page, with a live preview: https://shadcn.exchange/r/flx/content-11
- Screenshot: https://abzjhwgwpdpz7ua5.public.blob.vercel-storage.com/shots/flx/content-11-light-0a2e73a7b3338cc2.png
- Registry item: https://ui.flexnative.com/r/content-11.json
- Listed: 2026-10-13, source last changed 2026-10-13

## Install

```bash
npx shadcn@latest add https://ui.flexnative.com/r/content-11.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: `motion`, `react-wrap-balancer`
- Registry items: `@flx/dynamic-icon`, `card`, `badge`

## Files

### `registry/blocks/content/content-11/content-11.tsx`

```tsx
'use client'

import * as React from 'react'
import { icons } from 'lucide-react'
import { motion, useReducedMotion, type Variants } from 'motion/react'
import Balancer from 'react-wrap-balancer'

import { cn } from '@/lib/utils'

import { Icon } from '../../shared/dynamic-icon'
import { DashboardDemo } from './dashboard-demo'

export interface Content11Feature {
  icon: string
  title: string
  description: string
}

export interface Content11Props {
  title: string
  description?: string
  feature1: Content11Feature
  feature2: Content11Feature
  media?: React.ReactNode
  variant?: 'standard' | 'compact'
  animation?: 'none' | 'subtle'
}

const variantStyles = {
  standard: {
    section: 'py-16 sm:py-24',
    grid: 'gap-10 lg:gap-14',
    title: 'text-2xl sm:text-3xl',
    description: 'max-w-sm text-sm sm:text-base',
    header: 'gap-4',
    frame: 'h-72 sm:h-80 lg:h-[22rem]',
    peek: 'absolute top-6 left-6 w-[125%] max-w-none overflow-hidden rounded-2xl',
    features: 'gap-4 sm:gap-5',
    featureCard: 'gap-2 p-6',
    icon: 'size-5',
  },
  compact: {
    section: 'py-12 sm:py-16',
    grid: 'gap-8 lg:gap-10',
    title: 'text-xl sm:text-2xl',
    description: 'max-w-xs text-sm',
    header: 'gap-3',
    frame: 'h-60 sm:h-64 lg:h-72',
    peek: 'absolute top-4 left-4 w-[120%] max-w-none overflow-hidden rounded-xl',
    features: 'gap-3 sm:gap-4',
    featureCard: 'gap-2 p-5',
    icon: 'size-4',
  },
} as const

const container: Variants = {
  hidden: {},
  visible: { transition: { staggerChildren: 0.1, delayChildren: 0.05 } },
}

const item: Variants = {
  hidden: { opacity: 0, y: 12, filter: 'blur(6px)' },
  visible: {
    opacity: 1,
    y: 0,
    filter: 'blur(0px)',
    transition: { duration: 0.5, ease: [0.22, 1, 0.36, 1] },
  },
}

const mediaItem: Variants = {
  hidden: { opacity: 0, scale: 0.97, filter: 'blur(8px)' },
  visible: {
    opacity: 1,
    scale: 1,
    filter: 'blur(0px)',
    transition: { duration: 0.6, ease: [0.22, 1, 0.36, 1] },
  },
}

function FeatureCard({
  feature,
  animate,
  className,
  iconClassName,
}: Readonly<{
  feature: Content11Feature
  animate: boolean
  className: string
  iconClassName: string
}>) {
  const cardClassName = cn(
    'bg-secondary/70 dark:bg-secondary/30 flex h-full flex-col rounded-3xl',
    className,
  )

  const content = (
    <>
      {feature.icon && (
        <Icon
          name={feature.icon as keyof typeof icons}
          className={cn('text-foreground', iconClassName)}
        />
      )}
      <h3 className="text-foreground text-sm font-semibold">{feature.title}</h3>
      <p className="text-muted-foreground text-sm leading-relaxed">
        <Balancer>{feature.description}</Balancer>
      </p>
    </>
  )

  if (!animate) return <div className={cardClassName}>{content}</div>

  return (
    <motion.div variants={item} className={cardClassName}>
      {content}
    </motion.div>
  )
}

function Reveal({
  active,
  variants,
  className,
  children,
}: Readonly<{
  active: boolean
  variants?: Variants
  className?: string
  children: React.ReactNode
}>) {
  if (!active) return <div className={className}>{children}</div>

  return (
    <motion.div variants={variants ?? item} className={className}>
      {children}
    </motion.div>
  )
}

export function Content11({
  title,
  description,
  feature1,
  feature2,
  media = <DashboardDemo />,
  variant = 'standard',
  animation = 'none',
}: Readonly<Content11Props>) {
  const reduce = useReducedMotion()
  const animate = animation === 'subtle' && !reduce
  const vs = variantStyles[variant]

  const titleElement = title && (
    <h2
      className={cn(
        'text-foreground font-semibold tracking-tight text-balance',
        vs.title,
      )}
    >
      <Balancer>{title}</Balancer>
    </h2>
  )

  const descriptionElement = description && (
    <p className={cn('text-muted-foreground', vs.description)}>
      <Balancer>{description}</Balancer>
    </p>
  )

  const mediaElement = media && (
    <div
      className={cn(
        'bg-secondary/70 dark:bg-secondary/30 relative w-full overflow-hidden rounded-3xl',
        vs.frame,
      )}
    >
      <div className={cn(vs.peek, '*:w-full')}>{media}</div>
    </div>
  )

  const feature1Element = feature1 && (
    <FeatureCard
      feature={feature1}
      animate={animate}
      className={vs.featureCard}
      iconClassName={vs.icon}
    />
  )

  const feature2Element = feature2 && (
    <FeatureCard
      feature={feature2}
      animate={animate}
      className={vs.featureCard}
      iconClassName={vs.icon}
    />
  )

  const featuresElement = (
    <div className={cn('flex flex-col', vs.features)}>
      {feature1Element}
      {feature2Element}
    </div>
  )

  return (
    <section className="bg-background w-full">
      <motion.div
        className={cn(
          'mx-auto flex max-w-6xl flex-col px-6',
          vs.section,
          vs.grid,
        )}
        variants={animate ? container : undefined}
        initial={animate ? 'hidden' : false}
        whileInView={animate ? 'visible' : undefined}
        viewport={{ once: true, margin: '-80px' }}
      >
        <Reveal
          active={animate}
          className={cn('flex max-w-xl flex-col', vs.header)}
        >
          {titleElement}
          {descriptionElement}
        </Reveal>

        <div className="grid grid-cols-1 items-stretch gap-8 lg:grid-cols-[1.4fr_1fr] lg:gap-6">
          <Reveal active={animate} variants={mediaItem}>
            {mediaElement}
          </Reveal>
          {featuresElement}
        </div>
      </motion.div>
    </section>
  )
}
```

### `registry/blocks/content/content-11/dashboard-demo.tsx`

```tsx
import { ArrowDownRight, ArrowUpRight, Mail, MessageSquare, Phone } from 'lucide-react'

import { Card } from '@/components/ui/card'
import { cn } from '@/lib/utils'

const stats = [
  { label: 'Outstanding balance', value: '$1,842,900', delta: '-4.2%', trend: 'down' as const },
  { label: 'Active accounts', value: '312', delta: '+12', trend: 'up' as const },
  { label: 'Recovery rate', value: '74%', delta: '+3.1%', trend: 'up' as const },
  { label: 'Avg. resolution', value: '9.6 days', delta: '-1.8d', trend: 'down' as const },
]

const channels = [
  { icon: Mail, label: 'Email', sent: '1,240 sent', rate: '21.3%' },
  { icon: MessageSquare, label: 'SMS', sent: '860 sent', rate: '26.5%' },
  { icon: Phone, label: 'Phone', sent: '410 sent', rate: '31.2%' },
]

const timeline = [
  { title: 'Payment posted', meta: 'Meridian Co · $12,400' },
  { title: 'Reminder sequence completed', meta: 'Harlow Group' },
  { title: 'New accounts imported', meta: '380 records' },
  { title: 'Collection plan started', meta: 'Ridgeline LLC' },
]

export function DashboardDemo() {
  return (
    <Card className="border-border/40 w-full gap-0 overflow-hidden rounded-none p-0 shadow-sm">
      <div className="border-border/40 flex items-center justify-between gap-3 border-b px-5 py-4 sm:px-6">
        <div>
          <h3 className="text-foreground text-sm font-semibold tracking-tight">
            Collections
          </h3>
          <p className="text-muted-foreground mt-0.5 text-xs">
            How every account is trending this month
          </p>
        </div>
      </div>

      <div className="grid grid-cols-2 gap-3 px-5 py-4 sm:grid-cols-4 sm:px-6">
        {stats.map((stat) => (
          <div key={stat.label} className="border-border/40 min-w-0 rounded-lg border p-3">
            <p className="text-muted-foreground truncate text-[11px]">
              {stat.label}
            </p>
            <p className="text-foreground mt-1 text-base font-semibold tabular-nums">
              {stat.value}
            </p>
            <p
              className={cn(
                'mt-1 flex items-center gap-0.5 text-[11px] tabular-nums',
                stat.trend === 'up'
                  ? 'text-emerald-600 dark:text-emerald-400'
                  : 'text-muted-foreground',
              )}
            >
              {stat.trend === 'up' ? (
                <ArrowUpRight className="size-3" />
              ) : (
                <ArrowDownRight className="size-3" />
              )}
              {stat.delta}
            </p>
          </div>
        ))}
      </div>

      <div className="border-border/40 grid grid-cols-1 gap-6 border-t px-5 py-5 sm:grid-cols-2 sm:gap-0 sm:divide-x sm:divide-border/40 sm:px-6">
        <div className="sm:pr-6">
          <h4 className="text-foreground text-xs font-medium">
            Channel mix
          </h4>
          <div className="divide-border/40 mt-3 flex flex-col divide-y">
            {channels.map(({ icon: ChannelIcon, label, sent, rate }) => (
              <div
                key={label}
                className="flex items-center gap-3 py-2.5 first:pt-0 last:pb-0"
              >
                <ChannelIcon className="text-foreground/60 size-4 shrink-0" />
                <div className="min-w-0 flex-1">
                  <p className="text-foreground text-xs font-medium">
                    {label}
                  </p>
                  <p className="text-muted-foreground text-[11px]">{sent}</p>
                </div>
                <span className="text-foreground text-xs font-medium tabular-nums">
                  {rate}
                </span>
              </div>
            ))}
          </div>
        </div>

        <div className="sm:pl-6">
          <h4 className="text-foreground text-xs font-medium">Timeline</h4>
          <div className="relative mt-3 flex flex-col gap-3.5 pl-4">
            <div className="bg-border/50 absolute top-1 bottom-1 left-[3px] w-px" />
            {timeline.map((entry) => (
              <div key={entry.title} className="relative">
                <span className="bg-foreground/40 absolute top-1 -left-4 size-1.5 rounded-full" />
                <p className="text-foreground text-xs font-medium">
                  {entry.title}
                </p>
                <p className="text-muted-foreground text-[11px]">
                  {entry.meta}
                </p>
              </div>
            ))}
          </div>
        </div>
      </div>
    </Card>
  )
}
```

### `registry/blocks/content/content-11/content-11-example.tsx`

```tsx
import { Content11, type Content11Props } from './content-11'

export const values = {
  title: 'Every account, one place to watch it move',
  description:
    'Balances, campaigns, and payments stay in sync automatically, so your team spends less time reconciling and more time collecting.',
  variant: 'standard',
  animation: 'subtle',
  feature1: {
    icon: 'LayoutDashboard',
    title: 'One view for every account',
    description:
      'Balances, payments, and campaign activity live in a single dashboard instead of scattered spreadsheets.',
  },
  feature2: {
    icon: 'Sparkles',
    title: 'Insights that update themselves',
    description:
      'Every record is grouped by status, channel, and performance automatically, so trends surface before you go looking for them.',
  },
} satisfies Content11Props

export function Content11Example() {
  return (
    <Content11
      title={values.title}
      description={values.description}
      feature1={values.feature1}
      feature2={values.feature2}
      variant={values.variant}
      animation={values.animation}
    />
  )
}
```
