# Stats Section v4

> A two-tone heading (title plus muted description) pinned to the top and a 2×2 grid of large stats resting just above the flat end of the curve, over an edge-to-edge growth chart that fills the section: a gray line curving up from the bottom-left above a field of fading hairline bars. Static data, no API.

A shadcn/ui block from the [@uiception](https://uiception.com) registry, listed on [shadcn.exchange](https://shadcn.exchange/r/uiception/stats-section-v4).

- Page, with a live preview: https://shadcn.exchange/r/uiception/stats-section-v4
- Screenshot: https://abzjhwgwpdpz7ua5.public.blob.vercel-storage.com/shots/uiception/stats-section-v4-light-f6a179feea8992ad.png
- Registry item: https://uiception.com/r/stats-section-v4.json
- Listed: 2026-10-13, source last changed 2026-10-13

## Install

```bash
npx shadcn@latest add https://uiception.com/r/stats-section-v4.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: `recharts`
- Registry items: `chart`

## Files

### `registry/new-york/blocks/stats-section-v4/page.tsx`

```tsx
import StatsSectionV4 from "./components/stats-section-v4"

export default function Page() {
  return <StatsSectionV4 />
}
```

### `registry/new-york/blocks/stats-section-v4/components/stats-section-v4.tsx`

```tsx
import { sectionHeader, stats } from "../lib/config"
import { ScaleChart } from "./scale-chart"

export default function StatsSectionV4() {
  return (
    <section className="relative overflow-hidden">
      <div className="relative z-10 mx-auto flex max-w-6xl flex-col px-6 pt-16 md:min-h-[36rem] md:justify-between md:pt-24 md:pb-36 lg:min-h-[40rem] lg:pb-40">
        <h2 className="max-w-lg text-3xl leading-[1.15] font-medium tracking-tight md:text-4xl">
          {sectionHeader.title}{" "}
          <span className="text-muted-foreground">
            {sectionHeader.subtitle}
          </span>
        </h2>

        <dl className="mt-10 grid max-w-md grid-cols-2 gap-x-10 gap-y-8 md:mt-16">
          {stats.map((stat) => (
            <div key={stat.id} className="flex flex-col-reverse gap-1">
              <dt className="text-sm text-muted-foreground">{stat.label}</dt>
              <dd className="text-3xl font-semibold tracking-tight tabular-nums md:text-4xl">
                {stat.value}
              </dd>
            </div>
          ))}
        </dl>
      </div>

      <div
        aria-hidden
        className="pointer-events-none relative mt-10 h-56 sm:h-72 md:absolute md:inset-0 md:mt-0 md:h-auto"
      >
        <ScaleChart />
      </div>
    </section>
  )
}
```

### `registry/new-york/blocks/stats-section-v4/components/scale-chart.tsx`

```tsx
"use client"

import * as React from "react"
import { Bar, ComposedChart, Line, XAxis, YAxis } from "recharts"

import { type ChartConfig, ChartContainer } from "@/components/ui/chart"
import { cn } from "@/lib/utils"

import { CHART_COLOR, weeklyInstalls } from "../lib/config"

const chartConfig = {
  installs: { label: "Installs", color: CHART_COLOR },
} satisfies ChartConfig

const peak = Math.max(...weeklyInstalls.map((point) => point.installs))

export function ScaleChart({ className }: { className?: string }) {
  const gradientId = `ssv4-bars-${React.useId().replace(/:/g, "")}`

  return (
    <ChartContainer
      config={chartConfig}
      className={cn("aspect-auto h-full w-full", className)}
    >
      <ComposedChart
        data={weeklyInstalls}
        margin={{ left: 0, right: 0, top: 32, bottom: 0 }}
        barCategoryGap={0}
      >
        <defs>
          <linearGradient id={gradientId} x1="0" x2="0" y1="0" y2="1">
            <stop
              offset="0%"
              stopColor="var(--color-installs)"
              stopOpacity={0.35}
            />
            <stop
              offset="100%"
              stopColor="var(--color-installs)"
              stopOpacity={0.03}
            />
          </linearGradient>
        </defs>
        <XAxis dataKey="week" hide />
        <YAxis hide domain={[0, peak]} />
        <Bar
          dataKey="installs"
          fill={`url(#${gradientId})`}
          barSize={1}
          isAnimationActive={false}
        />
        <Line
          dataKey="installs"
          type="monotone"
          stroke="var(--color-installs)"
          strokeWidth={2}
          dot={false}
          isAnimationActive={false}
        />
      </ComposedChart>
    </ChartContainer>
  )
}
```

### `registry/new-york/blocks/stats-section-v4/lib/config.ts`

```ts
/** Same neutral gray as the Next.js series in stats-section-v2. */
export const CHART_COLOR = "#888888"

export const sectionHeader = {
  title: "Adoption that compounds.",
  subtitle: "Every block installed makes the next project faster to ship.",
} as const

export type Stat = {
  id: string
  value: string
  label: string
}

export const stats: Stat[] = [
  { id: "installs", value: "1.2M", label: "installs this week" },
  { id: "projects", value: "48k", label: "projects shipped" },
  { id: "blocks", value: "310", label: "blocks and templates" },
  { id: "countries", value: "140+", label: "countries building" },
]

export type WeekPoint = {
  week: number
  installs: number
}

const WEEKS = 180
const FINAL_INSTALLS = 1200
const START_INSTALLS = 18
/** Higher values keep the curve flat for longer before it bends upward. */
const GROWTH = 4.2

/**
 * Weekly installs, in thousands: flat at first, then compounding up to the
 * 1.2M "installs this week" stat in the final week.
 */
export const weeklyInstalls: WeekPoint[] = Array.from(
  { length: WEEKS },
  (_, index) => {
    const t = index / (WEEKS - 1)
    const curve = (Math.exp(GROWTH * t) - 1) / (Math.exp(GROWTH) - 1)
    return {
      week: index + 1,
      installs: Math.round(
        START_INSTALLS + (FINAL_INSTALLS - START_INSTALLS) * curve
      ),
    }
  }
)
```
