# Skyline Stats

> A stats section where the chart is a city: each team is a tower as tall as its count of release trains, with the number on a sign on its roof. Hover or focus a tower and it lights up floor by floor while the others dim. Beside it, a serif headline and three figures in a ruled list.

A shadcn/ui block from the [@keyframeui](https://keyframeui.com/?utm_source=shadcn.exchange) registry, listed on [shadcn.exchange](https://shadcn.exchange/r/keyframeui/skyline-stats).

- Page, with a live preview: https://shadcn.exchange/r/keyframeui/skyline-stats
- Screenshot: https://shadcn.exchange/shot/keyframeui/skyline-stats/light.png
- Registry item: https://keyframeui.com/r/skyline-stats.json
- Categories: blocks, stats-sections
- Listed: 2026-11-02, source last changed 2026-11-02

## Install

```bash
npx shadcn@latest add https://shadcn.exchange/r/keyframeui/skyline-stats.json
```

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

## Dependencies

- Registry items: `https://keyframeui.com/r/skyline.json`

## Notes from the registry

Live preview and the components it's built with: https://keyframeui.com/blocks/stats-sections/skyline-stats

## Files

### `registry/blocks/skyline-stats.tsx`

```tsx
"use client";

import * as React from "react";

import { Skyline, type SkylineTower } from "@/components/ui/skyline";

/* ── Content ─────────────────────────────────────────────────
 * Everything you'd change to make the section yours: the
 * palette, the copy, the figures beside the chart and the teams.
 * Each team is a tower as tall as its count, with the number on
 * a sign on its roof; hover or focus one to light it up.
 * ─────────────────────────────────────────────────────────── */

/** Paper and ink, an electric blue for the headline's italic, a quiet blue far print and a hot signal color for the sun and a lit tower. */
const PALETTE = {
  light: { paper: "#fafaf9", ink: "#0b0b0d", accent: "#2747ff", signal: "#ff5a1f", tint: "#bcc7ff" },
  dark: { paper: "#07080c", ink: "#f4f4f6", accent: "#8292ff", signal: "#ff6a2b", tint: "#202c78" },
};

const HEADLINE = { before: "Every team on the", accent: "same", after: "timetable" };
const BODY =
  "Each tower is one team's releases this year. The tall ones aren't working harder: they ship smaller trains more often, which is the whole idea.";

const FIGURES = [
  { value: "4,812", label: "changes shipped since January" },
  { value: "11 min", label: "median time to roll a train back" },
  { value: "0", label: "deploys after 4pm on a Friday" },
];

const CHART_LABEL = "Release trains shipped per team in 2026";
const TEAMS: SkylineTower[] = [
  { label: "Payments", value: 212 },
  { label: "Search", value: 148 },
  { label: "Mobile", value: 96 },
  { label: "Growth", value: 174 },
  { label: "Platform", value: 260 },
  { label: "Data", value: 121 },
];

/* ── Section ─────────────────────────────────────────────── */

export function SkylineStats() {
  return (
    <section
      style={
        {
          "--paper-light": PALETTE.light.paper,
          "--ink-light": PALETTE.light.ink,
          "--accent-light": PALETTE.light.accent,
          "--tint-light": PALETTE.light.tint,
          "--signal-light": PALETTE.light.signal,
          "--signal-dark": PALETTE.dark.signal,
          "--paper-dark": PALETTE.dark.paper,
          "--ink-dark": PALETTE.dark.ink,
          "--accent-dark": PALETTE.dark.accent,
          "--tint-dark": PALETTE.dark.tint,
        } as React.CSSProperties
      }
      className="bg-(--paper) text-(--ink) [--accent:var(--accent-light)] [--ink:var(--ink-light)] [--paper:var(--paper-light)] [--signal:var(--signal-light)] [--skyline-sun:var(--signal)] [--skyline-tint:var(--tint)] [--tint:var(--tint-light)] dark:[--accent:var(--accent-dark)] dark:[--signal:var(--signal-dark)] dark:[--ink:var(--ink-dark)] dark:[--paper:var(--paper-dark)] dark:[--tint:var(--tint-dark)]"
    >
      <div className="mx-auto grid max-w-6xl gap-12 px-6 py-24 sm:py-28 lg:grid-cols-[minmax(0,22rem)_minmax(0,1fr)] lg:items-end lg:gap-16">
        <div>
          <h2 className="font-serif text-4xl leading-[1.05] font-normal tracking-[-0.02em] text-balance sm:text-5xl">
            {HEADLINE.before} <em className="text-(--accent)">{HEADLINE.accent}</em> {HEADLINE.after}
          </h2>
          <p className="mt-5 text-base leading-relaxed text-pretty opacity-70">{BODY}</p>
          <dl className="mt-10 divide-y divide-current/15 border-y border-current/15">
            {FIGURES.map((figure) => (
              <div key={figure.label} className="flex items-baseline justify-between gap-6 py-3.5">
                <dt className="text-sm opacity-65">{figure.label}</dt>
                <dd className="font-mono text-lg tabular-nums">{figure.value}</dd>
              </div>
            ))}
          </dl>
        </div>
        <Skyline
          towers={TEAMS.map((team) => ({ ...team, display: `${team.value} trains` }))}
          signs="always"
          seed={9}
          sun={0.12}
          trees={false}
          label={CHART_LABEL}
          className="h-[22rem] sm:h-[26rem]"
        />
      </div>
    </section>
  );
}
```
