# Cortexcn documentation

> Cortexcn is a shadcn/ui registry of React components, charts, and blocks. Install them with one command, or let your AI agent build with them. Built for freelancers, developers, and startups who ship fast.

Cortexcn items are installed with the shadcn CLI. Add the registry to `components.json` once, then add any item by name. The source is copied into the project as React and Tailwind CSS, so there is no runtime package to update.

- Registry namespace: `@cortexcn`, served from `https://ui.cortexcn.dev/r/{name}.json`
- Registry index: https://ui.cortexcn.dev/r/registry.json
- Install an item: `npx shadcn@latest add @cortexcn/<name>`
- MCP server for agents: https://ui.cortexcn.dev/mcp (`claude mcp add --transport http cortexcn https://ui.cortexcn.dev/mcp`; setup for other clients at https://ui.cortexcn.dev/docs/integration/mcp)
- Agent skills and DESIGN.md: `npx shadcn@latest add https://ui.cortexcn.dev/r/agent-kit.json`
- Site: https://www.cortexcn.dev · Docs: https://ui.cortexcn.dev/docs

---

# Introduction

> Cortexcn is a set of beautifully designed components and a code distribution platform. Works with your favorite React frameworks and AI models. Open Code.

Source: https://ui.cortexcn.dev/docs

**This is not a component library you install. It is code you own and build on.**

You know how most traditional component libraries work: you install a package from npm, import the components, and use them in your app.

This approach works well until you need to customize a component to fit your design system or need one that isn't included in the library. **Often, you end up wrapping library components, writing workarounds to override styles, or mixing components from different libraries with incompatible APIs.**

This is what Cortexcn aims to solve. It is built around the following principles:

- **Open Code:** The top layer of your component code is open for modification.
- **Composition:** Every component uses a common, composable interface, making them predictable.
- **Distribution:** A shadcn registry and a single CLI command bring components into any project.
- **Beautiful Defaults:** Carefully chosen default styles, so you get great design out of the box.
- **AI-Ready:** Open code for LLMs to read, understand, and improve.

## Open Code

Cortexcn hands you the actual component code. You have full control to customize and extend the components to your needs. This means:

- **Full Transparency:** You see exactly how each component is built.
- **Easy Customization:** Modify any part of a component to fit your design and functionality requirements.
- **AI Integration:** Access to the code makes it straightforward for LLMs to read, understand, and even improve your components.

_In a typical library, if you need to change a component's behavior, you have to override styles or wrap the component. With Cortexcn, you edit the component code directly._

## Composition

Every component in Cortexcn shares a common, composable interface. **If a component does not exist, we build it, make it composable, and adjust its style to match and work with the rest of the design system.**

_A shared, composable interface means it's predictable for both your team and LLMs. You are not learning a different API for every new component._

## Distribution

Cortexcn is also a code distribution system. It publishes every component to a registry that follows the shadcn registry schema, and you install components with the shadcn CLI.

- **Schema:** A flat-file structure that defines each component, its dependencies, and its files.
- **CLI:** A command-line tool that installs components and their dependencies into your project.

_Add the `@cortexcn` registry to your `components.json` once, then run `npx shadcn@latest add @cortexcn/<component>` to add any component. See [Installation](https://ui.cortexcn.dev/docs/installation)._

## Beautiful Defaults

Cortexcn comes with a growing collection of components that have carefully chosen default styles. They are designed to look good on their own and to work well together as a consistent system:

- **Good Out of the Box:** Your UI has a clean and minimal look without extra work.
- **Unified Design:** Components naturally fit with one another. Each component is built to match the others, keeping your UI consistent.
- **Easily Customizable:** Styles come from CSS variables and Tailwind classes, so it's simple to override and extend the defaults.

## AI-Ready

The design of Cortexcn makes it easy for AI tools to work with your code. Its open code and consistent API allow AI models to read, understand, and even generate new components.

_An AI model can learn how your components work and suggest improvements or even create new components that integrate with your existing design._

---

# Components

> Every component you can add to your project from the Cortexcn registry.

Source: https://ui.cortexcn.dev/docs/components

Cortexcn components come in four families. Every one installs the same way: `npx shadcn@latest add @cortexcn/<name>`.

## Components

Everyday building blocks from shadcn/ui, from buttons and dialogs to menus, forms, and sidebars. Each page has the examples from the shadcn docs, ready to copy.

- [Accordion](https://ui.cortexcn.dev/docs/components/accordion.md): A vertically stacked set of headings that each reveal a section of content.
- [Alert](https://ui.cortexcn.dev/docs/components/alert.md): Displays a callout for user attention.
- [Alert Dialog](https://ui.cortexcn.dev/docs/components/alert-dialog.md): A modal dialog that interrupts the user with important content and expects a response.
- [Aspect Ratio](https://ui.cortexcn.dev/docs/components/aspect-ratio.md): Displays content within a desired ratio.
- [Avatar](https://ui.cortexcn.dev/docs/components/avatar.md): An image element with a fallback for representing the user.
- [Badge](https://ui.cortexcn.dev/docs/components/badge.md): Displays a badge or a component that looks like a badge.
- [Breadcrumb](https://ui.cortexcn.dev/docs/components/breadcrumb.md): Displays the path to the current resource using a hierarchy of links.
- [Button](https://ui.cortexcn.dev/docs/components/button.md): Displays a button or a component that looks like a button.
- [Button Group](https://ui.cortexcn.dev/docs/components/button-group.md): A container that groups related buttons together with consistent styling.
- [Calendar](https://ui.cortexcn.dev/docs/components/calendar.md): A date field component that allows users to enter and edit dates.
- [Card](https://ui.cortexcn.dev/docs/components/card.md): Displays a card with a header, content, and footer.
- [Carousel](https://ui.cortexcn.dev/docs/components/carousel.md): A carousel with motion and swipe built using Embla.
- [Checkbox](https://ui.cortexcn.dev/docs/components/checkbox.md): A control that allows the user to toggle between checked and not checked.
- [Collapsible](https://ui.cortexcn.dev/docs/components/collapsible.md): An interactive component which expands and collapses a panel.
- [Combobox](https://ui.cortexcn.dev/docs/components/combobox.md): An input with a list of suggestions that filters as you type.
- [Command](https://ui.cortexcn.dev/docs/components/command.md): A fast, composable command menu for React.
- [Context Menu](https://ui.cortexcn.dev/docs/components/context-menu.md): Displays a menu of actions triggered by a right click.
- [Dialog](https://ui.cortexcn.dev/docs/components/dialog.md): A window overlaid on the page that renders the content underneath inert.
- [Drawer](https://ui.cortexcn.dev/docs/components/drawer.md): A drawer component for React, built on Vaul.
- [Dropdown Menu](https://ui.cortexcn.dev/docs/components/dropdown-menu.md): Displays a menu of actions or functions, triggered by a button.
- [Empty](https://ui.cortexcn.dev/docs/components/empty.md): Displays an empty state, with media, a title, a description, and actions.
- [Field](https://ui.cortexcn.dev/docs/components/field.md): Combines labels, controls, and help text into accessible form fields.
- [Hover Card](https://ui.cortexcn.dev/docs/components/hover-card.md): For sighted users to preview content available behind a link.
- [Input](https://ui.cortexcn.dev/docs/components/input.md): Displays a form input field or a component that looks like an input field.
- [Input Group](https://ui.cortexcn.dev/docs/components/input-group.md): Adds addons, buttons, and helper content to inputs.
- [Input OTP](https://ui.cortexcn.dev/docs/components/input-otp.md): An accessible one-time password input with copy and paste support.
- [Item](https://ui.cortexcn.dev/docs/components/item.md): A versatile row for displaying media, a title, a description, and actions.
- [Kbd](https://ui.cortexcn.dev/docs/components/kbd.md): Displays textual user input from a keyboard, such as a shortcut.
- [Label](https://ui.cortexcn.dev/docs/components/label.md): Renders an accessible label associated with controls.
- [Menubar](https://ui.cortexcn.dev/docs/components/menubar.md): A persistent menu, common in desktop apps, with quick access to a set of commands.
- [Native Select](https://ui.cortexcn.dev/docs/components/native-select.md): A styled native HTML select element.
- [Navigation Menu](https://ui.cortexcn.dev/docs/components/navigation-menu.md): A collection of links for navigating websites.
- [Pagination](https://ui.cortexcn.dev/docs/components/pagination.md): Page navigation with next and previous links.
- [Popover](https://ui.cortexcn.dev/docs/components/popover.md): Displays rich content in a portal, triggered by a button.
- [Progress](https://ui.cortexcn.dev/docs/components/progress.md): Displays an indicator showing the completion progress of a task.
- [Radio Group](https://ui.cortexcn.dev/docs/components/radio-group.md): A set of checkable buttons where no more than one can be checked at a time.
- [Resizable](https://ui.cortexcn.dev/docs/components/resizable.md): Accessible resizable panel groups and layouts with keyboard support.
- [Scroll Area](https://ui.cortexcn.dev/docs/components/scroll-area.md): Augments native scroll functionality for custom, cross-browser styling.
- [Select](https://ui.cortexcn.dev/docs/components/select.md): Displays a list of options for the user to pick from, triggered by a button.
- [Separator](https://ui.cortexcn.dev/docs/components/separator.md): Visually or semantically separates content.
- [Sheet](https://ui.cortexcn.dev/docs/components/sheet.md): Extends the dialog to show content that complements the main content of the screen.
- [Sidebar](https://ui.cortexcn.dev/docs/components/sidebar.md): A composable, themeable, and customizable sidebar.
- [Skeleton](https://ui.cortexcn.dev/docs/components/skeleton.md): Shows a placeholder while content is loading.
- [Slider](https://ui.cortexcn.dev/docs/components/slider.md): An input where the user selects a value from within a given range.
- [Sonner](https://ui.cortexcn.dev/docs/components/sonner.md): An opinionated toast component for React.
- [Spinner](https://ui.cortexcn.dev/docs/components/spinner.md): An indicator that shows a loading state.
- [Switch](https://ui.cortexcn.dev/docs/components/switch.md): A control that allows the user to toggle between on and off.
- [Table](https://ui.cortexcn.dev/docs/components/table.md): A responsive table component.
- [Tabs](https://ui.cortexcn.dev/docs/components/tabs.md): A set of layered sections of content, shown one at a time.
- [Textarea](https://ui.cortexcn.dev/docs/components/textarea.md): Displays a form textarea or a component that looks like a textarea.
- [Toggle](https://ui.cortexcn.dev/docs/components/toggle.md): A two-state button that can be either on or off.
- [Toggle Group](https://ui.cortexcn.dev/docs/components/toggle-group.md): A set of two-state buttons that can be toggled on or off.
- [Tooltip](https://ui.cortexcn.dev/docs/components/tooltip.md): A popup that shows information about an element on hover or keyboard focus.

## Cortex

Cortexcn originals you won't find in shadcn/ui: motion, navigation, and theming.

- [Command Search](https://ui.cortexcn.dev/docs/components/command-search.md): A command palette that types queries and live-filters grouped results, with keyboard navigation.
- [Fan-Out Diagram](https://ui.cortexcn.dev/docs/components/fan-out-diagram.md): An animated architecture diagram where one source feeds a hub that fans out to many nodes, each with a live status.
- [FAQ Tabs Card](https://ui.cortexcn.dev/docs/components/faq-tabs-card.md): A tabbed FAQ card with animated accordion answers and a support footer.
- [Gooey Nav](https://ui.cortexcn.dev/docs/components/gooey-nav.md): A row of links with a filled pill under the active one. Choosing another link sends the pill there like a drop of liquid.
- [Lanyard 3D](https://ui.cortexcn.dev/docs/components/lanyard-3d.md): A 3D ID badge on a strap. Drag it and it swings and twists on a simulated strap; click it to flip it over.
- [Lanyard Badge](https://ui.cortexcn.dev/docs/components/lanyard-badge.md): An ID badge hanging from a strap. Drag it and it swings back on a simulated rope; click it to flip it over.
- [Line Nav](https://ui.cortexcn.dev/docs/components/line-nav.md): Vertical navigation with a line marker that expands on hover and active state.
- [Logos Carousel](https://ui.cortexcn.dev/docs/components/logos-carousel.md): Cycle through logos column by column in a staggered wave.
- [Marquee](https://ui.cortexcn.dev/docs/components/marquee.md): An infinite scrolling component that can be used to display text, images, or videos.
- [Number Ticker](https://ui.cortexcn.dev/docs/components/number-ticker.md): A rolling digit ticker that counts to a value with per-digit stagger, padding, and blur.
- [Perspective Marquee](https://ui.cortexcn.dev/docs/components/perspective-marquee.md): A tilted wall of images that scrolls endlessly in alternating columns.
- [Sphere Menu](https://ui.cortexcn.dev/docs/components/sphere-menu.md): A sphere of image tiles you can spin in any direction. When it slows down, the nearest tile turns to face you and its link appears.
- [Theme Toggle Effect](https://ui.cortexcn.dev/docs/components/theme-toggle-effect.md): Animated transitions when switching between light and dark themes.
- [Work Experience](https://ui.cortexcn.dev/docs/components/work-experience.md): Display work experiences with role details, company logos, and durations.

## Backgrounds

Animated full-bleed backgrounds for heroes and sections, drawn with WebGL.

- [Light Speed](https://ui.cortexcn.dev/docs/components/light-speed.md): A warp-speed tunnel of glowing light streaks, drawn with three.js and bloom.

## Charts

Composable charts with animation, tooltips, and themes. Mix lines, areas, and time-aligned columns on one chart with the [**Composed Chart**](https://ui.cortexcn.dev/docs/components/composed-chart) (`SeriesBar` + `Line` / `Area`).

- [Area Chart](https://ui.cortexcn.dev/docs/components/area-chart.md): A composable area chart with gradient fills, tooltips, and hover interactions
- [Bar Chart](https://ui.cortexcn.dev/docs/components/bar-chart.md): A composable bar chart with spring animations, stacked bars, horizontal orientation, and grouped series support
- [Candlestick Chart](https://ui.cortexcn.dev/docs/components/candlestick-chart.md): A composable OHLC candlestick chart with gradients, patterns, tooltips, and hover interactions
- [Choropleth Chart](https://ui.cortexcn.dev/docs/components/choropleth-chart.md): A composable geographic map chart for visualizing data across regions with interactive tooltips, zoom controls, and pattern support
- [Composed Chart](https://ui.cortexcn.dev/docs/components/composed-chart.md): Mix SeriesBar, Line, and Area on one shared time axis (Recharts ComposedChart–style)
- [Funnel Chart](https://ui.cortexcn.dev/docs/components/funnel-chart.md): An animated funnel chart with multi-layer halo rings, hover interactions, and staggered entrance animations
- [Gauge](https://ui.cortexcn.dev/docs/components/gauge-chart.md): Notch-based radial or linear gauge with optional center label, theme fills, patterns, arc gradients, and responsive sizing
- [Heatmap Chart](https://ui.cortexcn.dev/docs/components/heatmap-chart.md): A contribution heatmap with animated cells, configurable level colors and patterns, and an interactive legend
- [Line Chart](https://ui.cortexcn.dev/docs/components/line-chart.md): A composable line chart with tooltips, markers, and hover interactions
- [Live Line Chart](https://ui.cortexcn.dev/docs/components/live-line-chart.md): Real-time streaming line chart with smooth scrolling, crosshair, and animated axes
- [Pie Chart](https://ui.cortexcn.dev/docs/components/pie-chart.md): A composable pie and donut chart with animated slices, hover interactions, patterns, gradients, and an interactive legend
- [Profit/Loss Line](https://ui.cortexcn.dev/docs/components/profit-loss-line.md): Sign-colored line segments for profit and loss on a shared zero baseline
- [Radar Chart](https://ui.cortexcn.dev/docs/components/radar-chart.md): A composable multi-series radar chart with animated polygons, hover interactions, and customizable metrics
- [Ring Chart](https://ui.cortexcn.dev/docs/components/ring-chart.md): A composable multi-ring progress chart with animated arcs, hover interactions, and a reusable legend component
- [Sankey Chart](https://ui.cortexcn.dev/docs/components/sankey-chart.md): A composable sankey diagram for visualizing flow between nodes with animated links and interactive tooltips
- [Scatter Chart](https://ui.cortexcn.dev/docs/components/scatter-chart.md): A composable time-series scatter chart with offset rings, hover dimming, and animated enter
- [Sunburst Chart](https://ui.cortexcn.dev/docs/components/sunburst-chart.md): A composable hierarchical sunburst chart with drill-down zoom, animated segments, breadcrumb navigation, and legend sync

---

# Accordion

> A vertically stacked set of headings that each reveal a section of content.

Source: https://ui.cortexcn.dev/docs/components/accordion

## Installation

```bash
npx shadcn@latest add @cortexcn/accordion
```

The open and close animations use `animate-accordion-down` and `animate-accordion-up` from `tw-animate-css`, which `shadcn init` adds to your project.

## Usage

```tsx
import {
  Accordion,
  AccordionContent,
  AccordionItem,
  AccordionTrigger,
} from "@/components/accordion";
```

```tsx
<Accordion type="single" collapsible defaultValue="item-1">
  <AccordionItem value="item-1">
    <AccordionTrigger>Is it accessible?</AccordionTrigger>
    <AccordionContent>
      Yes. It adheres to the WAI-ARIA design pattern.
    </AccordionContent>
  </AccordionItem>
</Accordion>
```

## Examples

### Basic

A basic accordion that shows one item at a time. The first item is open by default.

### Multiple

Use `type="multiple"` to allow multiple items to be open at the same time.

### Disabled

Use the `disabled` prop on `AccordionItem` to disable individual items.

### Card

Wrap the accordion in a [Card](https://ui.cortexcn.dev/docs/components/card).

## API Reference

The accordion is built on the [Radix UI Accordion](https://www.radix-ui.com/primitives/docs/components/accordion), so every Radix prop works.

### Accordion

| Prop            | Type                     | Default  | Description                                        |
| --------------- | ------------------------ | -------- | -------------------------------------------------- |
| `type`          | `"single" \| "multiple"` | required | Whether one or several items can be open at a time |
| `collapsible`   | `boolean`                | `false`  | With `type="single"`, lets the open item close     |
| `defaultValue`  | `string \| string[]`     | -        | Items open on first render                         |
| `value`         | `string \| string[]`     | -        | Controlled open items                              |
| `onValueChange` | `(value) => void`        | -        | Called when the open items change                  |
| `disabled`      | `boolean`                | `false`  | Disables every item                                |
| `className`     | `string`                 | -        | Extra classes for the root                         |

### AccordionItem

| Prop        | Type      | Default  | Description                  |
| ----------- | --------- | -------- | ---------------------------- |
| `value`     | `string`  | required | Unique value for the item    |
| `disabled`  | `boolean` | `false`  | Stops the item from toggling |
| `className` | `string`  | -        | Extra classes for the item   |

### AccordionTrigger

| Prop        | Type     | Default | Description                   |
| ----------- | -------- | ------- | ----------------------------- |
| `className` | `string` | -       | Extra classes for the heading |

### AccordionContent

| Prop        | Type     | Default | Description                         |
| ----------- | -------- | ------- | ----------------------------------- |
| `className` | `string` | -       | Extra classes for the content panel |

---

# Alert

> Displays a callout for user attention.

Source: https://ui.cortexcn.dev/docs/components/alert

## Installation

```bash
npx shadcn@latest add @cortexcn/alert
```

## Usage

```tsx
import { Alert, AlertTitle, AlertDescription, AlertAction } from "@/components/alert";
```

## Examples

### Basic

### With icons

### Destructive

### With actions

### Inside card

---

# Alert Dialog

> A modal dialog that interrupts the user with important content and expects a response.

Source: https://ui.cortexcn.dev/docs/components/alert-dialog

## Installation

```bash
npx shadcn@latest add @cortexcn/alert-dialog
```

## Usage

```tsx
import { AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogMedia, AlertDialogOverlay, AlertDialogPortal, AlertDialogTitle, AlertDialogTrigger } from "@/components/alert-dialog";
```

## Examples

### Basic

### Small

### With media

### Small with media

### Destructive

### In dialog

---

# Area Chart

> A composable area chart with gradient fills, tooltips, and hover interactions

Source: https://ui.cortexcn.dev/docs/components/area-chart

## Installation

```bash
npx shadcn@latest add @cortexcn/area-chart
```

## Usage

The Area Chart uses the same composable API as the Line Chart. See the [charts gallery](https://ui.cortexcn.dev/charts/area-chart) for interactive examples.

```tsx
import { AreaChart, Area, Grid, XAxis, ChartTooltip } from "@/components/charts";

const data = [
  { date: new Date("2025-01-01"), revenue: 12000, costs: 8500 },
  { date: new Date("2025-01-02"), revenue: 13500, costs: 9200 },
  // ... more data
];

export default function RevenueChart() {
  return (
    <AreaChart data={data}>
      <Grid horizontal />
      <Area dataKey="revenue" fill="var(--chart-line-primary)" />
      <Area dataKey="costs" fill="var(--chart-line-secondary)" />
      <XAxis />
      <ChartTooltip />
    </AreaChart>
  );
}
```

## Components

### AreaChart

The root component that provides context to all children. It shares the same props as `LineChart`.

| Prop                          | Type                        | Default                                        | Description                                                     |
| ----------------------------- | --------------------------- | ---------------------------------------------- | --------------------------------------------------------------- |
| `data`                        | `Record<string, unknown>[]` | required                                       | Array of data points                                            |
| `xDataKey`                    | `string`                    | `"date"`                                       | Key in data for x-axis values                                   |
| `margin`                      | `Partial<Margin>`           | `{ top: 40, right: 40, bottom: 40, left: 40 }` | Chart margins                                                   |
| `animationDuration`           | `number`                    | `1100`                                         | Clip-reveal duration in ms (`cubic-bezier(0.85, 0, 0.15, 1)`)   |
| `status`                      | `"loading" \| "ready"`      | `"ready"`                                      | Loading ↔ ready choreography on one chart instance              |
| `loadingLabel`                | `string`                    | —                                              | Centered shimmer label while `status="loading"` (`""` hides it) |
| `yDomainTween`                | `boolean`                   | `true`                                         | Animate y-domain when status or target domain changes           |
| `yDomainTweenDuration`        | `number`                    | `500`                                          | Y-domain tween duration in ms                                   |
| `xDomain`                     | `[Date, Date]`              | —                                              | Visible x-range for brush zoom                                  |
| `xDomainSlotCount`            | `number`                    | —                                              | Full dataset length for x-scale padding when `xDomain` is set   |
| `tweenYDomainOnXDomainChange` | `boolean`                   | `false`                                        | Tween y-domain when the brush changes the visible x-range       |
| `aspectRatio`                 | `string`                    | `"2 / 1"`                                      | CSS aspect ratio                                                |
| `className`                   | `string`                    | `""`                                           | Additional CSS class                                            |
| `style`                       | `CSSProperties`             | —                                              | Inline container styles (e.g. fixed height for a brush strip)   |

### Area

Renders a filled area on the chart with a gradient fill.

| Prop                   | Type                     | Default                     | Description                                                                  |
| ---------------------- | ------------------------ | --------------------------- | ---------------------------------------------------------------------------- |
| `dataKey`              | `string`                 | required                    | Key in data for y values                                                     |
| `yAxisId`              | `string \| number`       | `"left"`                    | Y-scale group for biaxial charts (pair with `YAxis`)                         |
| `fill`                 | `string`                 | `var(--chart-line-primary)` | Gradient fill color                                                          |
| `fillOpacity`          | `number`                 | `0.4`                       | Fill opacity at the top                                                      |
| `stroke`               | `string`                 | Same as `fill`              | Line stroke color                                                            |
| `strokeWidth`          | `number`                 | `2`                         | Line stroke width                                                            |
| `curve`                | `CurveFactory`           | `curveMonotoneX`            | D3 curve function                                                            |
| `animate`              | `boolean`                | `true`                      | Enable grow animation                                                        |
| `showLine`             | `boolean`                | `true`                      | Show stroke line on top                                                      |
| `showHighlight`        | `boolean`                | `true`                      | Show highlight on hover                                                      |
| `gradientToOpacity`    | `number`                 | `0`                         | Opacity at bottom of gradient                                                |
| `fadeEdges`            | `boolean`                | `false`                     | Fade area fill at left/right edges                                           |
| `showMarkers`          | `boolean`                | `false`                     | Render scatter-style ring markers at each point                              |
| `loadingStroke`        | `string`                 | `var(--foreground)`         | Pulse stroke color while chart is loading                                    |
| `loadingStrokeOpacity` | `number`                 | `0.5`                       | Pulse stroke opacity while chart is loading                                  |
| `markers`              | `SeriesPointMarkerStyle` | —                           | Marker styling (same options as [`Scatter`](https://ui.cortexcn.dev/docs/components/scatter-chart)) |

### PatternArea

Renders a filled area using an SVG pattern (`url(#id)`). Define the pattern (e.g. `PatternLines`) as a child of `AreaChart`, then pair `PatternArea` with an `Area` that has `fillOpacity={0}` for the stroke line.

| Prop      | Type           | Default          | Description                                         |
| --------- | -------------- | ---------------- | --------------------------------------------------- |
| `dataKey` | `string`       | required         | Key in data for y values                            |
| `fill`    | `string`       | required         | Fill color or pattern URL (e.g. `url(#pattern-id)`) |
| `curve`   | `CurveFactory` | `curveMonotoneX` | D3 curve function                                   |

### Grid

Renders grid lines.

| Prop              | Type      | Default                                 | Description                                                       |
| ----------------- | --------- | --------------------------------------- | ----------------------------------------------------------------- |
| `horizontal`      | `boolean` | `true`                                  | Show horizontal lines                                             |
| `vertical`        | `boolean` | `false`                                 | Show vertical lines                                               |
| `numTicksRows`    | `number`  | `5`                                     | Number of horizontal lines                                        |
| `numTicksColumns` | `number`  | `10`                                    | Number of vertical lines                                          |
| `stroke`          | `string`  | `var(--chart-grid)`                     | Line color while ready                                            |
| `loadingStroke`   | `string`  | —                                       | Grid stroke while loading chrome is active                        |
| `strokeDasharray` | `string`  | `"4,4"`                                 | Dash pattern                                                      |
| `shimmer`         | `boolean` | `false`                                 | Animate a shimmer band across horizontal grid lines               |
| `shimmerStroke`   | `string`  | `color-mix(…)` on `--foreground` at 68% | Shimmer band color and opacity                                    |
| `shimmerLength`   | `number`  | `140`                                   | Shimmer band width in pixels                                      |
| `shimmerSpeed`    | `number`  | `1`                                     | Shimmer speed multiplier when sync is off (higher = faster)       |
| `shimmerSync`     | `boolean` | `false`                                 | Match shimmer timing to the line pulse (2.2s cycle + 280ms pause) |

### Background

Pattern fill for the plot area when you omit `Grid`. See the [Background utility](https://ui.cortexcn.dev/docs/utility/background) and **Pattern Background** examples on the [area chart gallery](https://ui.cortexcn.dev/charts/area-chart).

### YAxis

Value labels on the left or right. See [Y Axis](https://ui.cortexcn.dev/docs/utility/axis/y-axis) for `yAxisId`, `orientation`, and biaxial usage.

### XAxis

Renders x-axis labels that fade when the crosshair passes.

| Prop              | Type                 | Default  | Description                                                                                  |
| ----------------- | -------------------- | -------- | -------------------------------------------------------------------------------------------- |
| `numTicks`        | `number`             | `5`      | Number of tick labels to show                                                                |
| `tickerHalfWidth` | `number`             | `50`     | Fade radius for labels                                                                       |
| `tickMode`        | `"data" \| "domain"` | `"data"` | `"data"` snaps labels to data rows (crosshair-aligned); `"domain"` for calendar-even spacing |

### ChartTooltip

Renders the tooltip with crosshair, dots, and content box.

| Prop                  | Type                                    | Default  | Description                                               |
| --------------------- | --------------------------------------- | -------- | --------------------------------------------------------- |
| `showDatePill`        | `boolean`                               | `true`   | Show animated date ticker                                 |
| `showCrosshair`       | `boolean`                               | `true`   | Show vertical crosshair                                   |
| `showDots`            | `boolean`                               | `true`   | Show dots on series                                       |
| `indicatorColor`      | `string \| (point) => string`           | —        | Crosshair and dot color                                   |
| `indicatorDasharray`  | `string`                                | —        | Dash pattern for the crosshair (e.g. `"4,4"`)             |
| `indicatorFadeEdges`  | `"both" \| "top" \| "bottom" \| "none"` | `"both"` | Vertical crosshair fade                                   |
| `indicatorFadeLength` | `number`                                | `10`     | Fade size (% of height)                                   |
| `matchCrosshair`      | `boolean`                               | `false`  | Panel uses crosshair spring when `true`                   |
| `damping`             | `number`                                | `20`     | Panel follow when `matchCrosshair={false}`; `0` = instant |
| `content`             | `(props) => ReactNode`                  | -        | Custom content renderer                                   |
| `rows`                | `(point) => TooltipRow[]`               | -        | Custom row generator                                      |

## Brush zoom

See the [Brush](https://ui.cortexcn.dev/docs/utility/brush) utility docs for `ChartBrushLayout` and `ChartBrush` props.

Wrap the main chart in `ChartBrushLayout`, render a simplified mini chart in `brushStrip`, and add `ChartBrush` as a child of that strip. Pass `xDomain`, `xDomainSlotCount`, and `tweenYDomainOnXDomainChange` to the main `AreaChart` so the y-scale adapts as users pan and resize the brush.

<div className="not-prose mb-3 flex items-center justify-between gap-4">
  <h3 className="m-0 font-semibold text-foreground text-base tracking-tight">
    Preview
  </h3>
</div>

## Loading state

Drive loading and ready from your data layer with a single `AreaChart` — one `Grid`, one `Area`, no component swap. Set `status="loading"` while fetching; switch to `"ready"` when data resolves.

**Loading → ready:** pulse loop on skeleton data → pulse finishes its grow, then flows out right → loading label drifts down 30px, blurs, and fades → grid y-domain tween (500ms) → clip-path reveal (`cubic-bezier(0.85, 0, 0.15, 1)`) → interaction enabled.

**Ready → loading:** ready area conceals to the right → grid y-domain tween → pulse loop and shimmer resume.

Pair `Grid` `stroke` / `loadingStroke` with shimmer props. Pair `Area` `loadingStroke` props. Use `loadingLabel` on `AreaChart` for centered shimmer text via `@cortexcn/shimmering-text`.

<div className="not-prose mb-3 flex items-center justify-between gap-4">
  <h3 className="m-0 font-semibold text-foreground text-base tracking-tight">
    Preview
  </h3>
</div>

Toggle **Loading** / **Ready** in the preview to replay the transition, and **Pulse** / **Sweep** to switch the loading animation style. When target data spans a different y-range than the skeleton, `yDomainTween` morphs the scale before the area reveals.

Installing `@cortexcn/area-chart` pulls in `@cortexcn/shimmering-text` automatically.

### Loading style: pulse or sweep

The loading state has two animation styles, set with `loadingStyle` on the `Area`: the default `"pulse"` (a segment travels along the skeleton stroke) or `"sweep"` (a soft diagonal shimmer sweeps across the whole area). Set it on the `Area` inside a `status="loading"` chart, or on the `AreaChartLoading` wrapper:

```tsx
<AreaChart data={data} status="loading">
  <Grid horizontal shimmer />
  <Area dataKey="revenue" loadingStyle="sweep" />
</AreaChart>

// or, with the turnkey wrapper:
<AreaChartLoading loadingStyle="sweep" />;
```

The sweep masks over the real skeleton stroke, so it follows whatever `curve` the `Area` uses and respects `prefers-reduced-motion`. The sweep is used only during steady loading; the pulse still drives the exit transition. See the **Loading (Sweep)** example on the [area chart gallery](https://ui.cortexcn.dev/charts/area-chart).

## Dashed tail

Set `dashFromIndex` on `Area` to draw a solid stroke through one data point, then a dashed segment through the end of the series. Useful when the final period is still in progress (e.g. yesterday → today).

`dashFromIndex` is **inclusive** — dashing starts at that row and continues through the last point. The dashed segment follows the same curved path as the solid stroke and respects the stroke gradient fade from `fadeEdges`.

| Prop            | Type     | Default | Description                                         |
| --------------- | -------- | ------- | --------------------------------------------------- |
| `dashFromIndex` | `number` | —       | Inclusive data index where the dashed tail begins   |
| `dashArray`     | `string` | `"6,4"` | SVG `stroke-dasharray` pattern for the tail segment |

```tsx
<Area
  dataKey="visitors"
  dashFromIndex={5}
  dashArray="6,4"
  fill="var(--chart-line-primary)"
  fillOpacity={0.35}
/>
```

## Markers

Add markers to annotate specific dates on the chart:

```tsx
import {
  AreaChart,
  Area,
  ChartTooltip,
  ChartMarkers,
  MarkerTooltipContent,
  useActiveMarkers,
  type ChartMarker,
} from "@/components/charts";

const markers: ChartMarker[] = [
  {
    date: new Date("2025-01-05"),
    icon: "🚀",
    title: "v1.2.0 Released",
    description: "New chart animations",
  },
];

function MyChart({ data }) {
  return (
    <AreaChart data={data}>
      <Area dataKey="revenue" fill="var(--chart-line-primary)" />
      <ChartMarkers items={markers} />
      <ChartTooltip>
        <MarkerContent markers={markers} />
      </ChartTooltip>
    </AreaChart>
  );
}

function MarkerContent({ markers }) {
  const activeMarkers = useActiveMarkers(markers);
  if (activeMarkers.length === 0) return null;
  return <MarkerTooltipContent markers={activeMarkers} />;
}
```

### ChartMarker Interface

```ts
interface ChartMarker {
  date: Date;
  icon: React.ReactNode;
  title: string;
  description?: string;
  content?: React.ReactNode;
  color?: string;
  onClick?: () => void;
  href?: string;
  target?: "_blank" | "_self";
}
```

### ChartMarkers Props

| Prop        | Type            | Default  | Description                 |
| ----------- | --------------- | -------- | --------------------------- |
| `items`     | `ChartMarker[]` | required | Array of markers            |
| `size`      | `number`        | `28`     | Marker circle size          |
| `showLines` | `boolean`       | `true`   | Show vertical guide lines   |
| `animate`   | `boolean`       | `true`   | Animate markers on entrance |

## Segment Selection

Add click-drag and touch segment selection with composable components. The area highlight automatically shows the selected path segment.

### Basic Usage

```tsx
import {
  AreaChart,
  Area,
  Grid,
  XAxis,
  ChartTooltip,
  SegmentBackground,
  SegmentLineFrom,
  SegmentLineTo,
} from "@/components/charts";

<AreaChart data={data}>
  <Grid horizontal />
  <Area dataKey="revenue" fill="var(--chart-line-primary)" />
  <SegmentBackground />
  <SegmentLineFrom />
  <SegmentLineTo />
  <XAxis />
  <ChartTooltip />
</AreaChart>;
```

Use `SegmentBackground`, `SegmentLineFrom`, and `SegmentLineTo` independently — you do not need all three. Boundary lines support `variant="dashed" | "solid" | "gradient"`.

### Reading Selection Data

Use the `useChart` hook inside a child component to read the active selection:

```tsx
import { useChart } from "@/components/charts";

function SelectionStats({ onSelectionChange }) {
  const { selection, data, xAccessor } = useChart();

  useEffect(() => {
    if (!selection?.active) {
      onSelectionChange(null);
      return;
    }

    const startPoint = data[selection.startIndex];
    const endPoint = data[selection.endIndex];
    onSelectionChange({ startPoint, endPoint });
  }, [selection, data, xAccessor, onSelectionChange]);

  return null;
}
```

### SegmentBackground

| Prop   | Type     | Default                           | Description                        |
| ------ | -------- | --------------------------------- | ---------------------------------- |
| `fill` | `string` | `var(--chart-segment-background)` | Fill color for the selected region |

### SegmentLineFrom / SegmentLineTo

| Prop          | Type                                | Default                     | Description |
| ------------- | ----------------------------------- | --------------------------- | ----------- |
| `stroke`      | `string`                            | `var(--chart-segment-line)` | Line color  |
| `strokeWidth` | `number`                            | `1`                         | Line width  |
| `variant`     | `"dashed" \| "solid" \| "gradient"` | `"dashed"`                  | Line style  |

## Theming

The Area Chart uses the same CSS variables as the Line Chart:

```css
:root {
  --chart-background: oklch(1 0 0);
  --chart-foreground: oklch(0.145 0.004 285);
  --chart-foreground-muted: oklch(0.55 0.014 260);
  --chart-line-primary: oklch(0.623 0.214 255);
  --chart-line-secondary: oklch(0.705 0.015 265);
  --chart-crosshair: oklch(0.4 0.1828 274.34);
  --chart-grid: oklch(0.9 0 0);
  --chart-tooltip-foreground: oklch(0.985 0 0);
  --chart-tooltip-muted: oklch(0.65 0.01 260);
  --chart-marker-background: oklch(0.97 0.005 260);
  --chart-marker-border: oklch(0.85 0.01 260);
  --chart-marker-foreground: oklch(0.3 0.01 260);
  --chart-marker-badge-background: oklch(0 0 0);
  --chart-marker-badge-foreground: oklch(1 0 0);
  --chart-segment-background: oklch(0.5 0 0 / 0.06);
  --chart-segment-line: oklch(0.5 0 0 / 0.25);
}

.dark {
  --chart-background: oklch(0.145 0 0);
  --chart-foreground: oklch(0.45 0 0);
  --chart-crosshair: oklch(0.45 0 0);
  --chart-grid: oklch(0.25 0 0);
  --chart-marker-background: oklch(0.25 0.01 260);
  --chart-marker-border: oklch(0.4 0.01 260);
  --chart-marker-foreground: oklch(0.9 0 0);
  --chart-marker-badge-background: oklch(1 0 0);
  --chart-marker-badge-foreground: oklch(0.15 0 0);
  --chart-segment-background: oklch(1 0 0 / 0.06);
  --chart-segment-line: oklch(1 0 0 / 0.25);
}
```

## Dependencies

This component requires the same packages as the Line Chart:

```bash
pnpm add @visx/shape @visx/curve @visx/scale @visx/gradient @visx/responsive @visx/event @visx/grid d3-array motion react-use-measure
```

---

# Aspect Ratio

> Displays content within a desired ratio.

Source: https://ui.cortexcn.dev/docs/components/aspect-ratio

## Installation

```bash
npx shadcn@latest add @cortexcn/aspect-ratio
```

## Usage

```tsx
import { AspectRatio } from "@/components/aspect-ratio";
```

## Examples

### 16:9

### 21:9

### 1:1

### 9:16

---

# Avatar

> An image element with a fallback for representing the user.

Source: https://ui.cortexcn.dev/docs/components/avatar

## Installation

```bash
npx shadcn@latest add @cortexcn/avatar
```

## Usage

```tsx
import { Avatar, AvatarImage, AvatarFallback, AvatarGroup, AvatarGroupCount, AvatarBadge } from "@/components/avatar";
```

## Examples

### Sizes

### Badge

### Badge with icon

### Group

### Group with count

### Group with icon count

### In empty

---

# Badge

> Displays a badge or a component that looks like a badge.

Source: https://ui.cortexcn.dev/docs/components/badge

## Installation

```bash
npx shadcn@latest add @cortexcn/badge
```

## Usage

```tsx
import { Badge, badgeVariants } from "@/components/badge";
```

## Examples

### Variants

### Icon left

### Icon right

### With spinner

### asChild

### Long text

### Custom colors

---

# Bar Chart

> A composable bar chart with spring animations, stacked bars, horizontal orientation, and grouped series support

Source: https://ui.cortexcn.dev/docs/components/bar-chart

## Installation

```bash
npx shadcn@latest add @cortexcn/bar-chart
```

## Usage

The Bar Chart uses the same composable API as the Line and Area charts. Build charts by combining components:

```tsx
import {
  BarChart,
  Bar,
  BarXAxis,
  Grid,
  ChartTooltip,
} from "@/components/charts";

const data = [
  { month: "Jan", revenue: 12000, profit: 4500 },
  { month: "Feb", revenue: 15500, profit: 5200 },
  // ... more data
];

export default function RevenueChart() {
  return (
    <BarChart data={data} xDataKey="month">
      <Grid horizontal />
      <Bar dataKey="revenue" fill="var(--chart-line-primary)" lineCap="round" />
      <Bar
        dataKey="profit"
        fill="var(--chart-line-secondary)"
        lineCap="round"
      />
      <BarXAxis />
      <ChartTooltip />
    </BarChart>
  );
}
```

See the [charts gallery](https://ui.cortexcn.dev/charts/bar-chart) for stacked bars, horizontal layouts, gradients, patterns, the **Shape** square-column variant, and more.

## Components

### BarChart

The root component that provides context to all children.

| Prop                | Type                                                      | Default                                        | Description                                                      |
| ------------------- | --------------------------------------------------------- | ---------------------------------------------- | ---------------------------------------------------------------- |
| `data`              | `Record<string, unknown>[]`                               | required                                       | Array of data points                                             |
| `xDataKey`          | `string`                                                  | `"name"`                                       | Key in data for categorical axis values                          |
| `margin`            | `Partial<Margin>`                                         | `{ top: 40, right: 40, bottom: 40, left: 40 }` | Chart margins                                                    |
| `animationDuration` | `number`                                                  | `1100`                                         | Animation duration in ms                                         |
| `aspectRatio`       | `string`                                                  | `"2 / 1"`                                      | CSS aspect ratio                                                 |
| `barGap`            | `number`                                                  | `0.2`                                          | Gap between bar groups (0-1 fraction of band width)              |
| `barWidth`          | `number`                                                  | -                                              | Fixed bar width in pixels (auto-sizes if not set)                |
| `orientation`       | `"vertical" \| "horizontal"`                              | `"vertical"`                                   | Bar chart orientation                                            |
| `stacked`           | `boolean`                                                 | `false`                                        | Stack bars instead of grouping them                              |
| `stackGap`          | `number`                                                  | `0`                                            | Gap between stacked bar segments in pixels                       |
| `squareSnap`        | `{ squareGap: number; groupGap?: number; fit?: boolean }` | —                                              | Enables square-column tooltip snapping when using `<BarSquares>` |
| `className`         | `string`                                                  | `""`                                           | Additional CSS class                                             |

### Bar

Renders a bar for each data point with configurable styling and animations.

| Prop            | Type                          | Default                     | Description                                                                                                                                                                                        |
| --------------- | ----------------------------- | --------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `dataKey`       | `string`                      | required                    | Key in data for values                                                                                                                                                                             |
| `yAxisId`       | `string \| number`            | `"left"`                    | Y-scale group for vertical biaxial charts (pair with `YAxis`)                                                                                                                                      |
| `fill`          | `string`                      | `var(--chart-line-primary)` | Bar fill color (can be gradient/pattern url)                                                                                                                                                       |
| `stroke`        | `string`                      | -                           | Tooltip dot color. Use when fill is a gradient/pattern                                                                                                                                             |
| `lineCap`       | `"round" \| "butt" \| number` | `"round"`                   | Bar end cap style or custom radius                                                                                                                                                                 |
| `animate`       | `boolean`                     | `true`                      | Enable animation                                                                                                                                                                                   |
| `animationType` | `"grow" \| "fade"`            | `"grow"`                    | Animation style                                                                                                                                                                                    |
| `fadedOpacity`  | `number`                      | `0.3`                       | Opacity when another bar is hovered                                                                                                                                                                |
| `staggerDelay`  | `number`                      | auto                        | Delay between bars (auto-calculated based on bar count)                                                                                                                                            |
| `stackGap`      | `number`                      | `0`                         | Gap between stacked bars in pixels                                                                                                                                                                 |
| `perspective`   | `boolean`                     | `false`                     | Make this a 3D depth bar: trims the front-face top to meet the lid and forces a flat top. Pass `true` when pairing with `BarDepthBack`/`BarDepthFront` (see [3D Depth](#3d-depth--glass-surfaces)) |
| `minBarHeight`  | `number`                      | `0`                         | Minimum rendered height in px (non-stacked, vertical) — floors short/zero bars so they stay visible. Pair with `<BarDepthProvider minBarHeight>`                                                   |

### BarSquares

Renders a **Shape** bar as a vertical stack of discrete squares instead of a continuous `<Bar>`. Use one `<BarSquares>` per series (grouped, vertical charts only). Squares cascade upward on enter; supports solid fills, bar-spanning gradients, and pattern presets.

| Prop            | Type                                  | Default                     | Description                                          |
| --------------- | ------------------------------------- | --------------------------- | ---------------------------------------------------- |
| `dataKey`       | `string`                              | required                    | Key in data for values                               |
| `yAxisId`       | `string \| number`                    | series default              | Y-scale group for biaxial charts                     |
| `fill`          | `string`                              | `var(--chart-line-primary)` | Solid color or pattern `url(#…)`                     |
| `stroke`        | `string`                              | —                           | Tooltip ring/dot color when fill is gradient/pattern |
| `squareGap`     | `number`                              | `3`                         | Gap between stacked squares in pixels                |
| `squareRadius`  | `number`                              | `0.25`                      | Corner radius as a fraction of square size (0–0.5)   |
| `squareFit`     | `boolean`                             | `false`                     | Redistribute gap so columns fit bar height exactly   |
| `useGradient`   | `boolean`                             | `false`                     | Apply a bar-spanning gradient from `gradientStops`   |
| `gradientStops` | `{ offset: number; color: string }[]` | —                           | Gradient stops (0–100) when `useGradient` is true    |
| `patternPreset` | pattern preset id                     | —                           | Pattern preset when `fill` is a pattern url          |
| `groupGap`      | `number`                              | `4`                         | Gap between grouped series columns in pixels         |
| `fadedOpacity`  | `number`                              | `0.3`                       | Opacity when another bar is hovered                  |
| `animate`       | `boolean`                             | `true`                      | Enable enter animation                               |
| `staggerDelay`  | `number`                              | auto                        | Override per-column stagger delay                    |

Pass **`squareSnap`** on `<BarChart>` with the same `squareGap`, `groupGap`, and `squareFit` so tooltip ring indicators align with square columns:

```tsx
<BarChart
  data={data}
  xDataKey="month"
  squareSnap={{ squareGap: 3, groupGap: 4 }}
>
  <BarSquares
    dataKey="desktop"
    fill="url(#desktop-pattern)"
    stroke="var(--chart-5)"
    squareGap={3}
    groupGap={4}
  />
  <BarSquares
    dataKey="mobile"
    fill="var(--chart-1)"
    useGradient
    gradientStops={[
      { offset: 0, color: "var(--chart-1)" },
      { offset: 25, color: "var(--chart-2)" },
      { offset: 50, color: "var(--chart-3)" },
      { offset: 75, color: "var(--chart-4)" },
      { offset: 100, color: "var(--chart-5)" },
    ]}
    stroke="var(--chart-5)"
    squareGap={3}
    groupGap={4}
  />
  <BarXAxis />
  <ChartTooltip showCrosshair={false} dotVariant="ring" dotScale={1.05} />
</BarChart>
```

See the **Shape & Gradient** and **Shape Squircle Ring** examples on the [bar chart gallery](https://ui.cortexcn.dev/charts/bar-chart).

### BarColumnTrack

Optional underlay for Shape bars: patterned or solid fill in the **empty space above** each square column (not behind the bars). Place before `<BarSquares>`.

| Prop           | Type      | Default             | Description                       |
| -------------- | --------- | ------------------- | --------------------------------- |
| `fill`         | `string`  | `var(--chart-grid)` | Solid color or pattern `url(#…)`  |
| `opacity`      | `number`  | `0.3`               | Track opacity                     |
| `squareGap`    | `number`  | `3`                 | Match `<BarSquares squareGap>`    |
| `squareRadius` | `number`  | `0.25`              | Match `<BarSquares squareRadius>` |
| `squareFit`    | `boolean` | `false`             | Match `<BarSquares squareFit>`    |
| `groupGap`     | `number`  | `4`                 | Match `<BarSquares groupGap>`     |

Tracks animate from full column height on enter and shrink in sync as squares stack upward.

### BarXAxis

Displays categorical labels along the x-axis (for vertical bar charts).

| Prop              | Type      | Default | Description                          |
| ----------------- | --------- | ------- | ------------------------------------ |
| `tickerHalfWidth` | `number`  | `50`    | Width of ticker for fade calculation |
| `showAllLabels`   | `boolean` | `false` | Show all labels (may crowd)          |
| `maxLabels`       | `number`  | `12`    | Maximum labels to show               |

### BarYAxis

Displays categorical labels along the y-axis (for horizontal bar charts).

| Prop            | Type      | Default | Description            |
| --------------- | --------- | ------- | ---------------------- |
| `showAllLabels` | `boolean` | `true`  | Show all labels        |
| `maxLabels`     | `number`  | `20`    | Maximum labels to show |

### Grid

The Grid component now supports `fadeVertical` for vertical grid lines.

| Prop             | Type      | Default | Description                               |
| ---------------- | --------- | ------- | ----------------------------------------- |
| `horizontal`     | `boolean` | `true`  | Show horizontal grid lines                |
| `vertical`       | `boolean` | `false` | Show vertical grid lines                  |
| `fadeHorizontal` | `boolean` | `true`  | Fade horizontal lines at left/right edges |
| `fadeVertical`   | `boolean` | `false` | Fade vertical lines at top/bottom edges   |

### Background

Pattern fill for the plot area when you omit `Grid`. See the [Background utility](https://ui.cortexcn.dev/docs/utility/background) and **Pattern Background** examples on the [bar chart gallery](https://ui.cortexcn.dev/charts/bar-chart).

### BarDepthBack

Renders the 3D side + top faces. Place **before** `<Bar>` so the bar's front face occludes depth that would extend into the next column.

| Prop            | Type                       | Default                     | Description                                                       |
| --------------- | -------------------------- | --------------------------- | ----------------------------------------------------------------- |
| `dataKey`       | `string`                   | required                    | Key in data for the bar value (match the sibling `<Bar dataKey>`) |
| `color`         | `string`                   | `var(--chart-line-primary)` | Solid color for the side + top faces                              |
| `colorAccessor` | `(datum, index) => string` | -                           | Per-bar color override; takes precedence over `color`             |

### BarDepthFront

Renders the glossy glass sheen over the bar's fill. Place **after** `<Bar>`.

| Prop      | Type     | Default  | Description                                                       |
| --------- | -------- | -------- | ----------------------------------------------------------------- |
| `dataKey` | `string` | required | Key in data for the bar value (match the sibling `<Bar dataKey>`) |

### BarPulse

Optional looping vertical sweep over a single active bar (e.g. a live value). Place **after** `<BarDepthFront>`.

| Prop          | Type      | Default  | Description                                           |
| ------------- | --------- | -------- | ----------------------------------------------------- |
| `dataKey`     | `string`  | required | Key in data for the bar value                         |
| `activeIndex` | `number`  | -        | Index (in the data array) of the bar to pulse         |
| `pulsePaused` | `boolean` | `false`  | Freeze the sweep while keeping the 3D/glass treatment |

### BarDepthProvider

Optional wrapper supplying shared depth config to every layer beneath it. Wrap it **around** `<BarChart>`, not inside it. Use it to split **stacked** bars (`segmentsAccessor`) and/or tune the baseline contact shadow (`groundShadow`).

| Prop               | Type                                            | Default | Description                                                                                                                    |
| ------------------ | ----------------------------------------------- | ------- | ------------------------------------------------------------------------------------------------------------------------------ |
| `segmentsAccessor` | `(datum) => { value: number; color: string }[]` | -       | Stacked segments (bottom→top) for each datum                                                                                   |
| `groundShadow`     | `number`                                        | `0.26`  | Opacity (0–1) of the dark "contact shadow" that grounds each bar at the baseline. Set `0` to remove it (e.g. on bright fills). |
| `minBarHeight`     | `number`                                        | `0`     | Floors short/zero bars to a min px height so they stay visible. Pass the **same** value to `<Bar minBarHeight>`.               |

## 3D Depth & Glass Surfaces

Give bars a head-on 3D perspective and a glass-block sheen by layering `BarDepthBack` (side + top faces, before `Bar`) and `BarDepthFront` (front glass, after `Bar`). The layers read geometry from the chart context, so the only required prop is the matching `dataKey`.

Add **`perspective`** to the `Bar` and you're done — it shrinks the front face's top so the lid sits flush on the bar (instead of floating above it) and forces a flat top so the lid meets it with no gap. **Always pass it when using the depth layers.**

```tsx
import {
  BarChart,
  Bar,
  BarDepthBack,
  BarDepthFront,
  BarXAxis,
  Grid,
  ChartTooltip,
} from "@/components/charts";

<BarChart data={data} xDataKey="month">
  <Grid horizontal />
  <BarDepthBack dataKey="revenue" color="var(--chart-1)" />
  <Bar dataKey="revenue" fill="var(--chart-1)" perspective />
  <BarDepthFront dataKey="revenue" />
  <BarXAxis />
  <ChartTooltip />
</BarChart>;
```

### Custom indicator (optional)

The [3D Depth gallery example](https://ui.cortexcn.dev/charts/bar-chart) pairs depth bars with a rising line indicator. Disable the default crosshair and dots on `ChartTooltip`, then render your own overlay via `useChart` and a portal — see [Custom Indicator](https://ui.cortexcn.dev/docs/utility/custom-indicator).

Color bars individually with `colorAccessor`:

```tsx
<BarDepthBack
  dataKey="revenue"
  colorAccessor={(d) =>
    (d.revenue as number) >= 15000 ? "var(--chart-1)" : "var(--chart-3)"
  }
/>
```

Highlight a live / in-progress bar with `BarPulse` (render it after `BarDepthFront`):

```tsx
<BarPulse dataKey="revenue" activeIndex={data.length - 1} />
```

### Stacked bars (multiple data sources)

To give a **stacked** bar 3D depth, wrap the chart in `BarDepthProvider` with a `segmentsAccessor` returning one `{ value, color }` per data source (bottom→top). The side face splits into a matching parallelogram per segment, and the lid takes the topmost segment's color. The depth's height is the **sum of the segments**, so you don't need a separate total column — just stack a `<Bar>` per source (each with `perspective`) in the same order:

```tsx
<BarDepthProvider
  segmentsAccessor={(d) => [
    { value: d.desktop as number, color: "var(--chart-1)" },
    { value: d.mobile as number, color: "var(--chart-3)" },
  ]}
>
  <BarChart data={data} xDataKey="month" stacked>
    <BarDepthBack dataKey="desktop" />
    <Bar dataKey="desktop" fill="var(--chart-1)" perspective />
    <Bar dataKey="mobile" fill="var(--chart-3)" perspective />
    <BarDepthFront dataKey="desktop" />
    <BarXAxis />
    <ChartTooltip showCrosshair={false} showDots={false} />
  </BarChart>
</BarDepthProvider>
```

Each bar gets a subtle dark "contact shadow" at the baseline so it reads as sitting on the axis. Tune or remove it with `groundShadow` on the provider (it reads strongest over bright fills):

```tsx
<BarDepthProvider groundShadow={0.12}>
  {/* ...BarChart with depth layers... */}
</BarDepthProvider>
```

To keep **zero or very short** bars visible as a tiny bar instead of vanishing, set `minBarHeight` on **both** the `<Bar>` (floors the front face) and `<BarDepthProvider>` (floors the 3D surfaces) — they must match:

```tsx
<BarDepthProvider minBarHeight={6}>
  <BarChart data={data} xDataKey="month">
    <BarDepthBack dataKey="value" color="var(--chart-1)" />
    <Bar dataKey="value" fill="var(--chart-1)" perspective minBarHeight={6} />
    <BarDepthFront dataKey="value" />
  </BarChart>
</BarDepthProvider>
```

Negative values are supported (bars grow downward from the baseline) as long as the chart's value scale includes negatives. See the [charts gallery](https://ui.cortexcn.dev/charts/bar-chart) for a live 3D depth example.

## Loading state

`BarChart` accepts a `status` prop. While `status="loading"`, it replaces the bars with a shimmer skeleton: placeholder bars with a soft diagonal shimmer sweeping across them on a loop. On `status="ready"` it switches to the real bars. No chart data is required during loading. Bar heights come from a deterministic seed (SSR-safe, no `Math.random()`), and it respects `prefers-reduced-motion` by rendering a calm, static skeleton.

<div className="not-prose mb-3 flex items-center justify-between gap-4">
  <h3 className="m-0 font-semibold text-foreground text-base tracking-tight">
    Preview
  </h3>
</div>

Toggle **Loading** / **Ready** in the preview to swap the shimmer skeleton for the real bars.

```tsx
import { BarChart, Bar, BarXAxis } from "@/components/charts";

function RevenueChart({ data, isLoading }) {
  return (
    <BarChart
      data={data}
      xDataKey="month"
      status={isLoading ? "loading" : "ready"}
    >
      <Bar dataKey="revenue" />
      <BarXAxis />
    </BarChart>
  );
}
```

For the common "render a placeholder until data arrives" case, `BarChartLoading` is a turnkey shortcut for `<BarChart status="loading" />`:

```tsx
import { BarChartLoading } from "@/components/charts";

<BarChartLoading />;
```

| Prop          | Type                   | Default   | Description                                           |
| ------------- | ---------------------- | --------- | ----------------------------------------------------- |
| `status`      | `"loading" \| "ready"` | `"ready"` | On `BarChart`. `"loading"` shows the shimmer skeleton |
| `margin`      | `Partial<Margin>`      | -         | On `BarChartLoading`. Chart margins                   |
| `aspectRatio` | `string`               | `"2 / 1"` | On `BarChartLoading`. Container aspect ratio          |
| `className`   | `string`               | -         | On `BarChartLoading`. Additional container class      |

## Animation

Bars animate with the same easing as Line charts (`cubic-bezier(0.85, 0, 0.15, 1)`) for a smooth, organic feel. The stagger delay is automatically calculated based on the number of bars to ensure all animations complete within the total animation duration (~1.2s).

### Grow Animation (Default)

Bars grow from zero to their final size:

```tsx
<Bar dataKey="revenue" animationType="grow" />
```

### Fade Animation

Bars fade in with a blur effect:

```tsx
<Bar dataKey="revenue" animationType="fade" />
```

### Custom Stagger

Stagger is calculated automatically, but you can override it:

```tsx
// Override automatic stagger with custom delay
<Bar dataKey="revenue" staggerDelay={0.02} />

// No stagger (all bars animate together)
<Bar dataKey="revenue" staggerDelay={0} />
```

## Line Cap Styles

Control the bar end style:

```tsx
// Rounded caps (default) - full rounding
<Bar dataKey="revenue" lineCap="round" />

// Square caps - no rounding
<Bar dataKey="revenue" lineCap="butt" />

// Custom radius in pixels
<Bar dataKey="revenue" lineCap={4} />
<Bar dataKey="revenue" lineCap={8} />
```

## Theming

The Bar Chart uses the same CSS variables as other charts:

```css
:root {
  --chart-background: oklch(1 0 0);
  --chart-foreground: oklch(0.145 0.004 285);
  --chart-foreground-muted: oklch(0.55 0.014 260);
  --chart-line-primary: oklch(0.623 0.214 255);
  --chart-line-secondary: oklch(0.705 0.015 265);
  --chart-crosshair: oklch(0.4 0.1828 274.34);
  --chart-grid: oklch(0.9 0 0);
}

.dark {
  --chart-background: oklch(0.145 0 0);
  --chart-foreground: oklch(0.45 0 0);
  --chart-crosshair: oklch(0.45 0 0);
  --chart-grid: oklch(0.25 0 0);
}
```

## Dependencies

This component requires the same packages as the other charts:

```bash
pnpm add @visx/shape @visx/scale @visx/responsive @visx/event @visx/grid d3-array motion react-use-measure
```

---

# Breadcrumb

> Displays the path to the current resource using a hierarchy of links.

Source: https://ui.cortexcn.dev/docs/components/breadcrumb

## Installation

```bash
npx shadcn@latest add @cortexcn/breadcrumb
```

## Usage

```tsx
import { Breadcrumb, BreadcrumbList, BreadcrumbItem, BreadcrumbLink, BreadcrumbPage, BreadcrumbSeparator, BreadcrumbEllipsis } from "@/components/breadcrumb";
```

## Examples

### Basic

### With dropdown

### With link

---

# Button

> Displays a button or a component that looks like a button.

Source: https://ui.cortexcn.dev/docs/components/button

## Installation

```bash
npx shadcn@latest add @cortexcn/button
```

## Usage

```tsx
import { Button, buttonVariants } from "@/components/button";
```

## Examples

### Variants and sizes

### Icon right

### Icon left

### Icon only

### Invalid states

### Examples

---

# Button Group

> A container that groups related buttons together with consistent styling.

Source: https://ui.cortexcn.dev/docs/components/button-group

## Installation

```bash
npx shadcn@latest add @cortexcn/button-group
```

## Usage

```tsx
import { ButtonGroup, ButtonGroupSeparator, ButtonGroupText, buttonGroupVariants } from "@/components/button-group";
```

## Examples

### Basic

### With input

### With text

### With dropdown

### With select

### With icons

### With input group

### With fields

### With like

### With select and input

### Nested

### Pagination

### Pagination split

### Navigation

### Text alignment

### Vertical

### Vertical nested

---

# Calendar

> A date field component that allows users to enter and edit dates.

Source: https://ui.cortexcn.dev/docs/components/calendar

## Installation

```bash
npx shadcn@latest add @cortexcn/calendar
```

## Usage

```tsx
import { Calendar, CalendarDayButton } from "@/components/calendar";
```

## Examples

### Single

### Multiple

### Week numbers

### Booked dates

### Range

### Range multiple months

### With time

### With presets

### Custom days

### Date picker simple

### Date picker with dropdowns

### Date picker range

### In card

### In popover

---

# Candlestick Chart

> A composable OHLC candlestick chart with gradients, patterns, tooltips, and hover interactions

Source: https://ui.cortexcn.dev/docs/components/candlestick-chart

## Installation

```bash
npx shadcn@latest add @cortexcn/candlestick-chart
```

## Usage

The Candlestick Chart uses the same composable API as the Line and Area charts. Provide OHLC data and compose Grid, Candlestick, ChartTooltip, and XAxis.

### Basic Example

```tsx
import {
  CandlestickChart,
  Candlestick,
  Grid,
  ChartTooltip,
  XAxis,
} from "@/components/charts";

const ohlcData = [
  { date: new Date("2025-01-01"), open: 100, high: 108, low: 96, close: 104 },
  { date: new Date("2025-01-02"), open: 104, high: 112, low: 101, close: 109 },
  // ... more OHLC points
];

function OHLCChart() {
  return (
    <CandlestickChart
      data={ohlcData}
      margin={{ top: 16, right: 16, bottom: 40, left: 16 }}
      style={{ height: 320 }}
    >
      <Grid horizontal />
      <Candlestick fadedOpacity={0.25} />
      <ChartTooltip content={MyOHLCTooltipContent} />
      <XAxis />
    </CandlestickChart>
  );
}
```

### Data shape

Each point must have `date`, `open`, `high`, `low`, and `close`:

```ts
interface OHLCDataPoint {
  date: Date;
  open: number;
  high: number;
  low: number;
  close: number;
}
```

### Styling candles

The default fill uses the chart palette: `--chart-1` (positive) and `--chart-5` (negative). Override with `positiveFill` and `negativeFill` for gradients or solid colors (e.g. `var(--color-emerald-500)` for up, `var(--color-red-500)` for down). Use `bodyPatternPositive` and `bodyPatternNegative` with `url(#pattern-id)` for pattern fills. Control spacing with `candleGap` (0–1) or fixed `candleWidth` in pixels.

### Tooltip

Pass a custom `content` renderer to `ChartTooltip` that receives `{ point, index }` to show OHLC fields. Use `showCrosshair={false}` and `showDots={false}` for tooltip-only (no crosshair or dot).

### Background

Use [`Background`](https://ui.cortexcn.dev/docs/utility/background) instead of `Grid` for a pattern fill behind candles. See **Pattern Background** examples on the [candlestick chart gallery](https://ui.cortexcn.dev/charts/candlestick-chart).

---

# Card

> Displays a card with a header, content, and footer.

Source: https://ui.cortexcn.dev/docs/components/card

## Installation

```bash
npx shadcn@latest add @cortexcn/card
```

## Usage

```tsx
import {
  Card,
  CardAction,
  CardContent,
  CardDescription,
  CardFooter,
  CardHeader,
  CardTitle,
} from "@/components/card";
```

```tsx
<Card>
  <CardHeader>
    <CardTitle>Card Title</CardTitle>
    <CardDescription>Card Description</CardDescription>
    <CardAction>Card Action</CardAction>
  </CardHeader>
  <CardContent>
    <p>Card Content</p>
  </CardContent>
  <CardFooter>
    <p>Card Footer</p>
  </CardFooter>
</Card>
```

## Composition

Use the following composition to build a `Card`:

```text
Card
├── CardHeader
│   ├── CardTitle
│   ├── CardDescription
│   └── CardAction
├── CardContent
└── CardFooter
```

## Examples

### Login

A card with an action in the header, a form in the content, and buttons in the footer.

### Size

Use `size="sm"` to make the card small. The small size uses tighter spacing.

### Spacing

Besides the `size` prop, the `--card-spacing` CSS variable controls the gap between sections and the inset of every card part.

### Edge to edge

Use negative margins with `-mx-(--card-spacing)` to take content edge to edge while keeping it aligned with the card inset. When that content sits above a footer, add `-mb-(--card-spacing)` to `CardContent` to remove the section gap.

### Image

Put an image before the card header to create a card with a cover image.

## API Reference

### Card

The root container for the card content.

| Prop        | Type                | Default     |
| ----------- | ------------------- | ----------- |
| `size`      | `"default" \| "sm"` | `"default"` |
| `className` | `string`            | -           |

### CardHeader

Holds the title, description, and an optional action.

| Prop        | Type     | Default |
| ----------- | -------- | ------- |
| `className` | `string` | -       |

### CardTitle

The card title.

| Prop        | Type     | Default |
| ----------- | -------- | ------- |
| `className` | `string` | -       |

### CardDescription

Helper text under the title.

| Prop        | Type     | Default |
| ----------- | -------- | ------- |
| `className` | `string` | -       |

### CardAction

Places content in the top-right of the header, such as a button or a badge.

| Prop        | Type     | Default |
| ----------- | -------- | ------- |
| `className` | `string` | -       |

### CardContent

The main card body.

| Prop        | Type     | Default |
| ----------- | -------- | ------- |
| `className` | `string` | -       |

### CardFooter

Actions and secondary content at the bottom of the card.

| Prop        | Type     | Default |
| ----------- | -------- | ------- |
| `className` | `string` | -       |

---

# Carousel

> A carousel with motion and swipe built using Embla.

Source: https://ui.cortexcn.dev/docs/components/carousel

## Installation

```bash
npx shadcn@latest add @cortexcn/carousel
```

## Usage

```tsx
import { type CarouselApi, Carousel, CarouselContent, CarouselItem, CarouselPrevious, CarouselNext, useCarousel } from "@/components/carousel";
```

## Examples

### Basic

### Multiple

### With gap

---

# Checkbox

> A control that allows the user to toggle between checked and not checked.

Source: https://ui.cortexcn.dev/docs/components/checkbox

## Installation

```bash
npx shadcn@latest add @cortexcn/checkbox
```

## Usage

```tsx
import { Checkbox } from "@/components/checkbox";
```

## Examples

### Basic

### With description

### Invalid

### Disabled

### With title

### In table

### Group

---

# Choropleth Chart

> A composable geographic map chart for visualizing data across regions with interactive tooltips, zoom controls, and pattern support

Source: https://ui.cortexcn.dev/docs/components/choropleth-chart

## Installation

```bash
npx shadcn@latest add @cortexcn/choropleth-chart
```

## Usage

The Choropleth Chart uses a composable API similar to other charts. Build maps by combining components:

```tsx
import {
  ChoroplethChart,
  ChoroplethFeatureComponent,
  ChoroplethGraticule,
  ChoroplethTooltip,
} from "@/components/charts";
import * as topojson from "topojson-client";

// Load your GeoJSON data (from TopoJSON or direct GeoJSON)
const geojson = topojson.feature(topology, topology.objects.countries);

export default function WorldMap() {
  return (
    <ChoroplethChart data={geojson} aspectRatio="16 / 9">
      <ChoroplethGraticule />
      <ChoroplethFeatureComponent fill="var(--chart-scale-03)" />
      <ChoroplethTooltip />
    </ChoroplethChart>
  );
}
```

## Components

### ChoroplethChart

The root component that sets up the Mercator projection and provides context to children.

| Prop                | Type                | Default                                    | Description                                              |
| ------------------- | ------------------- | ------------------------------------------ | -------------------------------------------------------- |
| `data`              | `FeatureCollection` | required                                   | GeoJSON FeatureCollection with geographic features       |
| `margin`            | `Partial<Margin>`   | `{ top: 0, right: 0, bottom: 0, left: 0 }` | Chart margins                                            |
| `animationDuration` | `number`            | `800`                                      | Animation duration in ms                                 |
| `aspectRatio`       | `string`            | `"16 / 9"`                                 | CSS aspect ratio                                         |
| `scale`             | `number`            | auto                                       | Projection scale (auto-calculated from width if not set) |
| `center`            | `[number, number]`  | `[0, 20]`                                  | Center coordinates [longitude, latitude]                 |
| `translate`         | `[number, number]`  | auto                                       | Translate offset [x, y]                                  |
| `zoomEnabled`       | `boolean`           | `false`                                    | Enable zoom and pan interactions                         |
| `zoomMin`           | `number`            | `0.5`                                      | Minimum zoom scale                                       |
| `zoomMax`           | `number`            | `4`                                        | Maximum zoom scale                                       |
| `initialZoom`       | `TransformMatrix`   | identity                                   | Initial zoom transform                                   |
| `className`         | `string`            | `""`                                       | Additional CSS class                                     |

### ChoroplethFeatureComponent

Renders the geographic feature paths with hover states and optional patterns.

| Prop                | Type                                 | Default               | Description                                             |
| ------------------- | ------------------------------------ | --------------------- | ------------------------------------------------------- |
| `fill`              | `string`                             | -                     | Fill color for all features (overrides getFeatureColor) |
| `stroke`            | `string`                             | `"var(--chart-grid)"` | Stroke color for borders                                |
| `strokeWidth`       | `number`                             | `0.5`                 | Border stroke width                                     |
| `fadedOpacity`      | `number`                             | `0.4`                 | Opacity when another feature is hovered                 |
| `getFeatureColor`   | `(feature, index) => string`         | -                     | Custom color function                                   |
| `patterns`          | `ReactNode`                          | -                     | Pattern definitions using `@visx/pattern` components    |
| `getFeaturePattern` | `(feature, index) => string \| null` | -                     | Return pattern ID for a feature                         |

### ChoroplethGraticule

Renders optional graticule (latitude/longitude grid lines).

| Prop          | Type               | Default                   | Description                                          |
| ------------- | ------------------ | ------------------------- | ---------------------------------------------------- |
| `stroke`      | `string`           | `"rgba(255,255,255,0.1)"` | Line color                                           |
| `strokeWidth` | `number`           | `0.5`                     | Line width                                           |
| `step`        | `[number, number]` | `[10, 10]`                | Grid step intervals [longitude, latitude] in degrees |

### ChoroplethTooltip

Displays tooltips for features on hover, following the mouse position.

| Prop              | Type                         | Default          | Description              |
| ----------------- | ---------------------------- | ---------------- | ------------------------ |
| `content`         | `(props) => ReactNode`       | -                | Custom tooltip renderer  |
| `formatValue`     | `(value) => string`          | `toLocaleString` | Value formatter          |
| `getFeatureName`  | `(feature, index) => string` | -                | Custom name getter       |
| `getFeatureValue` | `(feature, index) => number` | -                | Value getter for display |
| `valueLabel`      | `string`                     | `"Value"`        | Label for the value row  |
| `className`       | `string`                     | `""`             | Additional CSS class     |

## Data Format

The choropleth expects a GeoJSON FeatureCollection:

```typescript
interface FeatureCollection {
  type: "FeatureCollection";
  features: Array<{
    type: "Feature";
    geometry: Geometry; // Polygon, MultiPolygon, etc.
    properties: {
      name?: string;
      id?: string | number;
      [key: string]: unknown;
    };
  }>;
}
```

For TopoJSON data, convert it using `topojson-client`:

```typescript
import * as topojson from "topojson-client";

const geojson = topojson.feature(topology, topology.objects.countries);
```

See the [charts gallery](https://ui.cortexcn.dev/charts/choropleth-chart) for analytics color scales, zoom controls, and pattern fills.

## Theming

For categorical maps, `defaultChoroplethColors` cycles through **`--chart-scale-01`** … **`--chart-scale-05`**. Pass `getFeatureColor` for custom bins (see gallery analytics demo). Empty / no-data regions typically use `var(--muted)`.

See [Theming](https://ui.cortexcn.dev/docs/theming) for the full sequential scale reference.

## Dependencies

This component requires:

```bash
pnpm add @visx/geo @visx/responsive @visx/pattern @visx/zoom topojson-client motion react-use-measure
```

---

# Collapsible

> An interactive component which expands and collapses a panel.

Source: https://ui.cortexcn.dev/docs/components/collapsible

## Installation

```bash
npx shadcn@latest add @cortexcn/collapsible
```

## Usage

```tsx
import { Collapsible, CollapsibleTrigger, CollapsibleContent } from "@/components/collapsible";
```

## Examples

### File tree

### Settings

---

# Combobox

> An input with a list of suggestions that filters as you type.

Source: https://ui.cortexcn.dev/docs/components/combobox

## Installation

```bash
npx shadcn@latest add @cortexcn/combobox
```

## Usage

```tsx
import { Combobox, ComboboxInput, ComboboxContent, ComboboxList, ComboboxItem, ComboboxGroup, ComboboxLabel, ComboboxCollection, ComboboxEmpty, ComboboxSeparator, ComboboxChips, ComboboxChip, ComboboxChipsInput, ComboboxTrigger, ComboboxValue, useComboboxAnchor } from "@/components/combobox";
```

## Examples

### Basic

### Disabled

### Invalid

### With clear button

### With auto highlight

### With groups

### With groups and separator

### Large list (100 items)

### With icon addon

### Combobox in popup

### Form with combobox

### Combobox multiple

### Combobox multiple disabled

### Combobox multiple invalid

### Combobox multiple (no remove)

### With custom item rendering

### Combobox in dialog

### With other inputs

### Disabled items

---

# Command

> A fast, composable command menu for React.

Source: https://ui.cortexcn.dev/docs/components/command

## Installation

```bash
npx shadcn@latest add @cortexcn/command
```

## Usage

```tsx
import { Command, CommandDialog, CommandInput, CommandList, CommandEmpty, CommandGroup, CommandItem, CommandShortcut, CommandSeparator } from "@/components/command";
```

## Examples

### Inline

### Basic

### With shortcuts

### With groups

### Many groups and items

---

# Command Search

> A command palette that types queries and live-filters grouped results, with keyboard navigation.

Source: https://ui.cortexcn.dev/docs/components/command-search

## Installation

```bash
npx shadcn@latest add @cortexcn/command-search
```

## Usage

```tsx
import { CommandSearch } from "@/components/command-search";
```

```tsx
<CommandSearch
  queries={["chart", "marquee"]}
  groups={[
    {
      label: "Components",
      items: [{ label: "Area Chart" }, { label: "Marquee" }],
    },
  ]}
  onSelect={(item) => console.log(item.label)}
/>
```

While it is on screen, the palette types each query in, filters the groups to matching rows, and highlights the match inside each label. Set `autoType={false}` and pass `query` to show a fixed search instead.

## Behavior

- The highlight follows the item under the pointer, or moves with the up and down arrow keys once the palette has focus. Enter calls `onSelect` with the highlighted item.
- The typing only runs while the palette is on screen. With reduced motion enabled, it shows the first query and stays still.
- Rows without an `icon` show an arrow. Pass any icon element to replace it.

## Props

| Prop          | Type                                | Default                     | Description                                        |
| ------------- | ----------------------------------- | --------------------------- | -------------------------------------------------- |
| `queries`     | `string[]`                          | Four sample queries         | Queries to type out and filter by                  |
| `autoType`    | `boolean`                           | `true`                      | Type the queries automatically                     |
| `query`       | `string`                            | `"anim"`                    | Fixed search text, used when `autoType` is `false` |
| `placeholder` | `string`                            | `"Search…"`                 | Shown while the field is empty                     |
| `groups`      | `CommandSearchGroup[]`              | Sample pages and components | Grouped results under the field                    |
| `onSelect`    | `(item: CommandSearchItem) => void` | -                           | Called when a row is clicked or chosen with Enter  |
| `height`      | `number`                            | `408`                       | Height of the palette in pixels                    |
| `className`   | `string`                            | -                           | Extra classes for the palette                      |

Adapted from the [Spectrum UI Command Search](https://ui.spectrumhq.in/docs/command-search) (Apache 2.0).

---

# Composed Chart

> Mix SeriesBar, Line, and Area on one shared time axis (Recharts ComposedChart–style)

Source: https://ui.cortexcn.dev/docs/components/composed-chart

## Installation

```bash
npx shadcn@latest add @cortexcn/composed-chart
```

## Usage

`ComposedChart` is the time-series shell for **mixing marks** on one `data` array and one pair of scales. Use **`SeriesBar`** for vertical columns aligned to dates (not the categorical `<Bar />` from `BarChart`, which uses a band scale).

- **`aspectRatio`** — wide charts (e.g. `4 / 1`) work for full-width heroes; in **narrow cards** use **`3 / 2`** or **`2 / 1`** so the plot stays tall enough to read.
- **`barSize`**, **`maxBarSize`**, **`barGap`** — parent-level layout for `SeriesBar` groups (similar to Recharts `ComposedChart` props). Use **`barGap={0}`** and a higher **`maxBarSize`** for dense daily data so columns read like the [90 days of data](https://ui.cortexcn.dev/docs/components/bar-chart#90-days-of-data) bar example.
- **`stacked`** / **`stackGap`** — stack `SeriesBar` segments in child order at each x (lines and areas are not stacked).
- **`SeriesBar`** — default **`radius` is 0** (square tops). Pass **`radius={4}`** (or similar) for rounded corners.
- **`Line`** / **`Area`** — pass a **`curve`** from `@visx/curve` (e.g. **`curveCatmullRom.alpha(0.42)`**) to soften paths when you have many daily points (preview + hero use the same curve for `revenue` and `runRate`).
- **`Line`** / **`Area`** — use **`showMarkers`** for scatter-style ring markers at each point; pass **`markers={{ radius, ringGap, strokeWidth }}`** to tune styling.
- **`Line`** / **`Area`** — use **`dashFromIndex`** and **`dashArray`** for a dashed tail on incomplete periods (the dashed segment follows the same curve and edge fade).
- **`XAxis`** — default ticks snap to data rows so the crosshair aligns. Tune **`numTicks`** for dense series (e.g. daily). Use **`tickMode="domain"`** only when you want calendar-even spacing instead of data alignment.
- **`ChartTooltip`** — for bar-heavy layouts, **`showCrosshair={false}`** often looks cleaner because the hover band is already vertical columns.
- **`YAxis`** / **`yAxisId`** — `Line` and `Area` support independent left/right scales (see [Y Axis](https://ui.cortexcn.dev/docs/utility/axis/y-axis)). `SeriesBar` uses the primary scale.
- **Hover dimming** — `SeriesBar` fades non-hovered columns using `tooltipData.index`, like grouped bars in `BarChart`. Tune with **`fadedOpacity`** on each `SeriesBar`.

### Basic example

```tsx
import {
  Area,
  ComposedChart,
  Grid,
  Line,
  SeriesBar,
  XAxis,
  ChartTooltip,
} from "@/components/charts";
import { curveCatmullRom } from "@visx/curve";
import { composedDemoData } from "@/lib/composed-demo-data";

const smooth = curveCatmullRom.alpha(0.42);

export default function Example() {
  return (
    <ComposedChart
      aspectRatio="2 / 1"
      barGap={0}
      data={composedDemoData}
      maxBarSize={32}
      xDataKey="date"
    >
      <Grid horizontal />
      <Area
        curve={smooth}
        dataKey="runRate"
        fill="var(--chart-4)"
        fillOpacity={0.32}
      />
      <SeriesBar dataKey="units" fill="var(--chart-3)" radius={4} />
      <Line curve={smooth} dataKey="revenue" stroke="var(--chart-1)" />
      <ChartTooltip showCrosshair={false} />
      <XAxis numTicks={8} />
    </ComposedChart>
  );
}
```

`composedDemoData` is 30 daily rows with ISO `date` strings, one slow wave across the month plus light ripples (kept readable next to dense bars). Outside this monorepo, copy the helpers from `apps/web/lib/composed-demo-data.ts` into your app.

See the [charts gallery](https://ui.cortexcn.dev/charts/composed-chart) for stacked bars, pattern fills, rounded bars, and more compositions.

### Background

Use [`Background`](https://ui.cortexcn.dev/docs/utility/background) instead of `Grid` for a pattern fill behind bars and lines. See **Pattern Background** examples on the [composed chart gallery](https://ui.cortexcn.dev/charts/composed-chart).

## See also

- [Line Chart](https://ui.cortexcn.dev/docs/components/line-chart) — lines only
- [Area Chart](https://ui.cortexcn.dev/docs/components/area-chart) — areas only
- [Bar Chart](https://ui.cortexcn.dev/docs/components/bar-chart) — categorical bars with `<Bar />`

---

# Context Menu

> Displays a menu of actions triggered by a right click.

Source: https://ui.cortexcn.dev/docs/components/context-menu

## Installation

```bash
npx shadcn@latest add @cortexcn/context-menu
```

## Usage

```tsx
import { ContextMenu, ContextMenuTrigger, ContextMenuContent, ContextMenuItem, ContextMenuCheckboxItem, ContextMenuRadioItem, ContextMenuLabel, ContextMenuSeparator, ContextMenuShortcut, ContextMenuGroup, ContextMenuPortal, ContextMenuSub, ContextMenuSubContent, ContextMenuSubTrigger, ContextMenuRadioGroup } from "@/components/context-menu";
```

## Examples

### Basic

### With sides

### With icons

### With shortcuts

### With submenu

### With groups, labels and separators

### With checkboxes

### With radio group

### With destructive items

### In dialog

### With inset

---

# Dialog

> A window overlaid on the page that renders the content underneath inert.

Source: https://ui.cortexcn.dev/docs/components/dialog

## Installation

```bash
npx shadcn@latest add @cortexcn/dialog
```

## Usage

```tsx
import { Dialog, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogOverlay, DialogPortal, DialogTitle, DialogTrigger } from "@/components/dialog";
```

## Examples

### With form

### Scrollable content

### With sticky footer

### No close button

### Chat settings

---

# Drawer

> A drawer component for React, built on Vaul.

Source: https://ui.cortexcn.dev/docs/components/drawer

## Installation

```bash
npx shadcn@latest add @cortexcn/drawer
```

## Usage

```tsx
import { Drawer, DrawerPortal, DrawerOverlay, DrawerTrigger, DrawerClose, DrawerContent, DrawerHeader, DrawerFooter, DrawerTitle, DrawerDescription } from "@/components/drawer";
```

## Examples

### Scrollable content

### Sides

---

# Dropdown Menu

> Displays a menu of actions or functions, triggered by a button.

Source: https://ui.cortexcn.dev/docs/components/dropdown-menu

## Installation

```bash
npx shadcn@latest add @cortexcn/dropdown-menu
```

## Usage

```tsx
import { DropdownMenu, DropdownMenuPortal, DropdownMenuTrigger, DropdownMenuContent, DropdownMenuGroup, DropdownMenuLabel, DropdownMenuItem, DropdownMenuCheckboxItem, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuSub, DropdownMenuSubTrigger, DropdownMenuSubContent } from "@/components/dropdown-menu";
```

## Examples

### Basic

### Complex

### With icons

### With shortcuts

### With submenu

### With checkboxes

### Checkboxes with icons

### With radio group

### Radio with icons

### With destructive items

### With avatar

### In dialog

### With inset

---

# Empty

> Displays an empty state, with media, a title, a description, and actions.

Source: https://ui.cortexcn.dev/docs/components/empty

## Installation

```bash
npx shadcn@latest add @cortexcn/empty
```

## Usage

```tsx
import { Empty, EmptyHeader, EmptyTitle, EmptyDescription, EmptyContent, EmptyMedia } from "@/components/empty";
```

## Examples

### Basic

### With muted background

### With border

### With icon

### With muted background alt

### In card

---

# Fan-Out Diagram

> An animated architecture diagram where one source feeds a hub that fans out to many nodes, each with a live status.

Source: https://ui.cortexcn.dev/docs/components/fan-out-diagram

## Installation

```bash
npx shadcn@latest add @cortexcn/fan-out-diagram
```

## Usage

```tsx
import { FanOutDiagram } from "@/components/fan-out-diagram";
import { AppWindow, Code, Terminal } from "lucide-react";
```

```tsx
<FanOutDiagram
  title="Agent platform"
  source={{ label: "Your app", icon: <AppWindow /> }}
  nodes={[
    { label: "Sandbox 1", meta: "Claude Code", icon: <Terminal />, status: "running" },
    { label: "Sandbox 2", meta: "Codex", icon: <Code />, status: "starting" },
  ]}
/>
```

A source card sends work to the hub, and the hub fans out to one row per node. Use it for the architecture section of a landing page, such as one sandbox per customer, one worker per queue, or one agent per task.

## Examples

### Job queue

Three rows are enough for a small system. A row's `statusLabel` replaces the status name, so an `error` row can say "retrying".

### Static

With `animated={false}`, the diagram draws in its final state, with no reveal and no moving packets.

## Behavior

- The first time the diagram scrolls into view, the panel, source, hub, lines and rows draw in, in that order. Then packets travel from the source to the hub and out along each line.
- Packets and the pulse on `running` rows only move while the diagram is on screen. With reduced motion enabled, the diagram shows its final state and nothing moves.
- The layout grows with the rows: one row per node, and the hub stays centred on them.
- It lays out left to right when its container is at least 36rem (576px) wide, and top to bottom below that: source on top, then the hub, then the rows. It follows its container, not the screen, so it also stacks inside a narrow column on a desktop.
- Icons are drawn in a 24 by 24 box. Any Lucide icon works, and so does an SVG `<image>` for a logo.
- Screen readers get one description of the whole diagram, built from the labels. Pass `ariaLabel` to write your own.

## Props

### FanOutDiagram

| Prop        | Type                                  | Default | Description                                         |
| ----------- | ------------------------------------- | ------- | --------------------------------------------------- |
| `title`     | `string`                              | -       | Label in the panel's top-left corner                |
| `titleIcon` | `ReactNode`                           | -       | Icon before the title                               |
| `source`    | `{ label: string; icon?: ReactNode }` | -       | The card that sends work in                         |
| `hubIcon`   | `ReactNode`                           | -       | Icon in the hub at the centre                       |
| `nodes`     | `FanOutNode[]`                        | -       | The rows the hub fans out to, top to bottom         |
| `animated`  | `boolean`                             | `true`  | Draw in on view and send packets along the lines    |
| `ariaLabel` | `string`                              | Built   | Description for screen readers                      |
| `className` | `string`                              | -       | Extra classes for the wrapper                       |

### FanOutNode

| Prop          | Type                                              | Default     | Description                              |
| ------------- | ------------------------------------------------- | ----------- | ---------------------------------------- |
| `label`       | `string`                                          | -           | The row's name                           |
| `meta`        | `string`                                          | -           | Secondary text after the label           |
| `icon`        | `ReactNode`                                       | -           | Icon in the row's tile                   |
| `status`      | `"running" \| "starting" \| "stopped" \| "error"` | -           | Colours the status dot                   |
| `statusLabel` | `string`                                          | The status  | Text next to the dot                     |

Inspired by the architecture diagram on the Agent 37 Cloud site.

---

# FAQ Tabs Card

> A tabbed FAQ card with animated accordion answers and a support footer.

Source: https://ui.cortexcn.dev/docs/components/faq-tabs-card

## Installation

```bash
npx shadcn@latest add @cortexcn/faq-tabs-card
```

## Usage

```tsx
import { FAQTabsCard } from "@/components/faq-tabs-card";
```

```tsx
<FAQTabsCard
  tabs={[
    {
      label: "General",
      faqs: [
        {
          question: "How do I get started?",
          answer: "Create an account and pick a template.",
        },
      ],
    },
  ]}
  footerLabel="Contact support"
  onFooterClick={() => router.push("/contact")}
/>
```

The card ships with sample questions so it looks complete out of the box. Pass your own `tabs` in real use.

## Behavior

- A pill slides between tabs, and switching tabs opens the question at `defaultOpenIndex` again.
- Each question opens and closes with a height animation, and only one is open at a time.
- The tab pill is scoped to each card, so two cards on one page never animate into each other.

## Props

| Prop               | Type         | Default             | Description                                        |
| ------------------ | ------------ | ------------------- | -------------------------------------------------- |
| `tabs`             | `FaqTab[]`   | Sample questions    | Tabs, each with a label and its questions          |
| `defaultTab`       | `number`     | `0`                 | Index of the tab selected at first                 |
| `defaultOpenIndex` | `number`     | `0`                 | Index of the question open at first, `-1` for none |
| `footerLabel`      | `string`     | `"Contact Support"` | Text on the button at the bottom                   |
| `onFooterClick`    | `() => void` | -                   | Called when the bottom button is clicked           |
| `className`        | `string`     | -                   | Extra classes for the card                         |

Adapted from the [Spectrum UI FAQ Tabs Card](https://ui.spectrumhq.in) (Apache 2.0).

---

# Field

> Combines labels, controls, and help text into accessible form fields.

Source: https://ui.cortexcn.dev/docs/components/field

## Installation

```bash
npx shadcn@latest add @cortexcn/field
```

## Usage

```tsx
import { Field, FieldLabel, FieldDescription, FieldError, FieldGroup, FieldLegend, FieldSeparator, FieldSet, FieldContent, FieldTitle } from "@/components/field";
```

## Examples

### Input fields

### Textarea fields

### Select fields

### Checkbox fields

### Radio fields

### Switch fields

### Slider fields

### Native select fields

### OTP input fields

### Horizontal fields

---

# Funnel Chart

> An animated funnel chart with multi-layer halo rings, hover interactions, and staggered entrance animations

Source: https://ui.cortexcn.dev/docs/components/funnel-chart

## Installation

```bash
npx shadcn@latest add @cortexcn/funnel-chart
```

## Usage

The Funnel Chart is a standalone component that renders an animated funnel visualization. Each segment represents a stage in a pipeline, with the width (or height in vertical mode) proportional to the value.

```tsx
import { FunnelChart } from "@/components/charts";

const data = [
  { label: "Visitors", value: 12400, displayValue: "12.4k" },
  { label: "Leads", value: 6800, displayValue: "6.8k" },
  { label: "Qualified", value: 3200, displayValue: "3.2k" },
  { label: "Proposals", value: 1500, displayValue: "1.5k" },
  { label: "Closed", value: 620, displayValue: "620" },
];

export default function SalesFunnel() {
  return <FunnelChart data={data} color="var(--chart-1)" layers={3} />;
}
```

## Props

### FunnelChart

| Prop               | Type                                       | Default            | Description                                        |
| ------------------ | ------------------------------------------ | ------------------ | -------------------------------------------------- |
| `data`             | `FunnelStage[]`                            | required           | Array of funnel stages                             |
| `orientation`      | `"horizontal" \| "vertical"`               | `"horizontal"`     | Layout direction                                   |
| `color`            | `string`                                   | `"var(--chart-1)"` | Default color for all segments                     |
| `layers`           | `number`                                   | `3`                | Number of concentric halo rings per segment        |
| `edges`            | `"curved" \| "straight"`                   | `"curved"`         | Edge style for segment shapes                      |
| `gap`              | `number`                                   | `4`                | Gap between segments in pixels                     |
| `staggerDelay`     | `number`                                   | `0.12`             | Stagger delay between segment animations (seconds) |
| `showPercentage`   | `boolean`                                  | `true`             | Show percentage badges                             |
| `showValues`       | `boolean`                                  | `true`             | Show value labels                                  |
| `showLabels`       | `boolean`                                  | `true`             | Show stage name labels                             |
| `formatPercentage` | `(pct: number) => string`                  | rounds to integer  | Custom percentage formatter                        |
| `formatValue`      | `(value: number) => string`                | locale string      | Custom value formatter                             |
| `labelLayout`      | `"spread" \| "grouped"`                    | `"spread"`         | How labels are arranged within each segment        |
| `labelOrientation` | `"vertical" \| "horizontal"`               | auto               | Stack direction for grouped labels                 |
| `labelAlign`       | `"center" \| "start" \| "end"`             | `"center"`         | Alignment of grouped labels                        |
| `hoveredIndex`     | `number \| null`                           | -                  | Controlled hover state (segment index)             |
| `onHoverChange`    | `(index: number \| null) => void`          | -                  | Callback when hover state changes                  |
| `grid`             | `boolean \| GridConfig`                    | `false`            | Background bands and grid lines                    |
| `renderPattern`    | `(id: string, color: string) => ReactNode` | -                  | Custom SVG pattern for the innermost ring          |
| `className`        | `string`                                   | -                  | Additional CSS class                               |
| `style`            | `CSSProperties`                            | -                  | Additional inline styles                           |

### FunnelStage

| Property       | Type                    | Description                                       |
| -------------- | ----------------------- | ------------------------------------------------- |
| `label`        | `string`                | Stage name displayed below the segment            |
| `value`        | `number`                | Numeric value (first item is treated as 100%)     |
| `displayValue` | `string?`               | Custom display string (overrides formatted value) |
| `color`        | `string?`               | Override the chart-level color for this segment   |
| `gradient`     | `FunnelGradientStop[]?` | Linear gradient for this segment                  |

### GridConfig

When passing an object to `grid`, the following options are available:

| Property      | Type      | Default                | Description                       |
| ------------- | --------- | ---------------------- | --------------------------------- |
| `bands`       | `boolean` | `true`                 | Show alternating background bands |
| `bandColor`   | `string`  | `"var(--color-muted)"` | Color of the background bands     |
| `lines`       | `boolean` | `true`                 | Show grid lines between segments  |
| `lineColor`   | `string`  | `"var(--chart-grid)"`  | Color of the grid lines           |
| `lineOpacity` | `number`  | `1`                    | Opacity of the grid lines         |
| `lineWidth`   | `number`  | `1`                    | Width of the grid lines in pixels |

See the [charts gallery](https://ui.cortexcn.dev/charts/funnel-chart) for vertical layouts, per-segment colors, patterns, and legend sync.

---

# Gauge

> Notch-based radial or linear gauge with optional center label, theme fills, patterns, arc gradients, and responsive sizing

Source: https://ui.cortexcn.dev/docs/components/gauge-chart

## Installation

```bash
npx shadcn@latest add @cortexcn/gauge-chart
```

## Usage

`Gauge` draws **notches** around an arc (default) or along a horizontal track (`orientation="linear"`). The center label is **optional** — omit `centerValue` for a track-only gauge.

- **Fill vs center:** `value` is the fill level **0–100**. `centerValue` is the statistic shown in the label (often the same story or a related KPI).
- **Arc center:** arc gauges overlay the label in the middle of the sweep (PieCenter-style NumberFlow + caption).
- **Linear label placement:** with `orientation="linear"`, place the label above or below the track using `labelPlacement` (`top` | `bottom`) and `labelAlign` (`start` | `center` | `end`) — the same six-position model as chart legend (top/bottom × left/center/right).
- **Responsive:** omit `width` and `height` to fill the parent. Arc gauges use **`minWidth`** (default **300**) and an aspect ratio. Linear gauges fill the parent width and use **`linearHeight`** (default **24**).
- **Linear notches:** linear gauges default to **`uniformWidth`** (rectangular notches). Pass `uniformWidth={false}` for tapered ticks.
- **Patterns / gradients in `<defs>`:** pass **`PatternLines`**, **`LinearGradient`**, etc. as **`children`**, then set **`activeFill`** / **`inactiveFill`** to `url(#id)`.
- **Arc gradients:** set **`useGradient`**. Optional **`activeGradient`** and **`inactiveGradient`** are **`[hexFrom, hexTo]`** tuples (interpolated along the notch index).
- **Fill opacity:** `activeFillOpacity` and `inactiveFillOpacity` map to SVG `fill-opacity` (0–1). Defaults are **1** for active notches and **0.8** for the track; docs and gallery examples use **`inactiveFillOpacity={0.4}`** for a lighter track.
- **Corner radius:** `notchCornerRadius` is the fillet in **pixels** at each notch corner (**0** = sharp). Large values are clamped by edge length and radial depth so shapes can approach a **capsule** / near-circular look.

```tsx
import { Gauge, PatternLines } from "@/components/charts";

export default function RevenueGauge() {
  return (
    <Gauge
      value={66}
      centerValue={428_000}
      spacing={25}
      inactiveFillOpacity={0.4}
      defaultLabel="ARR run rate"
      formatOptions={{
        style: "currency",
        currency: "USD",
        maximumFractionDigits: 0,
      }}
    />
  );
}
```

### Linear gauge

Track-only (no label):

```tsx
<Gauge
  orientation="linear"
  value={72}
  totalNotches={72}
  spacing={0}
  notchCornerRadius={3}
  inactiveFillOpacity={0.4}
  useGradient
/>
```

With label below center:

```tsx
<Gauge
  orientation="linear"
  value={72}
  centerValue={428_000}
  defaultLabel="ARR run rate"
  labelPlacement="bottom"
  labelAlign="center"
  totalNotches={72}
  spacing={0}
  notchCornerRadius={3}
  inactiveFillOpacity={0.4}
  useGradient
/>
```

## Props

### Gauge

| Prop                                        | Type                                           | Default                         | Description                                                                    |
| ------------------------------------------- | ---------------------------------------------- | ------------------------------- | ------------------------------------------------------------------------------ |
| `orientation`                               | `"arc"` \| `"linear"`                          | `"arc"`                         | Arc (default) or horizontal linear notch track                                 |
| `value`                                     | `number`                                       | required                        | Fill level **0–100**                                                           |
| `centerValue`                               | `number`                                       | —                               | Optional center statistic (NumberFlow); omit for no label                      |
| `labelPlacement`                            | `"top"` \| `"bottom"` \| `"left"` \| `"right"` | `"top"`                         | Label position for linear gauges (`top` / `bottom` recommended)                |
| `labelAlign`                                | `"start"` \| `"center"` \| `"end"`             | `"start"`                       | Horizontal alignment for linear label (left / center / right)                  |
| `totalNotches`                              | `number`                                       | `40`                            | Notch count                                                                    |
| `spacing`                                   | `number`                                       | `25`                            | **%** gap between notches                                                      |
| `notchLengthPercent`                        | `number`                                       | `100`                           | Notch depth as **%** of default (5–100); lower = shorter notches               |
| `notchWidthPercent`                         | `number`                                       | `80`                            | Linear only — notch width as **%** of slot                                     |
| `notchCornerRadius`                         | `number`                                       | `0`                             | Corner fillet in **px** (0 = sharp); large values clamp toward a capsule shape |
| `uniformWidth`                              | `boolean`                                      | `false` (arc) / `true` (linear) | Rectangular notches vs tapered                                                 |
| `startAngle` / `endAngle`                   | `number`                                       | `135` / `405`                   | Arc sweep in degrees (arc only)                                                |
| `linearHeight`                              | `number`                                       | `24`                            | Bar height in px (linear only)                                                 |
| `useGradient`                               | `boolean`                                      | `false`                         | Per-notch color ramp                                                           |
| `activeGradient`                            | `[string, string]`                             | lime → emerald                  | Hex stops for active notches when `useGradient`                                |
| `inactiveGradient`                          | `[string, string]`                             | same as active                  | Hex stops for inactive notches when `useGradient`                              |
| `activeFill` / `inactiveFill`               | `string`                                       | `chart-1` / `border`            | Solid, CSS color, or `url(#patternId)`                                         |
| `activeFillOpacity` / `inactiveFillOpacity` | `number`                                       | `1` / `0.8`                     | SVG `fill-opacity` (0–1) for active / track notches                            |
| `defaultLabel`                              | `string`                                       | `"Total"`                       | Center label                                                                   |
| `formatOptions`                             | `ChartStatFlowFormat`                          | standard                        | NumberFlow format                                                              |
| `prefix` / `suffix`                         | `string`                                       | -                               | Center prefix / suffix                                                         |
| `width` / `height`                          | `number`                                       | -                               | Fixed size; omit for responsive                                                |
| `minWidth`                                  | `number`                                       | `300` (arc) / `200` (linear)    | Min width (px) when responsive                                                 |
| `className`                                 | `string`                                       | -                               | Root wrapper                                                                   |
| `children`                                  | `ReactNode`                                    | -                               | Defs (`Pattern*`, `*Gradient`, …)                                              |

## Theming

Inactive (track) notches default to **`var(--border)`** — shared with ring tracks and radar grid lines. Active notches default to **`var(--chart-1)`**. Override with `inactiveFill` / `activeFill`, or tune **`--border`** / **`--chart-1`** in your theme. See [Theming](https://ui.cortexcn.dev/docs/theming).

## Live examples

See the [Gauge gallery](https://ui.cortexcn.dev/charts/gauge-chart) for arc and linear variants.

---

# Gooey Nav

> A row of links with a filled pill under the active one. Choosing another link sends the pill there like a drop of liquid.

Source: https://ui.cortexcn.dev/docs/components/gooey-nav

## Installation

```bash
npx shadcn@latest add @cortexcn/gooey-nav
```

## Usage

```tsx
import { GooeyNav } from "@/components/gooey-nav";
```

```tsx
<GooeyNav
  items={[
    { label: "Home", href: "/" },
    { label: "Pricing", href: "/pricing" },
    { label: "Docs", href: "/docs" },
  ]}
/>
```

## Examples

### Fewer drops

`drops` sets how many drops pull away from the pill, and `duration` how long it takes to arrive. `defaultIndex` picks the item that starts active.

## Behavior

- The edge of the pill facing the new item leaves first and the other edge follows a moment later, so the pill stretches across and snaps in behind itself.
- The pill and its drops sit on one layer with an SVG goo filter: a blur, then a sharp alpha cutoff, so shapes that come close melt into each other. The drops ride the tail a few milliseconds apart, string out behind it, and melt back in as it lands.
- The tail runs a little past its mark and wobbles back, so the pill feels like it has weight.
- The labels change color exactly where the pill covers them, even mid-move, because a second copy of the labels in the pill's color is clipped to the pill.
- Colors come from your theme: the pill is `foreground` and its label is `background`, so it works in light and dark mode.
- Links are real anchors with `aria-current="page"` on the active one. A link whose `href` is `"#"` does not jump to the top of the page.
- If the links do not fit, the row scrolls sideways instead of overflowing.
- With reduced motion enabled, the pill slides without stretching or drops.
- No animation library is used, so it adds no dependencies.

## Props

| Prop            | Type                              | Default | Description                                   |
| --------------- | --------------------------------- | ------- | --------------------------------------------- |
| `items`         | `{ label: string; href: string }[]` | -     | The links, left to right                      |
| `defaultIndex`  | `number`                          | `0`     | The item that starts active                   |
| `onIndexChange` | `(index: number) => void`         | -       | Called with the new index when one is chosen  |
| `drops`         | `number`                          | `6`     | Drops that pull away from the pill as it moves |
| `duration`      | `number`                          | `520`   | Time for the pill to reach the new item, in ms |
| `className`     | `string`                          | -       | Extra classes for the wrapper                 |

---

# Heatmap Chart

> A contribution heatmap with animated cells, configurable level colors and patterns, and an interactive legend

Source: https://ui.cortexcn.dev/docs/components/heatmap-chart

## Installation

```bash
npx shadcn@latest add @cortexcn/heatmap-chart
```

When using `loadingLabel` or `HeatmapChartLoading`, centered shimmer text uses `@cortexcn/shimmering-text` — installed automatically with `@cortexcn/heatmap-chart`.

## Usage

The Heatmap Chart uses a composable API. Wrap the chart and legend in `HeatmapInteractionProvider` so hover dimming and tooltips stay in sync:

```tsx
import {
  HeatmapCells,
  HeatmapChart,
  HeatmapInteractionBoundary,
  HeatmapInteractionProvider,
  HeatmapLegend,
  HeatmapTooltip,
  HeatmapXAxis,
  HeatmapYAxis,
} from "@/components/charts";

const data = [
  {
    bin: 0,
    bins: [
      { bin: 0, count: 2, date: new Date(2024, 0, 1) },
      { bin: 1, count: 0, date: new Date(2024, 0, 2) },
      // …one week column with 7 day bins
    ],
  },
  // …one column per week
];

export default function ContributionHeatmap() {
  return (
    <HeatmapInteractionProvider>
      <HeatmapInteractionBoundary>
        <HeatmapChart data={data} layout="fluid">
          <HeatmapCells />
          <HeatmapXAxis />
          <HeatmapYAxis />
          <HeatmapTooltip />
        </HeatmapChart>
        <HeatmapLegend />
      </HeatmapInteractionBoundary>
    </HeatmapInteractionProvider>
  );
}
```

## Components

### HeatmapChart

The root component that sizes the grid, builds color scales, and provides context to children.

| Prop                | Type                           | Default                                       | Description                                                               |
| ------------------- | ------------------------------ | --------------------------------------------- | ------------------------------------------------------------------------- |
| `data`              | `HeatmapColumn[]`              | required                                      | One column per week (or category) with row bins inside                    |
| `xDomain`           | `[Date, Date]`                 | -                                             | Visible time range — filters week columns                                 |
| `sizingColumnCount` | `number`                       | -                                             | Column count for stable cell sizing when scrubbing                        |
| `layout`            | `"fluid" \| "fill"`            | `"fluid"`                                     | `fluid` hugs content height; `fill` expands cells to parent               |
| `margin`            | `Partial<Margin>`              | `{ top: 28, right: 16, bottom: 0, left: 40 }` | Chart margins                                                             |
| `binSize`           | `number`                       | `0`                                           | Fixed cell size in px; `0` sizes cells to fit                             |
| `gap`               | `number`                       | `2`                                           | Gap between cells in pixels                                               |
| `colorScale`        | `(count) => string`            | -                                             | Override the default color scale                                          |
| `levelColors`       | `HeatmapLevelColors`           | `--chart-scale-01` … `--chart-scale-05`       | Five colors for empty + four activity levels                              |
| `levelStyles`       | `HeatmapLevelStyles`           | -                                             | Per-level color and optional pattern; takes precedence over `levelColors` |
| `aspectRatio`       | `string`                       | -                                             | CSS aspect ratio for the outer container                                  |
| `status`            | `ChartStatus`                  | `"ready"`                                     | Fetch / display status                                                    |
| `loadingLabel`      | `string`                       | -                                             | Centered label while loading                                              |
| `animationDuration` | `number`                       | `1600`                                        | Enter animation duration in ms                                            |
| `animate`           | `boolean`                      | `true`                                        | Play enter fade-in / loading shimmer                                      |
| `columnSeparators`  | `HeatmapSeparatorParsedConfig` | -                                             | Column grouping without a `HeatmapSeparator` child                        |
| `weekStartDay`      | `0`–`6`                        | `0`                                           | First row of the grid (`0` = Sunday, `1` = Monday, etc.)                  |
| `className`         | `string`                       | `""`                                          | Additional CSS class                                                      |

### HeatmapCells

Renders the grid of cells with enter animation and hover dimming.

| Prop              | Type                 | Default | Description                                                                                   |
| ----------------- | -------------------- | ------- | --------------------------------------------------------------------------------------------- |
| `cornerRadius`    | `number`             | `2`     | Corner radius for each cell                                                                   |
| `colorScale`      | `(count) => string`  | -       | Override chart color scale                                                                    |
| `inactiveOpacity` | `number`             | `0.3`   | Opacity for inactive cells while hovering                                                     |
| `inactiveScale`   | `number`             | `1`     | Scale for inactive cells while hovering                                                       |
| `activeScale`     | `number`             | `1`     | Scale for the highlighted cell while hovering                                                 |
| `rowOpacity`      | `number \| number[]` | `1`     | Per-row cell opacity by **display row index** (0 = top row). See [Row opacity](#row-opacity). |
| `interactive`     | `boolean`            | `true`  | Pointer hover and dimming                                                                     |

When `inactiveOpacity`, `inactiveScale`, and `activeScale` are all `1`, hover dimming is disabled.

### HeatmapXAxis / HeatmapYAxis

Month labels along the top and weekday labels along the left. Y-axis labels follow `weekStartDay` on `HeatmapChart`.

| Prop          | Type                       | Default  | Description                                                   |
| ------------- | -------------------------- | -------- | ------------------------------------------------------------- |
| `tickFilter`  | `"all" \| "odd" \| "even"` | `"odd"`  | Which row ticks to show                                       |
| `labelFormat` | `"full" \| "initial"`      | `"full"` | Full name or first letter                                     |
| `rowOpacity`  | `number \| number[]`       | -        | Per-row label opacity — pass the same value as `HeatmapCells` |
| `className`   | `string`                   | -        | Additional class for labels                                   |

### HeatmapLegend

Less → More scale swatches that share `levelStyles` with the chart.

| Prop              | Type                           | Default      | Description                                        |
| ----------------- | ------------------------------ | ------------ | -------------------------------------------------- |
| `lessLabel`       | `string`                       | `"Less"`     | Label before swatches                              |
| `moreLabel`       | `string`                       | `"More"`     | Label after swatches                               |
| `cellSize`        | `number`                       | `11`         | Swatch size in pixels                              |
| `gap`             | `number`                       | `2`          | Gap between swatches                               |
| `cornerRadius`    | `number`                       | `2`          | Swatch corner radius                               |
| `variant`         | `"swatches" \| "gradient"`     | `"swatches"` | Discrete swatches or continuous gradient bar       |
| `gradientSpan`    | `number`                       | `5`          | Gradient bar width in swatch units                 |
| `fontSize`        | `number`                       | -            | Font size in pixels for side labels                |
| `labelClassName`  | `string`                       | -            | Class name for less/more labels                    |
| `align`           | `"start" \| "center" \| "end"` | `"end"`      | Horizontal alignment                               |
| `levelStyles`     | `HeatmapLevelStyles`           | -            | Shared level colors and patterns                   |
| `inactiveOpacity` | `number`                       | `0.3`        | Opacity for inactive swatches while interacting    |
| `inactiveScale`   | `number`                       | `1`          | Scale for inactive swatches while interacting      |
| `activeScale`     | `number`                       | `1`          | Scale for the highlighted swatch while interacting |
| `interactive`     | `boolean`                      | auto         | Sync dimming with chart hover                      |

Gradient mode uses solid colors only (patterns are ignored).

### HeatmapSeparator

Vertical column separators with optional quarter labels.

| Prop              | Type                       | Default         | Description                                                         |
| ----------------- | -------------------------- | --------------- | ------------------------------------------------------------------- |
| `groupBy`         | `"every" \| "quarter"`     | `"every"`       | Group columns by interval or calendar quarter                       |
| `every`           | `number`                   | -               | Insert a separator every N columns when `groupBy="every"`           |
| `spacing`         | `number`                   | `0`             | Horizontal gap between column groups in pixels                      |
| `startOffset`     | `number`                   | plot top        | Distance from container top to line start (align with month labels) |
| `labelOffset`     | `number`                   | `0`             | Distance below line top for quarter labels                          |
| `showLabels`      | `boolean`                  | `false`         | Draw Q1–Q4 labels at group starts                                   |
| `labelClassName`  | `string`                   | -               | Class for quarter labels, e.g. `"text-black dark:text-white"`       |
| `stroke`          | `string`                   | `var(--border)` | Line color when `gradient` is omitted                               |
| `strokeStyle`     | `"solid" \| "dashed"`      | `"solid"`       | Line style                                                          |
| `strokeDasharray` | `string`                   | `"4,4"`         | Dash pattern when `strokeStyle="dashed"`                            |
| `strokeWidth`     | `number`                   | `1`             | Line width in pixels                                                |
| `strokeOpacity`   | `number`                   | `1`             | Opacity multiplier for solid strokes or gradient stops              |
| `gradient`        | `HeatmapSeparatorGradient` | -               | Optional vertical fade; omit for a flat solid stroke                |

**Solid stroke** — no `gradient` prop:

```tsx
<HeatmapSeparator
  groupBy="quarter"
  showLabels
  labelClassName="text-black dark:text-white"
  stroke="var(--border)"
  strokeStyle="solid"
/>
```

**Gradient fade** — softens the top and bottom of each line:

```tsx
<HeatmapSeparator
  groupBy="quarter"
  showLabels
  stroke="var(--muted)"
  gradient={{
    from: "var(--muted)",
    via: "var(--muted)",
    to: "var(--muted)",
    fromOpacity: 0,
    viaOpacity: 1,
    toOpacity: 0,
  }}
/>
```

### HeatmapTooltip

Shows the contribution count and date for the hovered cell.

| Prop              | Type                      | Default                           | Description                                                                                  |
| ----------------- | ------------------------- | --------------------------------- | -------------------------------------------------------------------------------------------- |
| `formatLabel`     | `(count, date) => string` | default formatter                 | Custom contribution line (bottom section)                                                    |
| `showDelay`       | `number`                  | `0`                               | Delay before first show (ms). Cell-to-cell updates are immediate once visible.               |
| `hideDelay`       | `number`                  | `120`                             | Grace period before hiding when leaving a cell (ms). Reduces flicker between adjacent cells. |
| `instant`         | `boolean`                 | `false`                           | No fade/scale motion — tooltip appears and disappears immediately                            |
| `backgroundColor` | `string`                  | `var(--chart-tooltip-background)` | Panel background (CSS variable or color value)                                               |
| `panelStyle`      | `CSSProperties`           | -                                 | Inline styles for the tooltip panel                                                          |
| `className`       | `string`                  | `""`                              | Additional CSS class                                                                         |

## Level styles and patterns

Pass `levelStyles` (five entries: empty + levels 1–4) to control both cell fills and legend swatches. Each level can be solid or use a pattern preset. Omit `patternColor` to derive stripe color from the level color, or set `patternColor: "var(--chart-scale-pattern-color)"` for the theme default:

```tsx
const levelStyles = [
  { color: "var(--chart-scale-01)", fillMode: "solid" },
  { color: "var(--chart-scale-02)", fillMode: "solid" },
  { color: "var(--chart-scale-03)", fillMode: "pattern", pattern: "diagonal", patternColor: "var(--chart-scale-pattern-color)" },
  { color: "var(--chart-scale-04)", fillMode: "solid" },
  { color: "var(--chart-scale-05)", fillMode: "solid" },
] as const;

<HeatmapChart data={data} levelStyles={levelStyles}>
  <HeatmapCells />
</HeatmapChart>
<HeatmapLegend levelStyles={levelStyles} />
```

## Data format

```typescript
interface HeatmapBin {
  bin: number; // row index (0–6 for days of week)
  count: number; // activity level 0–4
  date: Date;
}

interface HeatmapColumn {
  bin: number; // column index (week number)
  bins: HeatmapBin[];
}
```

Counts map to five visual levels (0 = empty, 1–4 = increasing activity). Use `getHeatmapContributionLevel(count)` from `@cortexcn/ui/charts` to derive the level from a raw count.

### Row opacity

`rowOpacity` on `HeatmapCells` and `HeatmapYAxis` controls opacity **per display row** — the row index after `weekStartDay` rotation, where `0` is the top row of the grid.

With `weekStartDay={1}` (Monday-first):

| Display row | Day |
| ----------- | --- |
| 0           | Mon |
| 1           | Tue |
| 2           | Wed |
| 3           | Thu |
| 4           | Fri |
| 5           | Sat |
| 6           | Sun |

Pass the **same** value to `HeatmapCells` and `HeatmapYAxis` so faded rows and their labels stay aligned.

**Plain array** — explicit opacity per row:

```tsx
const rowOpacity = [1, 1, 1, 1, 1, 0.35, 0.35]; // fade Sat + Sun (Mon-first)
```

**Helper** — `buildHeatmapRowOpacity` from `@cortexcn/ui/charts`:

```tsx
import { buildHeatmapRowOpacity } from "@/components/charts";

// Fade rows 5 and 6 (Sat + Sun when weekStartDay={1})
const weekendOpacity = buildHeatmapRowOpacity([5, 6], 0.35);

// Same result with a row predicate (nth-style rule)
const weekendOpacity = buildHeatmapRowOpacity((row) => row >= 5, 0.35);
```

Other predicate examples:

```tsx
buildHeatmapRowOpacity((row) => row % 2 === 0, 0.5); // even rows
buildHeatmapRowOpacity((row) => row < 2, 0.5); // first two rows
```

**Single number** — applies to every row:

```tsx
<HeatmapCells rowOpacity={0.6} />
```

### Monday-first grid with faded weekends

Source data can stay Sunday-first; `weekStartDay` rotates display rows without reshaping your data:

```tsx
import { buildHeatmapRowOpacity } from "@/components/charts";

const weekendOpacity = buildHeatmapRowOpacity((row) => row >= 5, 0.35);

<HeatmapChart data={data} weekStartDay={1}>
  <HeatmapCells rowOpacity={weekendOpacity} />
  <HeatmapYAxis
    tickFilter="all"
    labelFormat="initial"
    rowOpacity={weekendOpacity}
  />
</HeatmapChart>;
```

Default level colors use **`--chart-scale-01`** … **`--chart-scale-05`**. See [Theming](https://ui.cortexcn.dev/docs/theming).

## Gallery

See the [charts gallery](https://ui.cortexcn.dev/charts/heatmap-chart) for pattern fills and layout variants.

---

# Hover Card

> For sighted users to preview content available behind a link.

Source: https://ui.cortexcn.dev/docs/components/hover-card

## Installation

```bash
npx shadcn@latest add @cortexcn/hover-card
```

## Usage

```tsx
import { HoverCard, HoverCardTrigger, HoverCardContent } from "@/components/hover-card";
```

## Examples

### Sides

### In dialog

---

# Input

> Displays a form input field or a component that looks like an input field.

Source: https://ui.cortexcn.dev/docs/components/input

## Installation

```bash
npx shadcn@latest add @cortexcn/input
```

## Usage

```tsx
import { Input } from "@/components/input";
```

## Examples

### Basic

### Invalid

### With label

### With description

### Disabled

### Input types

### With select

### With button

### With native select

### Form

---

# Input Group

> Adds addons, buttons, and helper content to inputs.

Source: https://ui.cortexcn.dev/docs/components/input-group

## Installation

```bash
npx shadcn@latest add @cortexcn/input-group
```

## Usage

```tsx
import { InputGroup, InputGroupAddon, InputGroupButton, InputGroupText, InputGroupInput, InputGroupTextarea } from "@/components/input-group";
```

## Examples

### Basic

### With addons

### With buttons

### With kbd

### In card

### Textarea

---

# Input OTP

> An accessible one-time password input with copy and paste support.

Source: https://ui.cortexcn.dev/docs/components/input-otp

## Installation

```bash
npx shadcn@latest add @cortexcn/input-otp
```

## Usage

```tsx
import { InputOTP, InputOTPGroup, InputOTPSlot, InputOTPSeparator } from "@/components/input-otp";
```

## Examples

### Form

### Simple

### Digits only

### With separator

### Alphanumeric

### Disabled

### 4 digits

### Invalid state

---

# Item

> A versatile row for displaying media, a title, a description, and actions.

Source: https://ui.cortexcn.dev/docs/components/item

## Installation

```bash
npx shadcn@latest add @cortexcn/item
```

## Usage

```tsx
import { Item, ItemMedia, ItemContent, ItemActions, ItemGroup, ItemSeparator, ItemTitle, ItemDescription, ItemHeader, ItemFooter } from "@/components/item";
```

## Examples

### Default

### Outline

### Muted

### Small

### Outline, small

### Muted, small

### Extra small

### Outline, extra small

### Muted, extra small

### asChild

### Outline, asChild

### Muted, asChild

### ItemGroup

### Outline, ItemGroup

### Muted, ItemGroup

### ItemSeparator

### ItemHeader

### ItemFooter

### ItemHeader and ItemFooter

### Item with drawer

### Default, ItemMedia image

### Outline, ItemMedia image

### Outline, ItemMedia image, small

### Outline, ItemMedia image, extra small

### Muted, ItemMedia image

---

# Kbd

> Displays textual user input from a keyboard, such as a shortcut.

Source: https://ui.cortexcn.dev/docs/components/kbd

## Installation

```bash
npx shadcn@latest add @cortexcn/kbd
```

## Usage

```tsx
import { Kbd, KbdGroup } from "@/components/kbd";
```

## Examples

### Basic

### Modifier keys

### KbdGroup

### Arrow keys

### With icons

### With icons and text

### InputGroup

### Tooltip

### With samp

---

# Label

> Renders an accessible label associated with controls.

Source: https://ui.cortexcn.dev/docs/components/label

## Installation

```bash
npx shadcn@latest add @cortexcn/label
```

## Usage

```tsx
import { Label } from "@/components/label";
```

## Examples

### With checkbox

### With input

### Disabled

### With textarea

---

# Lanyard 3D

> A 3D ID badge on a strap. Drag it and it swings and twists on a simulated strap; click it to flip it over.

Source: https://ui.cortexcn.dev/docs/components/lanyard-3d

## Installation

```bash
npx shadcn@latest add @cortexcn/lanyard-3d
```

## Usage

```tsx
import { Lanyard3D } from "@/components/lanyard-3d";
```

```tsx
<Lanyard3D
  name="Alex Rivera"
  jobTitle="Design Engineer"
  badgeId="CX-0042"
  label="STAFF"
  strapText="CORTEXCN"
/>
```

The badge is drawn for you from these props: your logo and brand name at the top, a photo or initials, the name and job title, a barcode, and the badge code. The back carries the logo, the brand name, and `backText`. To use your own artwork instead, pass `frontImage` and `backImage`.

## Examples

### Your details

Set the name, job title, tag, code, and the text on the strap and the back. `dropIn={false}` starts it hanging still.

### Colors

`cardColor`, `inkColor`, and `strapColor` restyle the badge. The strap text turns light or dark to stay readable on the strap.

## Behavior

- The scene is drawn with three.js. The physics is written in the component: the strap is a rope of short segments and the card is six points held rigid, so no physics engine is loaded.
- Drag the card anywhere and it follows the pointer, as far as the strap reaches. Let go and it swings back and settles. A quick flick throws it.
- The strap twists as the card turns, and the card turns a little as it swings sideways, then turns back to face you.
- A click or tap without dragging flips the card. With the keyboard, focus the badge and press Enter or Space to flip it, or the arrow keys to swing it.
- The card faces and the strap are painted on canvases in the page's own fonts. The Cortexcn mark is drawn unless you pass `logo`.
- On a touch screen, a touch that starts on the card holds the page still while you drag. Elsewhere in the box, the page scrolls as usual.
- The animation stops once the badge hangs still and pauses while it is off screen, so an idle badge costs nothing.
- With reduced motion enabled, the badge hangs still and flips at once.
- In a box narrower than the card, the card scales down to fit, to no less than half its size.
- Images given as URLs must allow cross-origin use (CORS), since they are drawn on a canvas.

## Props

| Prop          | Type      | Default             | Description                                          |
| ------------- | --------- | ------------------- | ---------------------------------------------------- |
| `name`        | `string`  | `"Alex Rivera"`     | Name on the front                                    |
| `jobTitle`    | `string`  | `"Design Engineer"` | Line under the name                                  |
| `badgeId`     | `string`  | `"CX-0042"`         | Code beside the barcode                              |
| `label`       | `string`  | `"STAFF"`           | Tag in the top corner. An empty string hides it      |
| `initials`    | `string`  | From `name`         | Letters in the photo square                          |
| `photo`       | `string`  | -                   | Photo for the square instead of initials             |
| `brand`       | `string`  | `"Cortexcn"`        | Name beside the logo                                 |
| `logo`        | `string`  | Cortexcn mark       | Logo image URL                                       |
| `backText`    | `string`  | `"ui.cortexcn.dev"` | Line under the logo on the back                      |
| `frontImage`  | `string`  | -                   | Your own artwork for the whole front                 |
| `backImage`   | `string`  | -                   | Your own artwork for the whole back                  |
| `strapText`   | `string`  | `"CORTEXCN"`        | Text repeated along the strap                        |
| `strapColor`  | `string`  | `"#0a0a0a"`         | Strap color                                          |
| `cardColor`   | `string`  | `"#ffffff"`         | Card color                                           |
| `inkColor`    | `string`  | `"#0a0a0a"`         | Text and marks on the card                           |
| `strapLength` | `number`  | `200`               | Strap length in px                                   |
| `cardWidth`   | `number`  | `232`               | Card width in px                                     |
| `cardHeight`  | `number`  | `320`               | Card height in px                                    |
| `gravity`     | `number`  | `0.55`              | Pull of gravity on the strap and card                |
| `dropIn`      | `boolean` | `true`              | Swing in from the side on mount                      |
| `className`   | `string`  | -                   | Extra classes for the box. It is 560px tall by default |

---

# Lanyard Badge

> An ID badge hanging from a strap. Drag it and it swings back on a simulated rope; click it to flip it over.

Source: https://ui.cortexcn.dev/docs/components/lanyard-badge

## Installation

```bash
npx shadcn@latest add @cortexcn/lanyard-badge
```

## Usage

```tsx
import { LanyardBadge } from "@/components/lanyard-badge";
```

```tsx
<LanyardBadge
  front={<div className="p-6">Alex Rivera</div>}
  back={<div className="p-6">ui.cortexcn.dev</div>}
  strapText="CORTEXCN"
/>
```

The card is plain HTML, so the front and back can hold anything: a photo, a name and role, a QR code, or a link. Use it on an about page, a team page, or a conference landing page.

## Examples

### Front only

Without a `back`, clicking does nothing and the card only swings. A shorter `strapLength` hangs it higher, and `dropIn={false}` starts it hanging still.

## Behavior

- The strap is a rope of short segments, simulated in the browser and drawn as an SVG path, with `strapText` repeated along it. The card hangs from the end of the rope on a clip.
- Drag the card anywhere and it follows the pointer, as far as the strap reaches. Let go and it swings back and settles. A quick flick throws it.
- The card turns toward you as it swings sideways, and a soft shine moves across it.
- A click or tap without dragging flips the card when it has a `back`. With the keyboard, focus the card and press Enter or Space.
- The simulation stops once the badge hangs still, and starts again when you touch it, so an idle badge costs nothing.
- With reduced motion enabled, the badge hangs still and does not swing or drop in. It still flips.
- The strap hangs from the middle of the top edge and follows the box when it resizes. Give the box a height with `className`.
- In a box narrower than the card, the card scales down to fit, to no less than half its size.
- No 3D or physics library is used, so it adds no dependencies.

## Props

| Prop          | Type        | Default      | Description                                          |
| ------------- | ----------- | ------------ | ---------------------------------------------------- |
| `front`       | `ReactNode` | -            | The front of the card                                |
| `back`        | `ReactNode` | -            | The back of the card. Without it, the card does not flip |
| `strapText`   | `string`    | `"CORTEXCN"` | Words repeated along the strap                       |
| `strapLength` | `number`    | `200`        | Strap length from the top edge to the clip, in px    |
| `cardWidth`   | `number`    | `232`        | Card width in px                                     |
| `cardHeight`  | `number`    | `320`        | Card height in px                                    |
| `gravity`     | `number`    | `0.55`       | Downward pull. Higher swings faster                  |
| `dropIn`      | `boolean`   | `true`       | Swing in from the side on first render               |
| `className`   | `string`    | -            | Extra classes for the box. It is 560px tall by default |

---

# Light Speed

> A warp-speed tunnel of glowing light streaks, drawn with three.js and bloom.

Source: https://ui.cortexcn.dev/docs/components/light-speed

## Installation

```bash
npx shadcn@latest add @cortexcn/light-speed
```

Using TypeScript? Add the three.js types as well with `pnpm add -D @types/three`. The CLI adds them for you.

## Usage

```tsx
import { LightSpeed } from "@/components/light-speed";
```

```tsx
<section className="relative isolate flex h-[480px] items-center justify-center overflow-hidden">
  <LightSpeed />
  <h1 className="relative text-4xl font-medium text-white">
    Ship at light speed
  </h1>
</section>
```

The background fills its nearest positioned parent, so give that parent `relative` and a height. Content placed after it with `relative` sits on top.

## Examples

### Color and speed

A cooler color with fewer, slower streaks.

## Behavior

- Draws with WebGL through React Three Fiber, and a bloom pass from `@react-three/postprocessing` turns the bright streaks into a glow.
- Ignores the pointer, so buttons and links on top stay clickable, and it is hidden from screen readers.
- Renders at up to twice the device pixel ratio, which keeps it sharp without overworking large screens.
- With reduced motion enabled, it holds a still frame instead of animating.
- Set `paused` to hold the frame yourself, for example while the section is off screen.

## Props

| Prop             | Type      | Default     | Description                                                  |
| ---------------- | --------- | ----------- | ------------------------------------------------------------ |
| `particleCount`  | `number`  | `1000`      | Number of light streaks                                      |
| `speed`          | `number`  | `2.4`       | Base speed of the warp effect                                |
| `lightColor`     | `string`  | `"#b026ff"` | Color of the streaks                                         |
| `intensity`      | `number`  | `3`         | How far the color is pushed past full brightness; more glows |
| `radius`         | `number`  | `25`        | Radius of the tunnel the streaks spawn in                    |
| `cylinderLength` | `number`  | `150`       | Length of the tunnel before streaks loop back                |
| `paused`         | `boolean` | `false`     | Hold the current frame                                       |
| `className`      | `string`  | -           | Extra classes for the wrapper                                |

---

# Line Chart

> A composable line chart with tooltips, markers, and hover interactions

Source: https://ui.cortexcn.dev/docs/components/line-chart

## Installation

```bash
npx shadcn@latest add @cortexcn/line-chart
```

## Usage

Build charts by composing components. See the [charts gallery](https://ui.cortexcn.dev/charts/line-chart) for interactive examples.

```tsx
import { LineChart, Line, Grid, XAxis, ChartTooltip } from "@/components/charts";

const data = [
  { date: new Date("2025-01-01"), users: 1200 },
  { date: new Date("2025-01-02"), users: 1350 },
  // ...
];

export default function SimpleChart() {
  return (
    <LineChart data={data}>
      <Grid horizontal />
      <Line dataKey="users" />
      <XAxis />
      <ChartTooltip />
    </LineChart>
  );
}
```

## Updating data smoothly

When your data changes (e.g. filtering by date range, refreshing from an API), the chart automatically updates smoothly without replaying the enter animation. The y-domain tweens to the new scale via `yDomainTween` (enabled by default).

**Do not** change or pass the `revealSignature` prop when updating data. That prop is only for manually replaying the reveal animation.

Click the date range buttons — the line and y-axis morph smoothly without reinitialization. Use the replay button to run the enter animation again.

## Components

### LineChart

The root component that provides context to all children.

| Prop                          | Type                        | Default                                        | Description                                                     |
| ----------------------------- | --------------------------- | ---------------------------------------------- | --------------------------------------------------------------- |
| `data`                        | `Record<string, unknown>[]` | required                                       | Array of data points                                            |
| `xDataKey`                    | `string`                    | `"date"`                                       | Key in data for x-axis values                                   |
| `margin`                      | `Partial<Margin>`           | `{ top: 40, right: 40, bottom: 40, left: 40 }` | Chart margins                                                   |
| `animationDuration`           | `number`                    | `1100`                                         | Clip-reveal duration in ms (`cubic-bezier(0.85, 0, 0.15, 1)`)   |
| `status`                      | `"loading" \| "ready"`      | `"ready"`                                      | Loading ↔ ready choreography on one chart instance              |
| `loadingLabel`                | `string`                    | —                                              | Centered shimmer label while `status="loading"` (`""` hides it) |
| `yDomainTween`                | `boolean`                   | `true`                                         | Animate y-domain when status or target domain changes           |
| `yDomainTweenDuration`        | `number`                    | `500`                                          | Y-domain tween duration in ms                                   |
| `xDomain`                     | `[Date, Date]`              | —                                              | Visible x-range for brush zoom                                  |
| `xDomainSlotCount`            | `number`                    | —                                              | Full dataset length for x-scale padding when `xDomain` is set   |
| `tweenYDomainOnXDomainChange` | `boolean`                   | `false`                                        | Tween y-domain when the brush changes the visible x-range       |
| `aspectRatio`                 | `string`                    | `"2 / 1"`                                      | CSS aspect ratio                                                |
| `className`                   | `string`                    | `""`                                           | Additional CSS class                                            |
| `style`                       | `CSSProperties`             | —                                              | Inline container styles (e.g. fixed height for a brush strip)   |

### Line

Renders a line on the chart.

| Prop                   | Type                     | Default                     | Description                                                                  |
| ---------------------- | ------------------------ | --------------------------- | ---------------------------------------------------------------------------- |
| `dataKey`              | `string`                 | required                    | Key in data for y values                                                     |
| `yAxisId`              | `string \| number`       | `"left"`                    | Y-scale group for biaxial charts (pair with `YAxis`)                         |
| `stroke`               | `string`                 | `var(--chart-line-primary)` | Line color                                                                   |
| `strokeWidth`          | `number`                 | `2.5`                       | Line width                                                                   |
| `curve`                | `CurveFactory`           | `curveNatural`              | D3 curve function                                                            |
| `animate`              | `boolean`                | `true`                      | Enable grow animation                                                        |
| `fadeEdges`            | `boolean`                | `true`                      | Fade line at edges                                                           |
| `showHighlight`        | `boolean`                | `true`                      | Show highlight on hover                                                      |
| `showMarkers`          | `boolean`                | `false`                     | Render scatter-style ring markers at each point                              |
| `loadingStroke`        | `string`                 | `var(--foreground)`         | Pulse stroke color while chart is loading                                    |
| `loadingStrokeOpacity` | `number`                 | `0.5`                       | Pulse stroke opacity while chart is loading                                  |
| `markers`              | `SeriesPointMarkerStyle` | —                           | Marker styling (same options as [`Scatter`](https://ui.cortexcn.dev/docs/components/scatter-chart)) |

### Grid

Renders grid lines.

| Prop                          | Type       | Default                                 | Description                                                                       |
| ----------------------------- | ---------- | --------------------------------------- | --------------------------------------------------------------------------------- |
| `horizontal`                  | `boolean`  | `true`                                  | Show horizontal lines                                                             |
| `vertical`                    | `boolean`  | `false`                                 | Show vertical lines                                                               |
| `numTicksRows`                | `number`   | `5`                                     | Number of horizontal lines                                                        |
| `numTicksColumns`             | `number`   | `10`                                    | Number of vertical lines                                                          |
| `stroke`                      | `string`   | `var(--chart-grid)`                     | Line color while ready                                                            |
| `loadingStroke`               | `string`   | —                                       | Grid stroke while loading chrome is active                                        |
| `strokeDasharray`             | `string`   | `"4,4"`                                 | Dash pattern                                                                      |
| `highlightRowValues`          | `number[]` | —                                       | Draw emphasized horizontal lines at specific y values (e.g. `[0]` for break-even) |
| `highlightRowStroke`          | `string`   | `var(--chart-foreground-muted)`         | Stroke for highlighted rows                                                       |
| `highlightRowStrokeOpacity`   | `number`   | `1`                                     | Opacity for highlighted rows                                                      |
| `highlightRowStrokeWidth`     | `number`   | `1`                                     | Width for highlighted rows                                                        |
| `highlightRowStrokeDasharray` | `string`   | `"0"`                                   | Dash pattern for highlighted rows (`"0"` = solid)                                 |
| `shimmer`                     | `boolean`  | `false`                                 | Animate a shimmer band across horizontal grid lines                               |
| `shimmerStroke`               | `string`   | `color-mix(…)` on `--foreground` at 68% | Shimmer band color and opacity                                                    |
| `shimmerLength`               | `number`   | `140`                                   | Shimmer band width in pixels                                                      |
| `shimmerSpeed`                | `number`   | `1`                                     | Shimmer speed multiplier when sync is off (higher = faster)                       |
| `shimmerSync`                 | `boolean`  | `false`                                 | Match shimmer timing to the line pulse (2.2s cycle + 280ms pause)                 |

### Background

Pattern fill for the plot area when you omit `Grid`. Fades in after the series reveal on time-series charts. See the [Background utility](https://ui.cortexcn.dev/docs/utility/background) for presets (`diagonal`, `dots`, `cross`, …), edge fade, and opacity — and the **Pattern Background** examples on the [line chart gallery](https://ui.cortexcn.dev/charts/line-chart).

### XAxis

Renders x-axis labels that fade when the crosshair passes.

| Prop              | Type                 | Default  | Description                                                                                  |
| ----------------- | -------------------- | -------- | -------------------------------------------------------------------------------------------- |
| `numTicks`        | `number`             | `6`      | Number of tick labels                                                                        |
| `tickerHalfWidth` | `number`             | `50`     | Fade radius for labels                                                                       |
| `tickMode`        | `"data" \| "domain"` | `"data"` | `"data"` snaps labels to data rows (crosshair-aligned); `"domain"` for calendar-even spacing |

### ChartTooltip

Renders the tooltip with crosshair, dots, and content box.

| Prop                  | Type                                    | Default  | Description                                                    |
| --------------------- | --------------------------------------- | -------- | -------------------------------------------------------------- |
| `showDatePill`        | `boolean`                               | `true`   | Show animated date ticker                                      |
| `showCrosshair`       | `boolean`                               | `true`   | Show vertical crosshair                                        |
| `showDots`            | `boolean`                               | `true`   | Show dots on lines                                             |
| `indicatorColor`      | `string \| (point) => string`           | —        | Crosshair and dot color; use a function for value-based colors |
| `indicatorDasharray`  | `string`                                | —        | Dash pattern for the crosshair (e.g. `"4,4"`)                  |
| `indicatorFadeEdges`  | `"both" \| "top" \| "bottom" \| "none"` | `"both"` | Vertical crosshair fade                                        |
| `indicatorFadeLength` | `number`                                | `10`     | Fade size (% of height)                                        |
| `matchCrosshair`      | `boolean`                               | `false`  | Panel uses crosshair spring when `true`                        |
| `damping`             | `number`                                | `20`     | Panel follow when `matchCrosshair={false}`; `0` = instant      |
| `content`             | `(props) => ReactNode`                  | -        | Custom content renderer                                        |
| `rows`                | `(point) => TooltipRow[]`               | -        | Custom row generator                                           |

## Dual Y axes (biaxial)

Pair `yAxisId` on each `Line` with matching `YAxis` components. Increase `margin.left` and `margin.right` so labels fit. See [Y Axis](https://ui.cortexcn.dev/docs/utility/axis/y-axis) and the **Left and right Y axes** examples on the [line chart gallery](https://ui.cortexcn.dev/charts/line-chart).

## Profit/Loss line

For a single series that crosses zero, use [`ProfitLossLine`](https://ui.cortexcn.dev/docs/components/profit-loss-line) inside `LineChart`. Pair it with a hidden `Line` (same `dataKey`) so the chart registers the series for the y-domain and tooltip. When any value is negative, the y-axis automatically includes the full data extent instead of anchoring at zero.

Highlight the break-even baseline with `Grid highlightRowValues={[0]}`:

```tsx
<Grid
  highlightRowValues={[0]}
  highlightRowStroke="var(--foreground)"
  highlightRowStrokeOpacity={0.35}
  horizontal
/>
```

See the [Profit/Loss Line](https://ui.cortexcn.dev/docs/components/profit-loss-line) docs and the [line chart gallery](https://ui.cortexcn.dev/charts/line-chart) (**Profit/Loss** example).

## Projection

Extend a series past the last data point with [`ProjectionLine`](https://ui.cortexcn.dev/docs/utility/projection-line). Build the path with `buildProjectionPath` (auto slope, target value, or manual points). Optionally add [`LineSeriesTerminalMarker`](https://ui.cortexcn.dev/docs/utility/projection-line#terminal-marker) at the anchor.

Projections extend the x-domain to the horizon and are not supported together with [brush zoom](https://ui.cortexcn.dev/docs/utility/brush).

<div className="not-prose mb-3 flex items-center justify-between gap-4">
  <h3 className="m-0 font-semibold text-foreground text-base tracking-tight">
    Preview
  </h3>
</div>

See the [Projection Line utility](https://ui.cortexcn.dev/docs/utility/projection-line) for props and `buildProjectionPath` options.

## Brush zoom

Use `ChartBrushLayout` and `ChartBrush` the same way as on [`AreaChart`](https://ui.cortexcn.dev/docs/components/area-chart#brush-zoom). See the [Brush](https://ui.cortexcn.dev/docs/utility/brush) utility docs for full API reference. The brush strip typically shows simplified `Line` series; the main chart receives `xDomain`, `xDomainSlotCount`, and `tweenYDomainOnXDomainChange` for live zoom and y-domain tweening.

<div className="not-prose mb-3 flex items-center justify-between gap-4">
  <h3 className="m-0 font-semibold text-foreground text-base tracking-tight">
    Preview
  </h3>
</div>

## Loading state

Drive loading and ready from your data layer with a single `LineChart` — one `Grid`, one `Line`, no component swap. Set `status="loading"` while fetching; switch to `"ready"` when data resolves.

**Loading → ready:** pulse loop on skeleton data → pulse finishes its grow, then flows out right → loading label drifts down 30px, blurs, and fades → grid y-domain tween (500ms) → clip-path reveal (`cubic-bezier(0.85, 0, 0.15, 1)`) → interaction enabled.

**Ready → loading:** ready line conceals to the right → grid y-domain tween → pulse loop and shimmer resume.

Pair `Grid` `stroke` / `loadingStroke` with shimmer props. Pair `Line` `loadingStroke` props. Use `loadingLabel` on `LineChart` for centered shimmer text via `@cortexcn/shimmering-text`.

<div className="not-prose mb-3 flex items-center justify-between gap-4">
  <h3 className="m-0 font-semibold text-foreground text-base tracking-tight">
    Preview
  </h3>
</div>

Toggle **Loading** / **Ready** in the preview to replay the transition, and **Pulse** / **Sweep** to switch the loading animation style. When target data spans a different y-range than the skeleton, `yDomainTween` morphs the scale before the line reveals.

Installing `@cortexcn/line-chart` pulls in `@cortexcn/shimmering-text` automatically.

### Loading style: pulse or sweep

The loading state has two animation styles, set with `loadingStyle` on the `Line`: the default `"pulse"` (a segment travels along the skeleton stroke) or `"sweep"` (a soft diagonal shimmer sweeps across the whole line). Set it on the `Line` inside a `status="loading"` chart, or on the `LineChartLoading` wrapper:

```tsx
<LineChart data={data} status="loading">
  <Grid horizontal shimmer />
  <Line dataKey="revenue" loadingStyle="sweep" />
</LineChart>

// or, with the turnkey wrapper:
<LineChartLoading loadingStyle="sweep" />;
```

The sweep masks over the real skeleton line, so it follows whatever `curve` the `Line` uses (`curveStepAfter`, `curveNatural`, …) and respects `prefers-reduced-motion`. To keep the loading→ready handoff smooth, the sweep is used only during steady loading; the pulse still drives the exit transition. See the **Loading (Sweep)** example on the [line chart gallery](https://ui.cortexcn.dev/charts/line-chart).

## Dashed tail

Set `dashFromIndex` on `Line` to draw a solid stroke through one data point, then a dashed segment through the end of the series. Useful when the final period is still in progress (e.g. yesterday → today).

`dashFromIndex` is **inclusive** — dashing starts at that row and continues through the last point. The dashed segment follows the same curved path as the solid stroke and respects `fadeEdges`.

| Prop            | Type     | Default | Description                                         |
| --------------- | -------- | ------- | --------------------------------------------------- |
| `dashFromIndex` | `number` | —       | Inclusive data index where the dashed tail begins   |
| `dashArray`     | `string` | `"6,4"` | SVG `stroke-dasharray` pattern for the tail segment |

```tsx
<Line
  dataKey="visitors"
  dashFromIndex={5}
  dashArray="6,4"
  stroke="var(--chart-line-primary)"
/>
```

## Markers

Add markers to annotate specific dates on the chart:

```tsx
import {
  LineChart,
  Line,
  ChartTooltip,
  ChartMarkers,
  MarkerTooltipContent,
  useActiveMarkers,
  type ChartMarker,
} from "@/components/charts";

const markers: ChartMarker[] = [
  {
    date: new Date("2025-01-05"),
    icon: "🚀",
    title: "v1.2.0 Released",
    description: "New chart animations",
  },
  {
    date: new Date("2025-01-05"), // Same day - will stack!
    icon: "🐛",
    title: "Bug Fix",
    description: "Fixed tooltip positioning",
  },
];

function MyChart({ data }) {
  return (
    <LineChart data={data}>
      <Line dataKey="users" />
      <ChartMarkers items={markers} />
      <ChartTooltip>
        <MarkerContent markers={markers} />
      </ChartTooltip>
    </LineChart>
  );
}

// Use the hook to get markers for the hovered date
function MarkerContent({ markers }) {
  const activeMarkers = useActiveMarkers(markers);
  if (activeMarkers.length === 0) return null;
  return <MarkerTooltipContent markers={activeMarkers} />;
}
```

### ChartMarker Interface

```ts
interface ChartMarker {
  date: Date; // Date for marker position
  icon: React.ReactNode; // Icon (emoji or component)
  title: string; // Tooltip title
  description?: string; // Optional description
  content?: React.ReactNode; // Custom tooltip content
  color?: string; // Background color override
  onClick?: () => void; // Click handler
  href?: string; // URL to navigate to
  target?: "_blank" | "_self"; // Link target
}
```

### ChartMarkers Props

| Prop        | Type            | Default  | Description                 |
| ----------- | --------------- | -------- | --------------------------- |
| `items`     | `ChartMarker[]` | required | Array of markers            |
| `size`      | `number`        | `28`     | Marker circle size          |
| `showLines` | `boolean`       | `true`   | Show vertical guide lines   |
| `animate`   | `boolean`       | `true`   | Animate markers on entrance |

## Segment Selection

Add click-drag and touch segment selection with composable components. The line highlight automatically shows the selected path segment.

### Basic Usage

Click and drag (or two-finger touch on mobile) to select a range:

```tsx
import {
  LineChart,
  Line,
  Grid,
  XAxis,
  ChartTooltip,
  SegmentBackground,
  SegmentLineFrom,
  SegmentLineTo,
} from "@/components/charts";

<LineChart data={data}>
  <Grid horizontal />
  <Line dataKey="users" />
  <SegmentBackground />
  <SegmentLineFrom />
  <SegmentLineTo />
  <XAxis />
  <ChartTooltip />
</LineChart>;
```

Use `SegmentBackground`, `SegmentLineFrom`, and `SegmentLineTo` independently — you do not need all three. Boundary lines support `variant="dashed" | "solid" | "gradient"`.

### Reading Selection Data

Use the `useChart` hook inside a child component to read the active selection:

```tsx
import { useChart } from "@/components/charts";

function SelectionStats({ onSelectionChange }) {
  const { selection, data, xAccessor } = useChart();

  useEffect(() => {
    if (!selection?.active) {
      onSelectionChange(null);
      return;
    }

    const startPoint = data[selection.startIndex];
    const endPoint = data[selection.endIndex];
    // Compute and report stats...
    onSelectionChange({ startPoint, endPoint });
  }, [selection, data, xAccessor, onSelectionChange]);

  return null;
}
```

### SegmentBackground

| Prop   | Type     | Default                           | Description                        |
| ------ | -------- | --------------------------------- | ---------------------------------- |
| `fill` | `string` | `var(--chart-segment-background)` | Fill color for the selected region |

### SegmentLineFrom / SegmentLineTo

| Prop          | Type                                | Default                     | Description |
| ------------- | ----------------------------------- | --------------------------- | ----------- |
| `stroke`      | `string`                            | `var(--chart-segment-line)` | Line color  |
| `strokeWidth` | `number`                            | `1`                         | Line width  |
| `variant`     | `"dashed" \| "solid" \| "gradient"` | `"dashed"`                  | Line style  |

## Theming

The chart uses CSS variables for theming. Define these in your CSS:

```css
:root {
  --chart-background: oklch(1 0 0);
  --chart-foreground: oklch(0.145 0.004 285);
  --chart-foreground-muted: oklch(0.55 0.014 260);
  --chart-line-primary: oklch(0.623 0.214 255);
  --chart-line-secondary: oklch(0.705 0.015 265);
  --chart-crosshair: oklch(0.4 0.1828 274.34);
  --chart-grid: oklch(0.9 0 0);
  --chart-tooltip-foreground: oklch(0.985 0 0);
  --chart-tooltip-muted: oklch(0.65 0.01 260);
  --chart-marker-background: oklch(0.97 0.005 260);
  --chart-marker-border: oklch(0.85 0.01 260);
  --chart-marker-foreground: oklch(0.3 0.01 260);
  --chart-marker-badge-background: oklch(0 0 0);
  --chart-marker-badge-foreground: oklch(1 0 0);
  --chart-segment-background: oklch(0.5 0 0 / 0.06);
  --chart-segment-line: oklch(0.5 0 0 / 0.25);
}

.dark {
  --chart-background: oklch(0.145 0 0);
  --chart-foreground: oklch(0.45 0 0);
  --chart-crosshair: oklch(0.45 0 0);
  --chart-grid: oklch(0.25 0 0);
  --chart-marker-background: oklch(0.25 0.01 260);
  --chart-marker-border: oklch(0.4 0.01 260);
  --chart-marker-foreground: oklch(0.9 0 0);
  --chart-marker-badge-background: oklch(1 0 0);
  --chart-marker-badge-foreground: oklch(0.15 0 0);
  --chart-segment-background: oklch(1 0 0 / 0.06);
  --chart-segment-line: oklch(1 0 0 / 0.25);
}
```

## Dependencies

This component requires the following packages:

```bash
pnpm add @visx/shape @visx/curve @visx/scale @visx/gradient @visx/responsive @visx/event @visx/grid d3-array motion react-use-measure
```

---

# Line Nav

> Vertical navigation with a line marker that expands on hover and active state.

Source: https://ui.cortexcn.dev/docs/components/line-nav

## Installation

```bash
npx shadcn@latest add @cortexcn/line-nav
```

## Usage

```tsx
import { LineNav } from "@/components/line-nav";
```

```tsx
const items = [
  { title: "Introduction", href: "#introduction" },
  { title: "Installation", href: "#installation" },
  { title: "Usage", href: "#usage" },
];

<LineNav items={items} activeHref="#introduction" />;
```

## Examples

### Controlled active item

Track the active item in state and update it from `onItemClick`.

### Next.js client-side navigation

Items render as plain anchors so the component works in any framework. For client-side navigation in Next.js, open `components/line-nav.tsx` and swap `motion.a` for `motion.create(Link)`:

```tsx
import Link from "next/link";

const MotionLink = motion.create(Link);

// Inside LineNavItem, render <MotionLink ...> instead of <motion.a ...>
```

## Props

### LineNav

| Prop                   | Type                                                                | Default  | Description                               |
| ---------------------- | ------------------------------------------------------------------- | -------- | ----------------------------------------- |
| `items`                | [`LineNavItem[]`](#linenavitem)                                     | required | Navigation items, top to bottom           |
| `activeHref`           | `string`                                                            | -        | Href of the active item                   |
| `scrollActiveIntoView` | `boolean`                                                           | `true`   | Scroll the active item into view on mount |
| `onItemClick`          | `(item: LineNavItem, event: MouseEvent<HTMLAnchorElement>) => void` | -        | Called when an item is clicked            |
| `className`            | `string`                                                            | -        | Extra classes for the `nav` element       |

### LineNavItem

| Property | Type     | Description                       |
| -------- | -------- | --------------------------------- |
| `title`  | `string` | Label shown next to the line      |
| `href`   | `string` | Link target, also used as the key |

---

# Live Line Chart

> Real-time streaming line chart with smooth scrolling, crosshair, and animated axes

Source: https://ui.cortexcn.dev/docs/components/live-line-chart

## Installation

```bash
npx shadcn@latest add @cortexcn/live-line-chart
```

## Usage

The Live Line Chart is built for **streaming time-series data**: a sliding time window, smooth interpolation, a live dot at the current value, and an interactive crosshair. Use it for stock tickers, crypto micro-prices, or any real-time metric.

Data is an array of `{ time: number, value: number }` where `time` is Unix seconds. You push new points as they arrive and pass the **latest value** so the chart can smoothly interpolate the display.

### Basic Example

```tsx
import {
  LiveLineChart,
  LiveLine,
  ChartTooltip,
  LiveXAxis,
  LiveYAxis,
} from "@/components/charts";

const [data, setData] = useState([]);
const [value, setValue] = useState(100);

// Append new points (e.g. from WebSocket or polling)
useEffect(() => {
  const id = setInterval(() => {
    const point = { time: Date.now() / 1000, value: fetchLatest() };
    setData((prev) => [...prev.slice(-500), point]);
    setValue(point.value);
  }, 1000);
  return () => clearInterval(id);
}, []);

<LiveLineChart data={data} value={value} window={30}>
  <LiveLine
    dataKey="value"
    stroke="var(--chart-line-primary)"
    formatValue={(v) => `$${v.toFixed(2)}`}
  />
  <ChartTooltip showDatePill={false} content={MyTooltipContent} />
  <LiveXAxis />
  <LiveYAxis position="left" formatValue={(v) => `$${v.toFixed(2)}`} />
</LiveLineChart>;
```

### Data Shape

Each point must have:

| Field   | Type     | Description          |
| ------- | -------- | -------------------- |
| `time`  | `number` | Unix time in seconds |
| `value` | `number` | Y-axis value         |

Use `dataKey` on `LiveLineChart` if your value field has a different name (default is `"value"`).

### Time Window and Now Offset

- **`window`** (default `30`): Visible time window in seconds. Older points scroll off the left.
- **`nowOffsetUnits`** (default `0`): How many X-tick units to leave between the live dot and the right edge. Use `1` to get a short leading gap and a visible fade on the line/area at the right.

```tsx
<LiveLineChart data={data} value={value} window={20} nowOffsetUnits={1}>
  <LiveLine dataKey="value" />
  {/* ... */}
</LiveLineChart>
```

### Pause Scrolling

Set **`paused`** to freeze the chart (e.g. while the user inspects). The "now" marker and domain stop advancing; new data can still be appended.

```tsx
const [paused, setPaused] = useState(false);

<LiveLineChart data={data} value={value} paused={paused}>
  {/* ... */}
</LiveLineChart>;
```

### Momentum Colors

Pass **`momentumColors`** to `LiveLine` to color the line, fill, and dot by short-term trend (up / down / flat).

```tsx
const momentumColors = {
  up: "var(--color-emerald-500)",
  down: "var(--color-red-500)",
  flat: "var(--color-zinc-400)",
};

<LiveLine
  dataKey="value"
  momentumColors={momentumColors}
  formatValue={(v) => `$${v.toFixed(2)}`}
/>;
```

### Live Line Props

| Prop             | Type                    | Default                     | Description                                  |
| ---------------- | ----------------------- | --------------------------- | -------------------------------------------- |
| `dataKey`        | `string`                | required                    | Key in data for y values                     |
| `stroke`         | `string`                | `var(--chart-line-primary)` | Line color (ignored if `momentumColors` set) |
| `strokeWidth`    | `number`                | `2`                         | Line width                                   |
| `fill`           | `boolean`               | `true`                      | Show gradient fill under curve               |
| `pulse`          | `boolean`               | `true`                      | Show pulsing live dot                        |
| `dotSize`        | `number`                | `4`                         | Radius of the live dot                       |
| `badge`          | `boolean`               | `true`                      | Show value badge at live tip                 |
| `formatValue`    | `(v: number) => string` | -                           | Formatter for badge (and optional tooltip)   |
| `momentumColors` | `MomentumColors`        | -                           | `{ up, down, flat }` colors by trend         |

### LiveLineChart Props

| Prop             | Type              | Default   | Description                             |
| ---------------- | ----------------- | --------- | --------------------------------------- |
| `data`           | `LiveLinePoint[]` | required  | Streaming points `{ time, value }`      |
| `value`          | `number`          | required  | Latest value (for smooth interpolation) |
| `dataKey`        | `string`          | `"value"` | Key for value field in context          |
| `window`         | `number`          | `30`      | Visible time window (seconds)           |
| `numXTicks`      | `number`          | `5`       | Number of X-axis ticks                  |
| `nowOffsetUnits` | `number`          | `0`       | Leading offset in X-tick units          |
| `exaggerate`     | `boolean`         | `false`   | Tighter Y-axis range                    |
| `lerpSpeed`      | `number`          | `0.08`    | Y-range interpolation speed (0–1)       |
| `margin`         | `Partial<Margin>` | -         | Chart margins                           |
| `paused`         | `boolean`         | `false`   | Freeze chart scrolling                  |

### LiveXAxis / LiveYAxis

- **LiveXAxis**: Time labels and a time pill that follows the crosshair. No required props.
- **LiveYAxis**: Animated value labels. Use **`position`** `"left"` or `"right"` and **`formatValue`** for display.

### Tooltip

Use **`ChartTooltip`** with **`showDatePill={false}`** and a custom **`content`** renderer so the time and value match the live chart. The crosshair and time pill stay in sync via shared context.

### Grid with Live Charts

If you use **Grid** inside `LiveLineChart`, you can pass **`rowTickValues`** (from context or derived from the same scale as `LiveYAxis`) so horizontal grid lines align with the Y-axis labels. See the [Grid](https://ui.cortexcn.dev/docs/utility/grid) docs for `rowTickValues`.

### Background

Use [`Background`](https://ui.cortexcn.dev/docs/utility/background) instead of `Grid` for a pattern fill behind the live line. See **Pattern Background** examples on the [live line chart gallery](https://ui.cortexcn.dev/charts/live-line-chart).

## Loading state

`LiveLineChart` has no loading status of its own. A live chart's loading state is just a line, so render a [`LineChartLoading`](https://ui.cortexcn.dev/docs/components/line-chart) while the stream connects, then swap in `LiveLineChart` once data starts arriving:

```tsx
import { LineChartLoading, LiveLineChart } from "@/components/charts";

function LiveRevenue({ connected, points }) {
  if (!connected) {
    return <LineChartLoading loadingStyle="sweep" />;
  }
  return <LiveLineChart data={points} /* … */ />;
}
```

`loadingStyle="sweep"` gives the diagonal shimmer; omit it for the default traveling pulse. See the [Line Chart loading docs](https://ui.cortexcn.dev/docs/components/line-chart#loading-state) for the full set of loading props.

## Theming

Uses the same chart CSS variables as the Line Chart (`--chart-line-primary`, `--chart-grid`, `--chart-tooltip-*`, etc.). The live dot and badge use the line color or `momentumColors` when provided.

## Dependencies

```bash
pnpm add @visx/shape @visx/curve @visx/scale @visx/responsive @visx/event d3-array motion
```

---

# Logos Carousel

> Cycle through logos column by column in a staggered wave.

Source: https://ui.cortexcn.dev/docs/components/logos-carousel

## Installation

```bash
npx shadcn@latest add @cortexcn/logos-carousel
```

## Usage

```tsx
import { LogosCarousel } from "@/components/logos-carousel";
```

```tsx
<LogosCarousel className="h-16" columnCount={4}>
  <img src="/logos/vercel.svg" alt="Vercel" />
  <img src="/logos/nextjs.svg" alt="Next.js" />
  <img src="/logos/react.svg" alt="React" />
  <img src="/logos/stripe.svg" alt="Stripe" />
  {/* ...more logos */}
</LogosCarousel>
```

Each child is one logo. Logos are spread across the columns in order, so with 12 logos and 4 columns each column cycles through 3 logos. Give the carousel a height so the logos have room to animate.

## Examples

### Right to left

Set `direction="rtl"` to start the wave from the last column.

### Fewer columns

`columnCount` controls how many logos are visible at once. It is capped at the number of logos.

## Behavior

- The carousel only cycles while it is on screen and the browser tab is visible.
- With reduced motion enabled, logos cross-fade in place instead of sliding and blurring.
- Set the `--column-count` CSS variable to change the visible columns at a breakpoint, for example `className="[--column-count:2] md:[--column-count:4]"`.

## Props

| Prop          | Type             | Default  | Description                                   |
| ------------- | ---------------- | -------- | --------------------------------------------- |
| `children`    | `ReactNode`      | required | Logo elements to cycle through                |
| `columnCount` | `number`         | `4`      | Number of columns, capped at the logo count   |
| `direction`   | `"ltr" \| "rtl"` | `"ltr"`  | Direction the wave travels across the columns |
| `className`   | `string`         | -        | Extra classes for the grid container          |

---

# Marquee

> An infinite scrolling component that can be used to display text, images, or videos.

Source: https://ui.cortexcn.dev/docs/components/marquee

## Installation

```bash
npx shadcn@latest add @cortexcn/marquee
```

The CLI also adds the `animate-marquee` and `animate-marquee-vertical` animations to your `globals.css`. For a manual install, copy the CSS shown in the **Manual** tab.

## Usage

```tsx
import { Marquee } from "@/components/marquee";
```

```tsx
<Marquee pauseOnHover>
  <span>Next.js</span>
  <span>React</span>
  <span>Tailwind CSS</span>
</Marquee>
```

## Examples

### Two rows

Pair a normal row with a `reverse` row, then fade the edges with gradients.

### Vertical

Set `vertical` to scroll top to bottom. Give the parent a fixed height.

### Speed and spacing

The marquee reads two CSS variables. Override them with a class:

```tsx
<Marquee className="[--duration:20s] [--gap:2rem]">{children}</Marquee>
```

| Variable     | Default | Description                                   |
| ------------ | ------- | --------------------------------------------- |
| `--duration` | `40s`   | Time for one full loop. Lower is faster.      |
| `--gap`      | `1rem`  | Space between items and between repeated sets |

## Props

| Prop           | Type        | Default  | Description                                   |
| -------------- | ----------- | -------- | --------------------------------------------- |
| `children`     | `ReactNode` | required | Content to scroll                             |
| `reverse`      | `boolean`   | `false`  | Scroll in the opposite direction              |
| `pauseOnHover` | `boolean`   | `false`  | Pause the animation while hovered             |
| `vertical`     | `boolean`   | `false`  | Scroll vertically instead of horizontally     |
| `repeat`       | `number`    | `4`      | How many copies of the content are rendered   |
| `className`    | `string`    | -        | Extra classes, including `--duration`/`--gap` |

All other `div` props are passed to the root element.

---

# Menubar

> A persistent menu, common in desktop apps, with quick access to a set of commands.

Source: https://ui.cortexcn.dev/docs/components/menubar

## Installation

```bash
npx shadcn@latest add @cortexcn/menubar
```

## Usage

```tsx
import { Menubar, MenubarPortal, MenubarMenu, MenubarTrigger, MenubarContent, MenubarGroup, MenubarSeparator, MenubarLabel, MenubarItem, MenubarShortcut, MenubarCheckboxItem, MenubarRadioGroup, MenubarRadioItem, MenubarSub, MenubarSubTrigger, MenubarSubContent } from "@/components/menubar";
```

## Examples

### Basic

### With submenu

### With checkboxes

### With radio

### With icons

### With shortcuts

### Format

### Insert

### Destructive

### In dialog

### With inset

---

# Native Select

> A styled native HTML select element.

Source: https://ui.cortexcn.dev/docs/components/native-select

## Installation

```bash
npx shadcn@latest add @cortexcn/native-select
```

## Usage

```tsx
import { NativeSelect, NativeSelectOptGroup, NativeSelectOption } from "@/components/native-select";
```

## Examples

### Basic

### With groups

### Sizes

### With field

### Disabled

### Invalid

---

# Navigation Menu

> A collection of links for navigating websites.

Source: https://ui.cortexcn.dev/docs/components/navigation-menu

## Installation

```bash
npx shadcn@latest add @cortexcn/navigation-menu
```

## Usage

```tsx
import { NavigationMenu, NavigationMenuList, NavigationMenuItem, NavigationMenuContent, NavigationMenuTrigger, NavigationMenuLink, NavigationMenuIndicator, NavigationMenuViewport, navigationMenuTriggerStyle } from "@/components/navigation-menu";
```

## Examples

### With viewport

### Without viewport

---

# Number Ticker

> A rolling digit ticker that counts to a value with per-digit stagger, padding, and blur.

Source: https://ui.cortexcn.dev/docs/components/number-ticker

## Installation

```bash
npx shadcn@latest add @cortexcn/number-ticker
```

## Usage

```tsx
import { NumberTicker } from "@/components/number-ticker";
```

```tsx
<NumberTicker value={12480} prefix="$" locale blur />
```

Each digit is a column of 0 to 9 that rolls to its place. The first time the ticker scrolls into view, the digits roll in one after another; after that, a new `value` rolls every digit at once, so live updates never lag.

## Examples

### Padded

`pad` adds leading zeros, which suits counters and scoreboards.

## Behavior

- Screen readers get the full value once, as plain text, instead of every digit.
- With reduced motion enabled, digits jump straight to the new value with no roll or blur.
- `locale` is safe in server components. `format` takes a function, so it only works where the ticker renders on the client.

## Props

| Prop             | Type                        | Default | Description                                      |
| ---------------- | --------------------------- | ------- | ------------------------------------------------ |
| `value`          | `number`                    | -       | The number to show, rounded to a whole number    |
| `pad`            | `number`                    | -       | Pad with leading zeros to this many digits       |
| `duration`       | `number`                    | `0.9`   | Seconds each digit takes to roll                 |
| `stagger`        | `number`                    | `0.04`  | Seconds between digits on the first roll         |
| `startOnView`    | `boolean`                   | `true`  | Wait until the ticker scrolls into view          |
| `prefix`         | `string`                    | -       | Text before the number, such as `$`              |
| `suffix`         | `string`                    | -       | Text after the number, such as `%`               |
| `blur`           | `boolean`                   | `false` | Blur the digits briefly while they roll          |
| `locale`         | `boolean`                   | -       | Add thousands separators for the reader's locale |
| `format`         | `(value: number) => string` | -       | Custom formatting, used instead of `locale`      |
| `className`      | `string`                    | -       | Extra classes for the ticker                     |
| `digitClassName` | `string`                    | -       | Extra classes for each digit column              |

---

# Pagination

> Page navigation with next and previous links.

Source: https://ui.cortexcn.dev/docs/components/pagination

## Installation

```bash
npx shadcn@latest add @cortexcn/pagination
```

## Usage

```tsx
import { Pagination, PaginationContent, PaginationEllipsis, PaginationItem, PaginationLink, PaginationNext, PaginationPrevious } from "@/components/pagination";
```

## Examples

### Basic

### Simple

### With select

---

# Perspective Marquee

> A tilted wall of images that scrolls endlessly in alternating columns.

Source: https://ui.cortexcn.dev/docs/components/perspective-marquee

## Features

- Columns scroll in opposite directions, forever, with no gaps or jumps.
- Hovering a column pauses it, and hovering an image lifts it.
- The wall scales down on small screens and fades out at the edges.
- Built on [Marquee](https://ui.cortexcn.dev/docs/components/marquee), so it needs no animation library.
- Respects reduced motion by pausing the columns.

## Installation

```bash
npx shadcn@latest add @cortexcn/perspective-marquee
```

The CLI also installs [Marquee](https://ui.cortexcn.dev/docs/components/marquee) and adds its animations to your `globals.css`.

## Usage

```tsx
import { PerspectiveMarquee } from "@/components/perspective-marquee";
```

```tsx
<PerspectiveMarquee
  images={[
    { src: "/screens/dashboard.png", alt: "Dashboard" },
    { src: "/screens/pricing.png", alt: "Pricing page" },
  ]}
/>
```

Images are spread across the columns in order, so the first image goes to the first column, the second to the second, and so on. Around 12 to 20 images fill the wall well. Images use a 4:3 frame and `object-cover`.

## Examples

### Three columns

### As a hero background

Place it behind your content with `absolute inset-0` and lower its opacity so text stays readable.

## Props

| Prop           | Type                        | Default  | Description                                          |
| -------------- | --------------------------- | -------- | ---------------------------------------------------- |
| `images`       | `PerspectiveMarqueeImage[]` | required | Images for the wall, each with `src` and `alt`       |
| `columns`      | `number`                    | `4`      | Number of scrolling columns                          |
| `duration`     | `number`                    | `40`     | Seconds for one loop. Every other column runs slower |
| `pauseOnHover` | `boolean`                   | `true`   | Pause a column while the pointer is over it          |
| `className`    | `string`                    | -        | Extra classes for the container, such as a height    |

---

# Pie Chart

> A composable pie and donut chart with animated slices, hover interactions, patterns, gradients, and an interactive legend

Source: https://ui.cortexcn.dev/docs/components/pie-chart

## Installation

```bash
npx shadcn@latest add @cortexcn/pie-chart
```

## Usage

The Pie Chart uses a composable API similar to other charts in the library. Build charts by combining components:

```tsx
import { PieChart, PieSlice } from "@/components/charts";

const data = [
  { label: "Electronics", value: 4250, color: "#0ea5e9" },
  { label: "Clothing", value: 3120, color: "#a855f7" },
  { label: "Food", value: 2100, color: "#f59e0b" },
];

export default function SalesChart() {
  return (
    <PieChart data={data} size={280}>
      {data.map((_, index) => (
        <PieSlice key={index} index={index} />
      ))}
    </PieChart>
  );
}
```

## Components

### PieChart

The root component that provides context to all children.

| Prop            | Type                              | Default  | Description                                   |
| --------------- | --------------------------------- | -------- | --------------------------------------------- |
| `data`          | `PieData[]`                       | required | Array of pie data items                       |
| `size`          | `number`                          | auto     | Fixed size in pixels (uses parent if not set) |
| `innerRadius`   | `number`                          | `0`      | Inner radius for donut charts (0 = solid pie) |
| `padAngle`      | `number`                          | `0`      | Padding angle between slices (radians)        |
| `cornerRadius`  | `number`                          | `0`      | Corner radius for rounded slice edges         |
| `startAngle`    | `number`                          | `-PI/2`  | Start angle in radians (top)                  |
| `endAngle`      | `number`                          | `3*PI/2` | End angle in radians (full circle)            |
| `hoveredIndex`  | `number \| null`                  | -        | Controlled hover state                        |
| `onHoverChange` | `(index: number \| null) => void` | -        | Hover state callback                          |
| `className`     | `string`                          | `""`     | Additional CSS class                          |

### PieSlice

Renders an individual slice with animated arc and hover effects.

| Prop          | Type                              | Default           | Description                                                    |
| ------------- | --------------------------------- | ----------------- | -------------------------------------------------------------- |
| `index`       | `number`                          | required          | Index of the slice in the data array                           |
| `color`       | `string`                          | from data/palette | Optional color override                                        |
| `fill`        | `string`                          | -                 | Optional fill for patterns/gradients (e.g., `url(#patternId)`) |
| `animate`     | `boolean`                         | `true`            | Enable animation on mount                                      |
| `showGlow`    | `boolean`                         | `true`            | Show glow effect on hover                                      |
| `hoverEffect` | `"translate" \| "grow" \| "none"` | `"translate"`     | Hover animation type                                           |
| `hoverOffset` | `number`                          | `10`              | Distance in pixels for hover effect                            |

### PieCenter

Displays content in the center of a donut chart. Only renders when `innerRadius > 0`.

| Prop            | Type               | Default   | Description                         |
| --------------- | ------------------ | --------- | ----------------------------------- |
| `defaultLabel`  | `string`           | `"Total"` | Label shown when not hovering       |
| `formatOptions` | `NumberFlowFormat` | -         | Number formatting options           |
| `prefix`        | `string`           | -         | Prefix before the value (e.g., "$") |
| `suffix`        | `string`           | -         | Suffix after the value (e.g., "%")  |
| `children`      | `function`         | -         | Custom render function              |
| `className`     | `string`           | `""`      | Additional CSS class                |

### Legend

A composable legend component for pie charts and other visualizations. See the full [Legend documentation](https://ui.cortexcn.dev/docs/components/legend) for all components and options.

## Data Shape

```ts
interface PieData {
  label: string; // Display label
  value: number; // Value (determines slice size)
  color?: string; // Optional color (falls back to palette)
  fill?: string; // Optional fill for patterns/gradients
}

interface LegendItemData {
  label: string;
  value: number;
  color: string;
}
```

See the [charts gallery](https://ui.cortexcn.dev/charts/pie-chart) for donut charts, patterns, gradients, legend sync, and hover effects.

## Theming

The Pie Chart uses CSS variables for theming. Slice colors default to `--chart-1` through `--chart-5`:

```css
:root {
  --chart-1: oklch(0.646 0.222 41.116);
  --chart-2: oklch(0.6 0.118 184.704);
  --chart-3: oklch(0.398 0.07 227.392);
  --chart-4: oklch(0.828 0.189 84.429);
  --chart-5: oklch(0.769 0.188 70.08);
}

.dark {
  --chart-1: oklch(0.488 0.243 264.376);
  --chart-2: oklch(0.696 0.17 162.48);
  --chart-3: oklch(0.769 0.188 70.08);
  --chart-4: oklch(0.627 0.265 303.9);
  --chart-5: oklch(0.645 0.246 16.439);
}
```

## Animation

The pie chart features animations on mount:

1. **Slice Appearance** - Slices animate in with staggered timing
2. **Hover Effects** - Slices scale up on hover with glow effect
3. **Fade Effect** - Non-hovered slices fade when another slice is hovered
4. **Center Content** - Value animates when switching between slices

All animations use spring physics for natural motion.

## Dependencies

```bash
pnpm add @visx/shape @visx/group @visx/responsive @visx/pattern @visx/gradient d3-shape motion
```

---

# Popover

> Displays rich content in a portal, triggered by a button.

Source: https://ui.cortexcn.dev/docs/components/popover

## Installation

```bash
npx shadcn@latest add @cortexcn/popover
```

## Usage

```tsx
import { Popover, PopoverAnchor, PopoverContent, PopoverDescription, PopoverHeader, PopoverTitle, PopoverTrigger } from "@/components/popover";
```

## Examples

### Basic

### With form

### Alignments

### In dialog

---

# Profit/Loss Line

> Sign-colored line segments for profit and loss on a shared zero baseline

Source: https://ui.cortexcn.dev/docs/components/profit-loss-line

## Installation

```bash
npx shadcn@latest add @cortexcn/profit-loss-line
```

## Usage

Use `ProfitLossLine` inside `LineChart` for a single series that crosses zero. Pair it with a hidden `Line` (same `dataKey`) so the chart registers the series for the y-domain and tooltip. Highlight the zero baseline with `Grid highlightRowValues`.

```tsx
import {
  LineChart,
  Line,
  Grid,
  XAxis,
  ChartTooltip,
  ProfitLossLine,
  profitLossColor,
  resolveProfitLossTooltipLabel,
} from "@/components/charts";
import { curveLinear } from "@visx/curve";

const data = [
  { date: new Date("2024-01-01"), pnl: 420 },
  { date: new Date("2024-01-02"), pnl: -180 },
  // ...
];

export default function ProfitLossChart() {
  return (
    <LineChart data={data}>
      <Grid highlightRowValues={[0]} horizontal />
      <Line
        curve={curveLinear}
        dataKey="pnl"
        fadeEdges={false}
        showHighlight={false}
        stroke="transparent"
        strokeWidth={0}
      />
      <ProfitLossLine dataKey="pnl" />
      <XAxis />
      <ChartTooltip
        indicatorColor={(point) => profitLossColor((point.pnl as number) ?? 0)}
        rows={(point) => {
          const value = (point.pnl as number) ?? 0;
          return [
            {
              color: profitLossColor(value),
              label: resolveProfitLossTooltipLabel(""),
              value,
            },
          ];
        }}
      />
    </LineChart>
  );
}
```

## Components

### ProfitLossLine

Renders linear segments colored by sign. Values ≥ 0 use emerald; values &lt; 0 use red (Tailwind CSS variables by default).

| Prop            | Type           | Default                    | Description                                   |
| --------------- | -------------- | -------------------------- | --------------------------------------------- |
| `dataKey`       | `string`       | required                   | Key in data for y values                      |
| `xDataKey`      | `string`       | `"date"`                   | Key in data for x values                      |
| `strokeWidth`   | `number`       | `2.5`                      | Line width                                    |
| `curve`         | `CurveFactory` | `curveLinear`              | Interpolation curve (same as `Line`)          |
| `fadeEdges`     | `FadeEdges`    | `false`                    | Fade stroke toward transparent at chart edges |
| `positiveColor` | `string`       | `var(--color-emerald-500)` | Color for profit segments                     |
| `negativeColor` | `string`       | `var(--color-red-500)`     | Color for loss segments                       |

### ProfitLossLegend

Optional legend with Profit/Loss items. Hover dims the opposite segment when wrapped with `ProfitLossLegendHoverProvider`.

| Prop            | Type                              | Default   | Description            |
| --------------- | --------------------------------- | --------- | ---------------------- |
| `hoveredIndex`  | `number \| null`                  | `null`    | Controlled hover index |
| `onHoverChange` | `(index: number \| null) => void` | —         | Hover callback         |
| `align`         | `"start" \| "center" \| "end"`    | `"start"` | Horizontal alignment   |
| `className`     | `string`                          | —         | Additional CSS class   |

### Grid zero line

Use `highlightRowValues={[0]}` on `Grid` to emphasize the break-even baseline:

```tsx
<Grid
  highlightRowValues={[0]}
  highlightRowStroke="var(--foreground)"
  highlightRowStrokeOpacity={0.35}
  horizontal
/>
```

See the [Line Chart](https://ui.cortexcn.dev/docs/components/line-chart) docs for full `Grid` props.

### Background

Use [`Background`](https://ui.cortexcn.dev/docs/utility/background) instead of `Grid` for a pattern fill behind the profit/loss line. See **Pattern Background** examples on the [line chart gallery](https://ui.cortexcn.dev/charts/line-chart).

## Gallery

Interactive examples live on the [line chart gallery](https://ui.cortexcn.dev/charts/line-chart) under **Profit/Loss**.

---

# Progress

> Displays an indicator showing the completion progress of a task.

Source: https://ui.cortexcn.dev/docs/components/progress

## Installation

```bash
npx shadcn@latest add @cortexcn/progress
```

## Usage

```tsx
import { Progress } from "@/components/progress";
```

## Examples

### Progress bar

### With label

### Controlled

### File upload list

---

# Radar Chart

> A composable multi-series radar chart with animated polygons, hover interactions, and customizable metrics

Source: https://ui.cortexcn.dev/docs/components/radar-chart

## Installation

```bash
npx shadcn@latest add @cortexcn/radar-chart
```

## Usage

The Radar Chart uses a composable API. Define your metrics and data, then combine components:

```tsx
import {
  RadarChart,
  RadarGrid,
  RadarAxis,
  RadarLabels,
  RadarArea,
} from "@/components/charts";

const metrics = [
  { key: "speed", label: "Speed" },
  { key: "power", label: "Power" },
  { key: "technique", label: "Technique" },
];

const data = [
  {
    label: "Player A",
    color: "#3b82f6",
    values: { speed: 85, power: 70, technique: 90 },
  },
  {
    label: "Player B",
    color: "#f59e0b",
    values: { speed: 65, power: 95, technique: 60 },
  },
];

export default function PerformanceRadar() {
  return (
    <RadarChart data={data} metrics={metrics} size={400}>
      <RadarGrid />
      <RadarAxis />
      <RadarLabels />
      {data.map((item, index) => (
        <RadarArea key={item.label} index={index} />
      ))}
    </RadarChart>
  );
}
```

## Components

### RadarChart

The root container that provides context to all children.

| Prop            | Type                              | Default  | Description            |
| --------------- | --------------------------------- | -------- | ---------------------- |
| `data`          | `RadarData[]`                     | required | Array of data series   |
| `metrics`       | `RadarMetric[]`                   | required | Metrics to display     |
| `size`          | `number`                          | auto     | Fixed size in pixels   |
| `levels`        | `number`                          | `5`      | Number of grid circles |
| `margin`        | `number`                          | `60`     | Margin around chart    |
| `animate`       | `boolean`                         | `true`   | Enable animations      |
| `hoveredIndex`  | `number \| null`                  | -        | Controlled hover state |
| `onHoverChange` | `(index: number \| null) => void` | -        | Hover callback         |
| `className`     | `string`                          | `""`     | Additional CSS class   |

### RadarGrid

Renders the circular grid lines (spider web pattern).

| Prop         | Type      | Default | Description             |
| ------------ | --------- | ------- | ----------------------- |
| `showLabels` | `boolean` | `true`  | Show level value labels |
| `className`  | `string`  | `""`    | Additional CSS class    |

### RadarAxis

Renders axis lines from center to each metric.

| Prop        | Type     | Default | Description          |
| ----------- | -------- | ------- | -------------------- |
| `className` | `string` | `""`    | Additional CSS class |

### RadarLabels

Renders metric labels around the perimeter.

| Prop          | Type      | Default | Description                    |
| ------------- | --------- | ------- | ------------------------------ |
| `offset`      | `number`  | `24`    | Distance from chart edge       |
| `fontSize`    | `number`  | `11`    | Font size for labels           |
| `interactive` | `boolean` | `false` | Enable hover effects on labels |
| `className`   | `string`  | `""`    | Additional CSS class           |

### RadarArea

Renders a single data polygon with hover effects.

| Prop         | Type      | Default   | Description               |
| ------------ | --------- | --------- | ------------------------- |
| `index`      | `number`  | required  | Index in the data array   |
| `color`      | `string`  | from data | Optional color override   |
| `showPoints` | `boolean` | `true`    | Show data point circles   |
| `showGlow`   | `boolean` | `true`    | Show glow effect on hover |
| `className`  | `string`  | `""`      | Additional CSS class      |

## Data Shape

```ts
interface RadarMetric {
  key: string; // Unique identifier
  label: string; // Display label
}

interface RadarData {
  label: string; // Series label
  color: string; // Series color
  values: Record<string, number>; // metric key -> value (0-100)
}
```

See the [charts gallery](https://ui.cortexcn.dev/charts/radar-chart) for minimal styles, legend sync, and layout variations.

## Theming

`RadarGrid` and `RadarAxis` stroke defaults use `radarCssVars.border` → **`var(--border)`** — the same token as ring tracks and gauge inactive notches. Override `--border` in your theme or pass a custom `stroke` prop.

Series fill colors default to `--chart-1` through `--chart-5` via `defaultRadarColors`.

## Hooks

### useRadar

Access the radar context from any child component:

```tsx
import { useRadar } from "@/components/charts";

function CustomComponent() {
  const {
    data,
    metrics,
    radius,
    hoveredIndex,
    setHoveredIndex,
    getPointPosition,
  } = useRadar();
  // ...
}
```

## Animation

The radar chart features a multi-phase animation on mount:

1. **Grid Expansion** - Concentric circles scale in from center
2. **Axis Growth** - Lines grow outward from center
3. **Label Fade** - Metric labels fade in
4. **Area Expansion** - Data polygons animate from center to values

All animations use spring physics for natural motion. Hover interactions are instant with no delays.

## Dependencies

```bash
pnpm add @visx/group @visx/responsive @visx/scale @visx/shape motion
```

---

# Radio Group

> A set of checkable buttons where no more than one can be checked at a time.

Source: https://ui.cortexcn.dev/docs/components/radio-group

## Installation

```bash
npx shadcn@latest add @cortexcn/radio-group
```

## Usage

```tsx
import { RadioGroup, RadioGroupItem } from "@/components/radio-group";
```

## Examples

### Basic

### With descriptions

### With FieldSet

### Grid layout

### Disabled

### Invalid

---

# Resizable

> Accessible resizable panel groups and layouts with keyboard support.

Source: https://ui.cortexcn.dev/docs/components/resizable

## Installation

```bash
npx shadcn@latest add @cortexcn/resizable
```

## Usage

```tsx
import { ResizableHandle, ResizablePanel, ResizablePanelGroup } from "@/components/resizable";
```

## Examples

### Horizontal

### Vertical

### With handle

### Nested

### Controlled

---

# Ring Chart

> A composable multi-ring progress chart with animated arcs, hover interactions, and a reusable legend component

Source: https://ui.cortexcn.dev/docs/components/ring-chart

## Installation

```bash
npx shadcn@latest add @cortexcn/ring-chart
```

## Usage

The Ring Chart uses a composable API similar to other charts in the library. Build charts by combining components:

```tsx
import { RingChart, Ring, RingCenter } from "@/components/charts";

const data = [
  { label: "Organic", value: 4250, maxValue: 5000, color: "#0ea5e9" },
  { label: "Paid", value: 3120, maxValue: 5000, color: "#a855f7" },
  { label: "Email", value: 2100, maxValue: 5000, color: "#f59e0b" },
];

export default function SessionsChart() {
  return (
    <RingChart data={data} size={300}>
      {data.map((item, index) => (
        <Ring key={item.label} index={index} />
      ))}
      <RingCenter defaultLabel="Total Sessions" />
    </RingChart>
  );
}
```

## Components

### RingChart

The root component that provides context to all children.

| Prop              | Type                              | Default  | Description                                   |
| ----------------- | --------------------------------- | -------- | --------------------------------------------- |
| `data`            | `RingData[]`                      | required | Array of ring data items                      |
| `size`            | `number`                          | auto     | Fixed size in pixels (uses parent if not set) |
| `strokeWidth`     | `number`                          | `12`     | Width of each ring                            |
| `ringGap`         | `number`                          | `6`      | Gap between rings                             |
| `baseInnerRadius` | `number`                          | `60`     | Inner radius of the innermost ring            |
| `hoveredIndex`    | `number \| null`                  | -        | Controlled hover state                        |
| `onHoverChange`   | `(index: number \| null) => void` | -        | Hover state callback                          |
| `className`       | `string`                          | `""`     | Additional CSS class                          |

### Ring

Renders an individual ring with background track and animated progress arc.

| Prop       | Type                | Default           | Description                         |
| ---------- | ------------------- | ----------------- | ----------------------------------- |
| `index`    | `number`            | required          | Index of the ring in the data array |
| `color`    | `string`            | from data/palette | Optional color override             |
| `animate`  | `boolean`           | `true`            | Enable animation on mount           |
| `showGlow` | `boolean`           | `true`            | Show glow effect on hover           |
| `lineCap`  | `"round" \| "butt"` | `"round"`         | Line cap style for ring ends        |

### RingCenter

Displays the total or hovered value in the center of the chart.

| Prop           | Type                        | Default            | Description                   |
| -------------- | --------------------------- | ------------------ | ----------------------------- |
| `defaultLabel` | `string`                    | `"Total"`          | Label shown when not hovering |
| `formatValue`  | `(value: number) => string` | `toLocaleString()` | Format function for values    |
| `children`     | `function`                  | -                  | Custom render function        |
| `className`    | `string`                    | `""`               | Additional CSS class          |

### Legend

A composable legend component for ring charts, pie charts, and other visualizations. See the full [Legend documentation](https://ui.cortexcn.dev/docs/components/legend) for all components and options.

## Data Shape

```ts
interface RingData {
  label: string; // Display label
  value: number; // Current value
  maxValue: number; // Maximum value (for percentage)
  color?: string; // Optional color (falls back to palette)
}

interface LegendItem {
  label: string;
  value: number;
  maxValue?: number; // Required if showProgress is true
  color: string;
}
```

See the [charts gallery](https://ui.cortexcn.dev/charts/ring-chart) for custom colors, legend sync, and center content variations.

## Theming

The Ring Chart uses CSS variables for theming. The ring track uses `--border` (same as radar grid lines), and ring colors default to `--chart-1` through `--chart-5`:

```css
:root {
  --border: oklch(0.92 0.004 286.32);
  --chart-1: oklch(0.646 0.222 41.116);
  --chart-2: oklch(0.6 0.118 184.704);
  --chart-3: oklch(0.398 0.07 227.392);
  --chart-4: oklch(0.828 0.189 84.429);
  --chart-5: oklch(0.769 0.188 70.08);
}

.dark {
  --border: oklch(0.56 0.0195 267.65 / 0.2);
  --chart-1: oklch(0.488 0.243 264.376);
  --chart-2: oklch(0.696 0.17 162.48);
  --chart-3: oklch(0.769 0.188 70.08);
  --chart-4: oklch(0.627 0.265 303.9);
  --chart-5: oklch(0.645 0.246 16.439);
}
```

## Animation

The ring chart features a multi-phase animation on mount:

1. **Ring Expansion** - Background rings scale in with staggered timing
2. **Progress Arcs** - Progress arcs animate from 0 to their target value
3. **Center Content** - Value and label fade in
4. **Legend** - Items slide in from the right with progress bars filling

All animations use spring physics for natural motion.

## Dependencies

```bash
pnpm add @visx/shape @visx/group @visx/responsive motion
```

---

# Sankey Chart

> A composable sankey diagram for visualizing flow between nodes with animated links and interactive tooltips

Source: https://ui.cortexcn.dev/docs/components/sankey-chart

## Installation

```bash
npx shadcn@latest add @cortexcn/sankey-chart
```

## Usage

The Sankey Chart uses a composable API similar to other charts. Build diagrams by combining components:

```tsx
import {
  SankeyChart,
  SankeyNode,
  SankeyLink,
  SankeyTooltip,
} from "@/components/charts";

const data = {
  nodes: [
    { name: "Organic Search", category: "source" },
    { name: "Homepage", category: "landing" },
    { name: "Converted", category: "outcome" },
  ],
  links: [
    { source: 0, target: 1, value: 100 },
    { source: 1, target: 2, value: 80 },
  ],
};

export default function FlowDiagram() {
  return (
    <SankeyChart data={data}>
      <SankeyLink />
      <SankeyNode lineCap={4} labelOrientation="vertical" />
      <SankeyTooltip />
    </SankeyChart>
  );
}
```

## Components

### SankeyChart

The root component that computes the layout and provides context to children.

| Prop                | Type              | Default                                          | Description                            |
| ------------------- | ----------------- | ------------------------------------------------ | -------------------------------------- |
| `data`              | `SankeyData`      | required                                         | Object with `nodes` and `links` arrays |
| `margin`            | `Partial<Margin>` | `{ top: 40, right: 180, bottom: 40, left: 180 }` | Chart margins                          |
| `animationDuration` | `number`          | `1100`                                           | Animation duration in ms               |
| `aspectRatio`       | `string`          | `"2 / 1"`                                        | CSS aspect ratio                       |
| `nodeWidth`         | `number`          | `16`                                             | Width of nodes in pixels               |
| `nodePadding`       | `number`          | `24`                                             | Vertical padding between nodes         |
| `className`         | `string`          | `""`                                             | Additional CSS class                   |

### SankeyNode

Renders the nodes (bars) in the diagram with animated initialization and internal labels.

| Prop               | Type                         | Default        | Description                                                                            |
| ------------------ | ---------------------------- | -------------- | -------------------------------------------------------------------------------------- |
| `fill`             | `string`                     | -              | Fill color for all nodes                                                               |
| `lineCap`          | `number`                     | `4`            | Corner radius for nodes                                                                |
| `fadedOpacity`     | `number`                     | `0.4`          | Opacity when another element is hovered                                                |
| `showLabels`       | `boolean`                    | `true`         | Show node name labels                                                                  |
| `showValueLabels`  | `boolean`                    | `true`         | Show session count under node names                                                    |
| `labelOrientation` | `"horizontal" \| "vertical"` | `"horizontal"` | Reading direction for outside labels. Vertical rotates labels 90° along the node edge. |
| `getNodeColor`     | `(node, index) => string`    | -              | Custom color function                                                                  |

### SankeyLink

Renders the links (flows) between nodes with animated path reveal and gradient colors.

| Prop             | Type                              | Default | Description                                          |
| ---------------- | --------------------------------- | ------- | ---------------------------------------------------- |
| `stroke`         | `string`                          | -       | Solid stroke color (overrides gradient)              |
| `strokeOpacity`  | `number`                          | `0.7`   | Link opacity                                         |
| `fadedOpacity`   | `number`                          | `0.1`   | Opacity when another element is hovered              |
| `useGradient`    | `boolean`                         | `true`  | Use gradient from source to target node color        |
| `getNodeColor`   | `(node, index) => string`         | -       | Custom node color function for gradients             |
| `getLinkColor`   | `(link, index) => string`         | -       | Custom link color (overrides gradient)               |
| `patterns`       | `ReactNode`                       | -       | Pattern definitions using `@visx/pattern` components |
| `getLinkPattern` | `(link, index) => string \| null` | -       | Return pattern ID for a link, or null for gradient   |

### SankeyTooltip

Displays tooltips for nodes and links on hover.

| Prop          | Type                   | Default          | Description                  |
| ------------- | ---------------------- | ---------------- | ---------------------------- |
| `nodeContent` | `(props) => ReactNode` | -                | Custom node tooltip renderer |
| `linkContent` | `(props) => ReactNode` | -                | Custom link tooltip renderer |
| `formatValue` | `(value) => string`    | `toLocaleString` | Value formatter              |
| `className`   | `string`               | `""`             | Additional CSS class         |

## Data Format

The sankey data follows the d3-sankey format:

```typescript
interface SankeyData {
  nodes: Array<{
    name: string;
    category: "source" | "landing" | "outcome";
    [key: string]: unknown;
  }>;
  links: Array<{
    source: number; // Index into nodes array
    target: number; // Index into nodes array
    value: number; // Flow value
  }>;
}
```

## Label orientation

Outside node labels default to horizontal text on the left or right of each column. Pass `labelOrientation="vertical"` on `SankeyNode` to rotate labels 90° along the node edge — the node name and session count stay on separate lines, stacked along the reading direction. Use wider side margins so rotated labels are not clipped.

```tsx
<SankeyChart data={data} margin={{ top: 40, right: 80, bottom: 40, left: 80 }}>
  <SankeyLink />
  <SankeyNode labelOrientation="vertical" />
  <SankeyTooltip />
</SankeyChart>
```

## Animation

The sankey chart uses the same animation system as other charts:

- **Nodes**: ScaleY and opacity fade in, staggered by index
- **Links**: Grow from source to target node using stroke-dashoffset animation
- **Gradients**: Links use gradient colors flowing from source node color to target node color
- **Easing**: `cubic-bezier(0.85, 0, 0.15, 1)` for smooth, organic motion

### Animation Timeline

- **0-600ms**: Nodes fade/scale in (staggered)
- **200-1100ms**: Links grow from source to target (staggered, starts after nodes begin appearing)

## Hover Behavior

When hovering over a node or link:

- Hovered link and its source/target nodes stay at full opacity
- Connected nodes and links remain visible
- All other links and nodes fade
- Tooltip appears showing relevant data

See the [charts gallery](https://ui.cortexcn.dev/charts/sankey-chart) for label-free layouts and pattern fills.

## Dependencies

This component requires:

```bash
pnpm add @visx/sankey @visx/responsive @visx/pattern motion react-use-measure
```

---

# Scatter Chart

> A composable time-series scatter chart with offset rings, hover dimming, and animated enter

Source: https://ui.cortexcn.dev/docs/components/scatter-chart

## Installation

```bash
npx shadcn@latest add @cortexcn/scatter-chart
```

## Usage

Build scatter charts by composing `ScatterChart` with one or more `Scatter` series, plus shared cartesian pieces (`Grid` or [`Background`](https://ui.cortexcn.dev/docs/utility/background), `XAxis`, `ChartTooltip`).

### Basic Example

```tsx
import {
  ScatterChart,
  Scatter,
  Grid,
  XAxis,
  ChartTooltip,
} from "@/components/charts";

const data = [
  { date: new Date("2025-01-01"), users: 1200 },
  { date: new Date("2025-02-01"), users: 1350 },
  { date: new Date("2025-03-01"), users: 1100 },
];

export default function SimpleScatter() {
  return (
    <ScatterChart data={data}>
      <Grid horizontal />
      <Scatter dataKey="users" />
      <XAxis />
      <ChartTooltip />
    </ScatterChart>
  );
}
```

### Multiple Series

Series colors default to the chart palette (`--chart-1` … `--chart-5`) in child order:

```tsx
<ScatterChart data={data}>
  <Grid horizontal />
  <Scatter dataKey="sessions" />
  <Scatter dataKey="conversions" />
  <XAxis />
  <ChartTooltip />
</ScatterChart>
```

### Offset Ring

Each dot is an inner fill plus an outer ring separated by a gap (`ringGap`):

```tsx
<Scatter dataKey="users" radius={6} strokeWidth={2} ringGap={2} />
```

### Hover Interaction

Non-active points can fade and blur while the crosshair is active:

```tsx
<Scatter
  dataKey="users"
  fadeOnHover
  inactiveOpacity={0.5}
  inactiveBlur={2}
  showActiveHighlight
/>
```

### Y Gradient

Color dots by vertical position with a chart-space gradient — lower values toward red, higher toward green. Set `strokeWidth={0}` for solid fills without rings:

```tsx
<Scatter dataKey="users" strokeWidth={0} yGradient />

// Custom stops
<Scatter
  dataKey="users"
  strokeWidth={0}
  yGradient={{ from: "var(--color-red-500)", to: "var(--color-emerald-500)" }}
/>
```

## Props

### ScatterChart

| Prop                | Type                        | Default            | Description                                                |
| ------------------- | --------------------------- | ------------------ | ---------------------------------------------------------- |
| `data`              | `Record<string, unknown>[]` | required           | Rows with a date (or `xDataKey`) and numeric series fields |
| `xDataKey`          | `string`                    | `"date"`           | Field used for the time x-axis                             |
| `margin`            | `Partial<Margin>`           | `40` all sides     | Chart margins                                              |
| `animationDuration` | `number`                    | `1100`             | Enter animation duration (ms)                              |
| `enterTransition`   | `Transition`                | line-chart default | Motion tween for enter                                     |
| `aspectRatio`       | `string`                    | `"2 / 1"`          | Container aspect ratio                                     |

### Scatter

| Prop                  | Type                                        | Default        | Description                                          |
| --------------------- | ------------------------------------------- | -------------- | ---------------------------------------------------- |
| `dataKey`             | `string`                                    | required       | Y value field                                        |
| `yAxisId`             | `string \| number`                          | `"left"`       | Y-scale group for biaxial charts (pair with `YAxis`) |
| `fill`                | `string`                                    | series palette | Inner dot fill                                       |
| `stroke`              | `string`                                    | same as `fill` | Outer ring color                                     |
| `strokeWidth`         | `number`                                    | `2`            | Outer ring width (0 disables)                        |
| `ringGap`             | `number`                                    | `2`            | Gap between fill and ring (px)                       |
| `radius`              | `number`                                    | `5`            | Inner dot radius (px)                                |
| `fadeOnHover`         | `boolean`                                   | `true`         | Dim/blur non-active points on hover                  |
| `inactiveOpacity`     | `number`                                    | `0.5`          | Opacity for dimmed points                            |
| `inactiveBlur`        | `number`                                    | `2`            | Blur (px) for dimmed points                          |
| `showActiveHighlight` | `boolean`                                   | `true`         | Scale up the active point                            |
| `yGradient`           | `boolean \| { from?: string; to?: string }` | —              | Color dots by y-position (default red → green)       |

## Shared Components

Use the same cartesian building blocks as `LineChart`:

- `Grid` — horizontal/vertical grid lines
- [`Background`](https://ui.cortexcn.dev/docs/utility/background) — pattern fill when grid lines are hidden (see [gallery](https://ui.cortexcn.dev/charts/scatter-chart))
- `YAxis` — value labels (single shared scale; see [Y Axis](https://ui.cortexcn.dev/docs/utility/axis/y-axis))
- `XAxis` — date labels with crosshair fade
- `ChartTooltip` — crosshair, date pill, and series rows

---

# Scroll Area

> Augments native scroll functionality for custom, cross-browser styling.

Source: https://ui.cortexcn.dev/docs/components/scroll-area

## Installation

```bash
npx shadcn@latest add @cortexcn/scroll-area
```

## Usage

```tsx
import { ScrollArea, ScrollBar } from "@/components/scroll-area";
```

## Examples

### Vertical

### Horizontal

---

# Select

> Displays a list of options for the user to pick from, triggered by a button.

Source: https://ui.cortexcn.dev/docs/components/select

## Installation

```bash
npx shadcn@latest add @cortexcn/select
```

## Usage

```tsx
import { Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectScrollDownButton, SelectScrollUpButton, SelectSeparator, SelectTrigger, SelectValue } from "@/components/select";
```

## Examples

### Basic

### With icons

### With groups and labels

### Large list

### Sizes

### Subscription plan

### With button

### Popper

### With field

### Invalid

### Inline with input and NativeSelect

### Disabled

### In dialog

---

# Separator

> Visually or semantically separates content.

Source: https://ui.cortexcn.dev/docs/components/separator

## Installation

```bash
npx shadcn@latest add @cortexcn/separator
```

## Usage

```tsx
import { Separator } from "@/components/separator";
```

## Examples

### Horizontal

### Vertical

### Vertical menu

### In list

---

# Sheet

> Extends the dialog to show content that complements the main content of the screen.

Source: https://ui.cortexcn.dev/docs/components/sheet

## Installation

```bash
npx shadcn@latest add @cortexcn/sheet
```

## Usage

```tsx
import { Sheet, SheetTrigger, SheetClose, SheetContent, SheetHeader, SheetFooter, SheetTitle, SheetDescription } from "@/components/sheet";
```

## Examples

### With form

### No close button

### Sides

---

# Sidebar

> A composable, themeable, and customizable sidebar.

Source: https://ui.cortexcn.dev/docs/components/sidebar

## Installation

```bash
npx shadcn@latest add @cortexcn/sidebar
```

The sidebar reads its colors from the `--sidebar` tokens that `shadcn init` adds to your theme.

## Usage

```tsx
import { Sidebar, SidebarContent, SidebarFooter, SidebarGroup, SidebarGroupAction, SidebarGroupContent, SidebarGroupLabel, SidebarHeader, SidebarInput, SidebarInset, SidebarMenu, SidebarMenuAction, SidebarMenuBadge, SidebarMenuButton, SidebarMenuItem, SidebarMenuSkeleton, SidebarMenuSub, SidebarMenuSubButton, SidebarMenuSubItem, SidebarProvider, SidebarRail, SidebarSeparator, SidebarTrigger, useSidebar } from "@/components/sidebar";
```

Wrap your layout in `SidebarProvider`, put a `Sidebar` next to a `SidebarInset`, and add a `SidebarTrigger` to toggle it. Press Ctrl+B (Cmd+B on a Mac) to toggle it from the keyboard.

## Examples

### Default

### Floating

### Collapsible to icons

### Inset

---

# Skeleton

> Shows a placeholder while content is loading.

Source: https://ui.cortexcn.dev/docs/components/skeleton

## Installation

```bash
npx shadcn@latest add @cortexcn/skeleton
```

## Usage

```tsx
import { Skeleton } from "@/components/skeleton";
```

## Examples

### Avatar

### Card

### Text

### Form

### Table

---

# Slider

> An input where the user selects a value from within a given range.

Source: https://ui.cortexcn.dev/docs/components/slider

## Installation

```bash
npx shadcn@latest add @cortexcn/slider
```

## Usage

```tsx
import { Slider } from "@/components/slider";
```

## Examples

### Basic

### Range

### Multiple thumbs

### Vertical

### Controlled

### Disabled

---

# Sonner

> An opinionated toast component for React.

Source: https://ui.cortexcn.dev/docs/components/sonner

## Installation

```bash
npx shadcn@latest add @cortexcn/sonner
```

## Usage

```tsx
import { Toaster } from "@/components/sonner";
```

## Examples

### Basic

### With description

---

# Sphere Menu

> A sphere of image tiles you can spin in any direction. When it slows down, the nearest tile turns to face you and its link appears.

Source: https://ui.cortexcn.dev/docs/components/sphere-menu

## Installation

```bash
npx shadcn@latest add @cortexcn/sphere-menu
```

## Usage

```tsx
import { SphereMenu } from "@/components/sphere-menu";
```

```tsx
<SphereMenu
  items={[
    {
      image: "/work/one.jpg",
      title: "Project one",
      description: "A short line about it.",
      href: "/work/one",
    },
    {
      image: "/work/two.jpg",
      title: "Project two",
      href: "/work/two",
    },
  ]}
/>
```

Use it for a portfolio, a gallery, or a playful way into the sections of a site. The items repeat around the sphere, so a few are enough.

## Examples

### More tiles

`tiles` sets how many tiles cover the sphere, and `scale` how large the sphere is in its box.

## Behavior

- Tiles are spread evenly over a sphere, and the sphere is drawn with CSS 3D transforms, not WebGL, so there is nothing to load and the tiles are real images.
- Drag in any direction to turn it. Let go and it keeps spinning, slows down, and turns the nearest tile to face you, standing it upright. The sphere draws back a little while you drag.
- When it comes to rest, the front tile's title, description, and link fade in. They fade out as soon as it moves again.
- With the keyboard, focus the sphere and use the arrow keys to turn it to the next tile. Every item is also listed as a plain link for screen readers.
- Tiles fade out as they turn toward the edge, and the far side is hidden.
- The animation only runs while the sphere moves. With reduced motion enabled, it stops where you let go and turns to the nearest tile without easing.
- No 3D or math library is used, so it adds no dependencies.

## Props

### SphereMenu

| Prop          | Type               | Default  | Description                                       |
| ------------- | ------------------ | -------- | ------------------------------------------------- |
| `items`       | `SphereMenuItem[]` | -        | The items. They repeat to fill the tiles          |
| `tiles`       | `number`           | `36`     | Tiles on the sphere                               |
| `scale`       | `number`           | `1`      | Sphere size, as a share of the box                |
| `actionLabel` | `string`           | `"Open"` | Text before the title on the link                 |
| `className`   | `string`           | -        | Extra classes for the box. It is 560px tall by default |

### SphereMenuItem

| Prop          | Type     | Default | Description                    |
| ------------- | -------- | ------- | ------------------------------ |
| `image`       | `string` | -       | Image for the tile             |
| `title`       | `string` | -       | Shown when the tile is in front |
| `description` | `string` | -       | A line under the title         |
| `href`        | `string` | -       | Where the link goes            |

---

# Spinner

> An indicator that shows a loading state.

Source: https://ui.cortexcn.dev/docs/components/spinner

## Installation

```bash
npx shadcn@latest add @cortexcn/spinner
```

## Usage

```tsx
import { Spinner } from "@/components/spinner";
```

## Examples

### Basic

### In buttons

### In badges

### In input group

### In empty state

---

# Sunburst Chart

> A composable hierarchical sunburst chart with drill-down zoom, animated segments, breadcrumb navigation, and legend sync

Source: https://ui.cortexcn.dev/docs/components/sunburst-chart

## Installation

```bash
npx shadcn@latest add @cortexcn/sunburst-chart
```

## Usage

The Sunburst Chart uses a composable API. Map one `SunburstSegment` per arc in the layout, then add optional chrome for navigation and labels:

```tsx
import {
  buildArcs,
  SunburstBreadcrumb,
  SunburstCenter,
  SunburstChart,
  SunburstHint,
  SunburstLabels,
  SunburstSegment,
} from "@/components/charts";

const data = {
  name: "Revenue",
  children: [
    {
      name: "Product",
      children: [
        { name: "Enterprise", value: 198 },
        { name: "Pro", value: 145 },
      ],
    },
    {
      name: "Services",
      children: [
        { name: "Consulting", value: 160 },
        { name: "Support", value: 90 },
      ],
    },
  ],
};

export default function RevenueSunburst() {
  const { arcs } = buildArcs(data);

  return (
    <SunburstChart data={data} size={440}>
      <SunburstBreadcrumb>
        <DrillBreadcrumb />
      </SunburstBreadcrumb>
      {arcs.map((arc) => (
        <SunburstSegment index={arc.arcIndex} key={arc.id} />
      ))}
      <SunburstCenter />
      <SunburstLabels />
      <SunburstHint />
    </SunburstChart>
  );
}
```

Click a segment with children to zoom in. Click the center hub or a breadcrumb crumb to zoom back out.

## Breadcrumb composition

`SunburstBreadcrumb` is a chrome slot rendered above the SVG. Compose your own trail UI with `useSunburstBreadcrumbItems()`:

```tsx
import {
  SunburstBreadcrumb,
  useSunburstBreadcrumbItems,
} from "@/components/charts";
import {
  BreadcrumbItem,
  BreadcrumbLink,
  BreadcrumbList,
  BreadcrumbPage,
  BreadcrumbSeparator,
} from "@/components/ui/breadcrumb";

function DrillBreadcrumb() {
  const { items, zoomTo } = useSunburstBreadcrumbItems();

  return (
    <BreadcrumbList>
      {items.map((item, index) => (
        <span className="contents" key={item.id}>
          {index > 0 ? <BreadcrumbSeparator /> : null}
          <BreadcrumbItem>
            {item.isCurrent ? (
              <BreadcrumbPage>{item.label}</BreadcrumbPage>
            ) : (
              <BreadcrumbLink
                render={
                  <button onClick={() => zoomTo(item.id)} type="button" />
                }
              >
                {item.label}
              </BreadcrumbLink>
            )}
          </BreadcrumbItem>
        </span>
      ))}
    </BreadcrumbList>
  );
}
```

## Components

### SunburstChart

The root component that computes the layout and provides context to children.

| Prop                | Type                              | Default  | Description                                                                              |
| ------------------- | --------------------------------- | -------- | ---------------------------------------------------------------------------------------- |
| `data`              | `SunburstNode`                    | required | Hierarchical data tree                                                                   |
| `size`              | `number`                          | `520`    | Chart diameter in pixels                                                                 |
| `playKey`           | `number`                          | `0`      | Bump to replay the enter animation                                                       |
| `focusId`           | `string`                          | -        | Controlled drill-down focus node id                                                      |
| `onFocusChange`     | `(focusId: string) => void`       | -        | Called when focus changes via click or breadcrumb                                        |
| `hoveredIndex`      | `number \| null`                  | -        | Controlled hover — arc index in the `arcs` array                                         |
| `onHoverChange`     | `(index: number \| null) => void` | -        | Hover state callback                                                                     |
| `hoverPop`          | `number`                          | `8`      | Segment grow distance on hover (px), cumulative along the path from root to hovered node |
| `padding`           | `number`                          | auto     | Inset reserved inside the view box for hover growth (derived from depth and `hoverPop`)  |
| `enterTransition`   | `Transition`                      | -        | Override enter animation transition                                                      |
| `enterStaggerScale` | `number`                          | `1`      | Scale ring-by-ring stagger timing                                                        |
| `className`         | `string`                          | `""`     | Wrapper class                                                                            |

### SunburstSegment

Renders one arc with enter animation, drill-down click handling, and hover grow along the ancestor path.

| Prop          | Type     | Default           | Description                                                   |
| ------------- | -------- | ----------------- | ------------------------------------------------------------- |
| `index`       | `number` | required          | Arc index from `buildArcs(data).arcs`                         |
| `color`       | `string` | from data/palette | Optional color override                                       |
| `fill`        | `string` | -                 | Optional fill for patterns/gradients (e.g. `url(#patternId)`) |
| `fillOpacity` | `number` | depth-based       | Optional fill opacity override                                |

### SunburstCenter

Navigation hub rendered after drill-down. Click to zoom out to the parent focus.

| Prop        | Type     | Default | Description          |
| ----------- | -------- | ------- | -------------------- |
| `className` | `string` | `""`    | Additional CSS class |

### SunburstBreadcrumb

Chrome slot above the chart for drill-down navigation. Pass your breadcrumb UI as `children`. Use `useSunburstBreadcrumbItems()` inside children to read the trail and `zoomTo`.

| Prop        | Type        | Default  | Description                               |
| ----------- | ----------- | -------- | ----------------------------------------- |
| `className` | `string`    | `"mb-4"` | Nav wrapper class                         |
| `children`  | `ReactNode` | required | Breadcrumb UI composed from chart context |

### useSunburstBreadcrumbItems

Hook for building breadcrumb UI inside `SunburstBreadcrumb`:

```ts
const { items, zoomTo } = useSunburstBreadcrumbItems();
// items: { id, label, isCurrent }[]
```

### SunburstLabels

Segment name labels positioned at arc centroids. Each label fades in after its segment finishes the enter animation.

| Prop          | Type     | Default                   | Description                  |
| ------------- | -------- | ------------------------- | ---------------------------- |
| `fontSize`    | `number` | `11`                      | Label font size              |
| `fill`        | `string` | `var(--chart-label)`      | Label fill color             |
| `stroke`      | `string` | `var(--chart-background)` | Outline stroke for contrast  |
| `strokeWidth` | `number` | `2.5`                     | Outline width (0 to disable) |
| `className`   | `string` | -                         | SVG group class              |

### SunburstHint

Contextual hint text below the chart (hover trail or zoom instructions). Rendered outside the SVG.

| Prop        | Type                              | Default                                                    | Description                                                     |
| ----------- | --------------------------------- | ---------------------------------------------------------- | --------------------------------------------------------------- |
| `className` | `string`                          | `"mt-3 min-h-5 text-center text-muted-foreground text-sm"` | Hint wrapper class                                              |
| `children`  | `ReactNode \| (ctx) => ReactNode` | -                                                          | Custom hint content; receives `{ hintText, hoveredArc, focus }` |

Custom hint example:

```tsx
<SunburstHint>
  {({ hintText, hoveredArc }) =>
    hoveredArc ? (
      <span className="font-medium">{hintText}</span>
    ) : (
      <span>Explore the breakdown</span>
    )
  }
</SunburstHint>
```

### Legend

A composable legend synced to the current focus level. See the full [Legend documentation](https://ui.cortexcn.dev/docs/utility/legend) for all components and options.

## Data Shape

```ts
interface SunburstNode {
  name: string;
  value?: number; // Leaf value (parent values are summed from children)
  color?: string; // Optional color override
  fill?: string; // Optional fill for patterns/gradients
  children?: SunburstNode[];
}
```

Use `buildArcs(data)` to get the flat `arcs` array, `maxDepth`, and `focusById` map for controlled drill-down and legend wiring.

See the [charts gallery](https://ui.cortexcn.dev/charts/sunburst-chart) for pattern fills, legend sync, and drill-down interaction.

## Theming

The Sunburst Chart uses CSS variables for theming. Category colors default to `--chart-1` through `--chart-5`. Inner rings use full opacity; outer rings step down in opacity for depth:

```css
:root {
  --chart-1: oklch(0.646 0.222 41.116);
  --chart-2: oklch(0.6 0.118 184.704);
  --chart-3: oklch(0.398 0.07 227.392);
  --chart-4: oklch(0.828 0.189 84.429);
  --chart-5: oklch(0.769 0.188 70.08);
}
```

## Animation

1. **Enter reveal** — Rings animate clockwise with staggered segment timing
2. **Label fade** — Labels fade in per segment after that segment's reveal completes
3. **Drill-down zoom** — Focus morphs matching arcs; others collapse to a point
4. **Hover grow** — Segments on the path from root to the hovered node extend outward, capped at the thickness of one expanded ring at the first drill level; descendants shift radially to accommodate parent growth. A padded inset inside the view box (auto from `hoverPop` and depth) prevents clipping.
5. **Fade** — Unrelated segments dim to 25% opacity when another branch is hovered (160ms ease-out)

All animations respect `prefers-reduced-motion`.

## Dependencies

```bash
pnpm add motion
```

Add `@visx/pattern` when using `PatternLines` or other pattern fills.

---

# Switch

> A control that allows the user to toggle between on and off.

Source: https://ui.cortexcn.dev/docs/components/switch

## Installation

```bash
npx shadcn@latest add @cortexcn/switch
```

## Usage

```tsx
import { Switch } from "@/components/switch";
```

## Examples

### Basic

### With description

### With label

### Disabled

### Sizes

---

# Table

> A responsive table component.

Source: https://ui.cortexcn.dev/docs/components/table

## Installation

```bash
npx shadcn@latest add @cortexcn/table
```

## Usage

```tsx
import { Table, TableHeader, TableBody, TableFooter, TableHead, TableRow, TableCell, TableCaption } from "@/components/table";
```

## Examples

### Basic

### With footer

### Simple

### With badges

### With actions

### With select

### With input

---

# Tabs

> A set of layered sections of content, shown one at a time.

Source: https://ui.cortexcn.dev/docs/components/tabs

## Installation

```bash
npx shadcn@latest add @cortexcn/tabs
```

## Usage

```tsx
import { Tabs, TabsList, TabsTrigger, TabsContent, tabsListVariants } from "@/components/tabs";
```

## Examples

### Basic

### Line

### Variants alignment

### Disabled

### With icons

### Icon only

### Multiple

### With content

### Line with content

### Line disabled

### With dropdown

### Vertical

### With input and button

---

# Textarea

> Displays a form textarea or a component that looks like a textarea.

Source: https://ui.cortexcn.dev/docs/components/textarea

## Installation

```bash
npx shadcn@latest add @cortexcn/textarea
```

## Usage

```tsx
import { Textarea } from "@/components/textarea";
```

## Examples

### Basic

### Invalid

### With label

### With description

### Disabled

---

# Theme Toggle Effect

> Animated transitions when switching between light and dark themes.

Source: https://ui.cortexcn.dev/docs/components/theme-toggle-effect

## Browser compatibility

This component uses the [View Transitions API](https://developer.mozilla.org/en-US/docs/Web/API/View_Transition_API). Check the latest [browser compatibility on MDN](https://developer.mozilla.org/en-US/docs/Web/API/Document/startViewTransition#browser_compatibility) before using it in production. Browsers without the API, and users who prefer reduced motion, switch themes instantly.

## Installation

## Usage

Wrap your theme setter with `startThemeTransition` and pass the effect you installed:

```tsx
"use client";

import { useTheme } from "next-themes";
import { startThemeTransition } from "@/components/theme-toggle-effect";

export function ThemeToggle() {
  const { resolvedTheme, setTheme } = useTheme();

  function toggleTheme() {
    const next = resolvedTheme === "dark" ? "light" : "dark";
    startThemeTransition(() => setTheme(next), "circle");
  }

  return <button onClick={toggleTheme}>Toggle theme</button>;
}
```

It works with any theme setter, not only `next-themes`:

```tsx
startThemeTransition(() => {
  document.documentElement.classList.toggle("dark");
}, "polygon");
```

The preview above has every effect installed so you can compare them. In your app, install the effect you use and pass the same name to `startThemeTransition`.

`startThemeTransition` sets `data-theme-toggle-effect` on `<html>` for the length of the switch, and every effect rule is scoped to that attribute. The effect CSS never runs for other view transitions, such as page navigations.

## API

```ts
function startThemeTransition(
  update: () => void,
  effect?: ThemeToggleEffect,
): void;
```

| Parameter | Type                | Default    | Description                               |
| --------- | ------------------- | ---------- | ----------------------------------------- |
| `update`  | `() => void`        | required   | Applies the new theme, usually `setTheme` |
| `effect`  | `ThemeToggleEffect` | `"circle"` | Which reveal effect to play               |

`THEME_TOGGLE_EFFECTS` is a readonly array of every effect name, and `ThemeToggleEffect` is the union of its values.

## References

- [View Transition API](https://developer.mozilla.org/en-US/docs/Web/API/View_Transition_API)
- [Document: startViewTransition()](https://developer.mozilla.org/en-US/docs/Web/API/Document/startViewTransition)

---

# Toggle

> A two-state button that can be either on or off.

Source: https://ui.cortexcn.dev/docs/components/toggle

## Installation

```bash
npx shadcn@latest add @cortexcn/toggle
```

## Usage

```tsx
import { Toggle, toggleVariants } from "@/components/toggle";
```

## Examples

### Basic

### Outline

### Sizes

### With button text

### With button icon

### With button icon and text

### Disabled

### With icon

---

# Toggle Group

> A set of two-state buttons that can be toggled on or off.

Source: https://ui.cortexcn.dev/docs/components/toggle-group

## Installation

```bash
npx shadcn@latest add @cortexcn/toggle-group
```

## Usage

```tsx
import { ToggleGroup, ToggleGroupItem } from "@/components/toggle-group";
```

## Examples

### Basic

### Outline

### Outline with icons

### Sizes

### With spacing

### With icons

### Filter

### Date range

### Sort

### With input and select

### Vertical

### Vertical outline

### Vertical outline with icons

### Vertical with spacing

### Font weight selector

---

# Tooltip

> A popup that shows information about an element on hover or keyboard focus.

Source: https://ui.cortexcn.dev/docs/components/tooltip

## Installation

```bash
npx shadcn@latest add @cortexcn/tooltip
```

## Usage

```tsx
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "@/components/tooltip";
```

## Examples

### Basic

### Sides

### With icon

### Long content

### Disabled

### With keyboard shortcut

### On link

### Formatted content

---

# Work Experience

> Display work experiences with role details, company logos, and durations.

Source: https://ui.cortexcn.dev/docs/components/work-experience

## Features

- Supports multiple positions per company.
- Markdown in position descriptions: paragraphs, lists, **bold**, `code`, and links.
- Company logos, employment type, period, and a calculated duration.
- Positions with a description expand and collapse; positions without one stay static.
- No markdown, date, or icon libraries required.

## Installation

```bash
npx shadcn@latest add @cortexcn/work-experience
```

The CLI also installs the shadcn/ui [Collapsible](https://ui.shadcn.com/docs/components/collapsible) and [Separator](https://ui.shadcn.com/docs/components/separator) components.

## Usage

```tsx
import { WorkExperience } from "@/components/work-experience";
import type { ExperienceItemType } from "@/components/work-experience";
```

```tsx
const experiences: ExperienceItemType[] = [
  {
    id: "acme",
    companyName: "Acme",
    companyWebsite: "https://acme.com",
    isCurrentEmployer: true,
    positions: [
      {
        id: "engineer",
        title: "Software Engineer",
        employmentPeriod: { start: "03.2024" },
        employmentType: "Full-time",
        description:
          "- Shipped the new billing flow.\n- Led the design system.",
        skills: ["React", "TypeScript"],
      },
    ],
  },
];

<WorkExperience experiences={experiences} />;
```

Dates use `MM.YYYY` or `YYYY`. Leave `end` out for a current role; the period then ends with an infinity sign and the duration counts up to today. `icon` accepts any element, so you can use whichever icon set your project already has.

## API reference

### WorkExperience

| Prop          | Type                                          | Default  | Description                    |
| ------------- | --------------------------------------------- | -------- | ------------------------------ |
| `experiences` | [`ExperienceItemType[]`](#experienceitemtype) | required | Companies to list, in order    |
| `className`   | `string`                                      | -        | Extra classes for the root div |

### ExperienceItemType

| Property            | Type                                                          | Description                                |
| ------------------- | ------------------------------------------------------------- | ------------------------------------------ |
| `id`                | `string`                                                      | Unique identifier for the experience item  |
| `companyName`       | `string`                                                      | Name of the company                        |
| `companyLogo`       | `string?`                                                     | URL or path to the company's logo image    |
| `companyWebsite`    | `string?`                                                     | URL to the company's website               |
| `positions`         | [`ExperiencePositionItemType[]`](#experiencepositionitemtype) | Positions held at the company              |
| `isCurrentEmployer` | `boolean?`                                                    | Shows a live indicator next to the company |

### ExperiencePositionItemType

| Property           | Type                              | Description                                                 |
| ------------------ | --------------------------------- | ----------------------------------------------------------- |
| `id`               | `string`                          | Unique identifier for the position                          |
| `title`            | `string`                          | The job title or position name                              |
| `employmentPeriod` | `{ start: string; end?: string }` | `MM.YYYY` or `YYYY`. Omit `end` for current roles           |
| `employmentType`   | `string?`                         | For example `"Full-time"`, `"Part-time"`, or `"Contract"`   |
| `description`      | `string?`                         | Markdown description; the position collapses when it is set |
| `icon`             | `ReactElement?`                   | Icon for the position. Defaults to a briefcase              |
| `skills`           | `string[]?`                       | Skills shown as tags under the position                     |
| `isExpanded`       | `boolean?`                        | Whether the description starts expanded                     |

---

# Installation

> How to install and configure Cortexcn in your project.

Source: https://ui.cortexcn.dev/docs/installation

Cortexcn components are distributed through a shadcn registry. You add them with the shadcn CLI, and the component source is copied into your project.

## Prerequisites

Before installing Cortexcn components, make sure you have shadcn/ui set up in your project. If you haven't already, run:

```bash
npx shadcn@latest init
```

## Add the registry

Add the `@cortexcn` namespace to the `registries` field in your `components.json`:

```json
{
  "registries": {
    "@cortexcn": "https://ui.cortexcn.dev/r/{name}.json"
  }
}
```

You only need to do this once per project.

## Install components

Install any Cortexcn component using the CLI:

```bash
npx shadcn@latest add @cortexcn/area-chart
```

This will:

- Download the component source code into your project
- Install any npm packages the component needs
- Install any other Cortexcn components it depends on

For example, `@cortexcn/line-chart`, `@cortexcn/area-chart`, and `@cortexcn/heatmap-chart` pull in `@cortexcn/shimmering-text` for their loading labels.

## Next Steps

You're all set. Browse the [Components](https://ui.cortexcn.dev/docs/components) section to start adding components to your project.

---

# DESIGN.md

> Cortexcn's design system as a DESIGN.md file your AI assistant can read and follow.

Source: https://ui.cortexcn.dev/docs/integration/design-md

Cortexcn publishes its design system as a `DESIGN.md` file, so an AI assistant building UI in your project uses the same colors, corners, type, and motion as the components.

## The format

DESIGN.md is an open format from Google Labs ([google-labs-code/design.md](https://github.com/google-labs-code/design.md), spec version alpha). A file has two parts:

- YAML front matter with the design tokens: `colors`, `typography`, `rounded`, `spacing`, and `components`.
- Markdown sections that explain how to use them: Overview, Colors, Typography, Layout, Elevation & Depth, Shapes, Components, and Do's and Don'ts.

Cortexcn's file is generated from its real theme tokens, so it matches the components you install.

## Install

Add it to your project root:

```bash
npx shadcn@latest add https://ui.cortexcn.dev/r/design-md.json
```

This writes `DESIGN.md`. To install it together with the [skills](https://ui.cortexcn.dev/docs/integration/skills), use `https://ui.cortexcn.dev/r/agent-kit.json` instead.

Agents connected to the [MCP server](https://ui.cortexcn.dev/docs/integration/mcp) can also read it with the `get_design_guide` tool, without installing anything.

The file is generated, so it is not reproduced on this page. To read the raw version, open [design-md.json](https://ui.cortexcn.dev/r/design-md.json).

## What it specifies

| Area           | Rule                                                                                                                     |
| -------------- | ------------------------------------------------------------------------------------------------------------------------ |
| Corners        | Square. `--radius` is `0`, and every `rounded-*` class resolves from it.                                                 |
| Color          | Theme tokens only: `background`, `foreground`, `card`, `muted`, `primary`, `border`, `ring`, and `chart-1` to `chart-5`. |
| Light and dark | Both modes come from the same tokens. Dark mode is the `.dark` class.                                                    |
| Focus          | Every interactive element shows `focus-visible:ring-3 focus-visible:ring-ring/50`.                                       |
| Control sizes  | `h-9` by default, `h-8` small, `h-10` large.                                                                             |
| Motion         | 100 to 300 ms, easing out. Reduced motion is respected.                                                                  |

## Make your assistant use it

No assistant is documented to load `DESIGN.md` on its own, so reference it from a file your assistant does read.

For Claude Code, add this line to `CLAUDE.md`:

```md title="CLAUDE.md"
@DESIGN.md
```

For Codex, Cursor, and GitHub Copilot, add a line like this to `AGENTS.md`:

```md title="AGENTS.md"
Follow DESIGN.md for all UI work.
```

Or install the `cortexcn-design` [skill](https://ui.cortexcn.dev/docs/integration/skills), which reads `DESIGN.md` before any UI work.

## Lint or export it

This step is optional. Google's DESIGN.md CLI can check the file against the spec:

```bash
npx @google/design.md lint DESIGN.md
```

It can also export the tokens to another format, such as `css-tailwind`:

```bash
npx @google/design.md export --format css-tailwind DESIGN.md
```

## Related

- [Skills](https://ui.cortexcn.dev/docs/integration/skills): the `cortexcn-design` skill applies this file
- [MCP Server](https://ui.cortexcn.dev/docs/integration/mcp): read the file with `get_design_guide`
- [Components](https://ui.cortexcn.dev/docs/components): the components the file describes

---

# MCP Server

> Connect your AI assistant to Cortexcn so it can search, read, and install components, blocks, and charts.

Source: https://ui.cortexcn.dev/docs/integration/mcp

The Cortexcn MCP server lets an AI assistant search the registry, read an item's docs and source, and get the exact command to install it into your project.

## Quick Start

1. Connect the server. In Claude Code, run:

   ```bash
   claude mcp add --transport http cortexcn https://ui.cortexcn.dev/mcp
   ```

   For other assistants, see [Connect your assistant](#connect-your-assistant).

2. Make sure your project has shadcn set up. If there is no `components.json` in the project root, run:

   ```bash
   npx shadcn@latest init
   ```

3. Ask your assistant for what you need, for example: "Add the Lanyard 3D component to the about page."

## About the server

| Setting           | Value                                          |
| ----------------- | ---------------------------------------------- |
| URL               | `https://ui.cortexcn.dev/mcp`                  |
| Server name       | `cortexcn`                                     |
| Transport         | Streamable HTTP                                |
| Protocol versions | The 2025 revisions and the 2026-07-28 revision |
| Sessions          | Stateless                                      |
| Sign-in           | None                                           |
| Access            | Read-only                                      |

The server is hosted, so most clients connect to the URL directly and there is nothing to install or run.

## How installs work

The server never runs commands on your machine. When you ask for an item, it returns the install command, and your assistant (Claude Code, Cursor, or another agent with terminal access) runs it in your project root:

```bash
npx shadcn@latest add https://ui.cortexcn.dev/r/lanyard-3d.json
```

The command uses the item's URL, so you do not need to add the `@cortexcn` registry to `components.json`. The project still needs shadcn initialized. The CLI installs the item's npm dependencies and any other registry items it needs.

Chat apps such as claude.ai and ChatGPT cannot reach your terminal, so there the assistant gives you the command to run yourself.

## Tools

| Tool                  | Arguments                            | What it returns                                                                                                                            |
| --------------------- | ------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------ |
| `search_items`        | `query`, optional `kind` and `limit` | Components, blocks, and charts that match a keyword or a need, ranked by relevance.                                                        |
| `list_items`          | optional `kind` and `category`       | Every item, filtered by kind or category if you pass them.                                                                                 |
| `list_categories`     | none                                 | The groups items are organized in, with a count for each.                                                                                  |
| `get_item`            | `name`, optional `include_docs`      | The install command, the files and dependencies it adds, links to its page and live preview, and its docs with usage, examples, and props. |
| `get_item_source`     | `name`                               | The source of the item's files.                                                                                                            |
| `get_install_command` | `names`, optional `package_manager`  | One shadcn CLI command that installs several items at once.                                                                                |
| `get_setup_guide`     | none                                 | How to prepare a project: `shadcn init` and the `@cortexcn` registry in `components.json`.                                                 |
| `get_design_guide`    | none                                 | Cortexcn's [DESIGN.md](https://ui.cortexcn.dev/docs/integration/design-md).                                                                                       |

Argument values:

- `kind` is one of `component`, `block`, `chart`, `hook`, or `lib`.
- `limit` defaults to 8 results, up to 25.
- `include_docs` defaults to `true`.
- `package_manager` is one of `pnpm`, `npm`, `yarn`, or `bun`, and defaults to `pnpm`.

## Connect your assistant

Each client below uses the same URL. If a config file already lists other servers, add the `cortexcn` entry next to them.

### Claude Code

```bash
claude mcp add --transport http cortexcn https://ui.cortexcn.dev/mcp
```

Add `--scope user` to use it in every project:

```bash
claude mcp add --transport http --scope user cortexcn https://ui.cortexcn.dev/mcp
```

Or add `--scope project` to write it to `.mcp.json` in the project root, so everyone on your team gets it. You can also write that file by hand:

```json title=".mcp.json"
{
  "mcpServers": {
    "cortexcn": {
      "type": "http",
      "url": "https://ui.cortexcn.dev/mcp"
    }
  }
}
```

Run `/mcp` inside Claude Code to check that the server is connected.

### Claude Desktop and claude.ai

1. Open [Customize > Connectors](https://claude.ai/customize/connectors).
2. Choose **Add custom connector**.
3. Paste `https://ui.cortexcn.dev/mcp` as the URL and choose **No sign-in**.

In Claude Desktop you can use the config file instead. This runs [mcp-remote](https://www.npmjs.com/package/mcp-remote) through `npx` as a local bridge to the server, so it needs Node.js:

```json title="claude_desktop_config.json"
{
  "mcpServers": {
    "cortexcn": {
      "command": "npx",
      "args": ["-y", "mcp-remote", "https://ui.cortexcn.dev/mcp"]
    }
  }
}
```

The file is at:

- macOS: `~/Library/Application Support/Claude/claude_desktop_config.json`
- Windows: `%APPDATA%\Claude\claude_desktop_config.json`

Restart Claude Desktop after you save it.

### Cursor

[Add to Cursor](cursor://anysphere.cursor-deeplink/mcp/install?name=cortexcn&config=eyJ1cmwiOiJodHRwczovL3VpLmNvcnRleGNuLmRldi9tY3AifQ==)

Or add it to `.cursor/mcp.json` in your project, or to `~/.cursor/mcp.json` to use it in every project:

```json title=".cursor/mcp.json"
{
  "mcpServers": {
    "cortexcn": {
      "url": "https://ui.cortexcn.dev/mcp"
    }
  }
}
```

### VS Code

The server works with GitHub Copilot in agent mode. Add it to `.vscode/mcp.json` in your project:

```json title=".vscode/mcp.json"
{
  "servers": {
    "cortexcn": {
      "type": "http",
      "url": "https://ui.cortexcn.dev/mcp"
    }
  }
}
```

Or add it from a terminal:

```bash
code --add-mcp "{\"name\":\"cortexcn\",\"type\":\"http\",\"url\":\"https://ui.cortexcn.dev/mcp\"}"
```

### Windsurf and Devin Desktop

Add it to `mcp_config.json`:

```json title="mcp_config.json"
{
  "mcpServers": {
    "cortexcn": {
      "serverUrl": "https://ui.cortexcn.dev/mcp"
    }
  }
}
```

### OpenAI Codex CLI

```bash
codex mcp add cortexcn --url https://ui.cortexcn.dev/mcp
```

Or add it to `~/.codex/config.toml`:

```toml title="~/.codex/config.toml"
[mcp_servers.cortexcn]
url = "https://ui.cortexcn.dev/mcp"
```

### Zed

Add it to your Zed `settings.json`:

```json title="settings.json"
{
  "context_servers": {
    "cortexcn": {
      "url": "https://ui.cortexcn.dev/mcp"
    }
  }
}
```

### ChatGPT

Custom connectors need developer mode, which is available on the web for Plus, Pro, Business, Enterprise, and Edu plans.

1. Go to **Settings > Security and login** and turn on **Developer mode**.
2. Add a connector, paste `https://ui.cortexcn.dev/mcp` as the URL, and choose **No authentication**.

## Example prompts

Once the server is connected, ask in plain words:

- "Find a hero block with a product screenshot and add it to the landing page."
- "Add the Lanyard 3D component and use our team's names."
- "Build a dashboard page with an area chart and three stat cards from Cortexcn."
- "What props does the Gooey Nav take?"
- "Show me the source of the Sphere Menu before we install it."
- "Which Cortexcn chart fits a sales funnel? Add it to the reports page."

## Install from a component page

Every component page has an install box with an **MCP** tab. It shows the command that connects the server in Claude Code and a prompt to paste into your assistant, such as:

```text
Add the Cortexcn lanyard-3d item to this project.
```

## Assistants without MCP

If your assistant cannot use MCP, give it the docs as markdown instead:

- Add `.md` to any docs page URL, for example [https://ui.cortexcn.dev/docs/components/lanyard-3d.md](https://ui.cortexcn.dev/docs/components/lanyard-3d.md).
- Every docs page in one file: [https://ui.cortexcn.dev/llms-full.txt](https://ui.cortexcn.dev/llms-full.txt).

## Requirements

- An AI assistant that supports MCP.
- To install items: a React and Tailwind CSS project with shadcn initialized (`npx shadcn@latest init`).
- Node.js 18 or later for the shadcn CLI.

## Related

- [Skills](https://ui.cortexcn.dev/docs/integration/skills): teach your assistant how to work with Cortexcn
- [DESIGN.md](https://ui.cortexcn.dev/docs/integration/design-md): the design system your assistant should follow
- [Installation](https://ui.cortexcn.dev/docs/installation): set up the `@cortexcn` registry by hand

---

# Skills

> Agent skills that teach your AI assistant how to find, install, and style Cortexcn components, blocks, and charts.

Source: https://ui.cortexcn.dev/docs/integration/skills

Cortexcn publishes two agent skills that tell your AI assistant how to work with Cortexcn: one for finding and installing items, and one for following the Cortexcn design system.

## The skills

| Skill             | What it covers                                                                                                                                                                   |
| ----------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `cortexcn`        | How to find, install, compose, and theme Cortexcn items. It uses the [MCP server](https://ui.cortexcn.dev/docs/integration/mcp) when it is connected, and otherwise the registry and the markdown docs. |
| `cortexcn-design` | How to apply the Cortexcn design system from [DESIGN.md](https://ui.cortexcn.dev/docs/integration/design-md) before building or restyling UI, with a checklist to run before finishing.                 |

Both use the open Agent Skills format: each skill is a folder with a `SKILL.md` file of instructions in markdown. Your assistant reads the short description of every installed skill and loads the full file when a task matches, so you do not have to name the skill in your request.

Skills are plain markdown. Your team can read them, edit them to fit the project, and commit them like any other file.

## Install

### With the shadcn CLI

```bash
npx shadcn@latest add https://ui.cortexcn.dev/r/agent-skills.json
```

You do not need a `components.json` for these files. The command writes both skills twice, once for Claude Code and once for Codex, Cursor, and GitHub Copilot:

```text
.claude/skills/cortexcn/SKILL.md
.claude/skills/cortexcn-design/SKILL.md
.agents/skills/cortexcn/SKILL.md
.agents/skills/cortexcn-design/SKILL.md
```

### With the skills CLI

```bash
npx skills add https://ui.cortexcn.dev
```

The skills CLI reads the skill index that Cortexcn publishes at [https://ui.cortexcn.dev/.well-known/agent-skills/index.json](https://ui.cortexcn.dev/.well-known/agent-skills/index.json).

### Everything at once

To install both skills and the `DESIGN.md` file in one step:

```bash
npx shadcn@latest add https://ui.cortexcn.dev/r/agent-kit.json
```

## Where each assistant reads skills

| Assistant                 | Folder                                                     |
| ------------------------- | ---------------------------------------------------------- |
| Claude Code               | `.claude/skills/`                                          |
| OpenAI Codex              | `.agents/skills/`                                          |
| Cursor                    | `.agents/skills/` (it also reads `.claude/skills/`)        |
| GitHub Copilot in VS Code | `.github/skills/`, `.claude/skills/`, or `.agents/skills/` |

The shadcn CLI install covers all four, because it writes to both `.claude/skills/` and `.agents/skills/`.

## Example requests

With the skills installed, ask as you normally would:

- "Add a feature grid from Cortexcn below the hero."
- "Install the area chart and plot weekly signups with a tooltip."
- "Build a stats page with bar and line charts from the @cortexcn registry."
- "Add a stat card with a line chart to the dashboard."
- "Restyle this settings form to follow DESIGN.md."
- "Check this page against the Cortexcn design checklist."

## Use with the MCP server

The skills work on their own, using the registry and the markdown docs. Pair them with the [MCP server](https://ui.cortexcn.dev/docs/integration/mcp) for the best results: the `cortexcn` skill tells the assistant to search with `search_items` and read `get_item` before it installs anything, so it works from the current catalog and the real props.

## Related

- [MCP Server](https://ui.cortexcn.dev/docs/integration/mcp): connect your assistant to the Cortexcn registry
- [DESIGN.md](https://ui.cortexcn.dev/docs/integration/design-md): the design system the `cortexcn-design` skill follows
- [Installation](https://ui.cortexcn.dev/docs/installation): set up the `@cortexcn` registry by hand

---

# Theming

> Theme your charts using CSS custom properties for consistent, customizable styling.

Source: https://ui.cortexcn.dev/docs/theming

Charts use CSS custom properties (variables) for theming, allowing you to customize colors across light and dark modes without modifying component code.

## Using chartCssVars

The `chartCssVars` object provides type-safe access to chart CSS variables:

```tsx
import { chartCssVars } from "@/components/charts";

// In your component
<rect fill={chartCssVars.indicatorColor} />
<line stroke={chartCssVars.crosshair} />
```

This is preferred over hardcoding CSS variable strings, as it provides autocomplete and prevents typos.

## Available Variables

### Core Colors

| Variable          | CSS Property               | Description                |
| ----------------- | -------------------------- | -------------------------- |
| `background`      | `--chart-background`       | Chart container background |
| `foreground`      | `--chart-foreground`       | Primary text/element color |
| `foregroundMuted` | `--chart-foreground-muted` | Secondary/muted text color |
| `label`           | `--chart-label`            | Axis label text color      |

### Line & Grid

| Variable        | CSS Property             | Description                  |
| --------------- | ------------------------ | ---------------------------- |
| `linePrimary`   | `--chart-line-primary`   | Primary line stroke color    |
| `lineSecondary` | `--chart-line-secondary` | Secondary line stroke color  |
| `crosshair`     | `--chart-crosshair`      | Tooltip crosshair line color |
| `grid`          | `--chart-grid`           | Grid line color              |

### Indicators

| Variable                  | CSS Property                        | Description                                 |
| ------------------------- | ----------------------------------- | ------------------------------------------- |
| `indicatorColor`          | `--chart-indicator-color`           | Primary indicator color (e.g., hover lines) |
| `indicatorSecondaryColor` | `--chart-indicator-secondary-color` | Secondary indicator color                   |

### Markers

| Variable           | CSS Property                      | Description                   |
| ------------------ | --------------------------------- | ----------------------------- |
| `markerBackground` | `--chart-marker-background`       | Marker circle background      |
| `markerBorder`     | `--chart-marker-border`           | Marker circle border          |
| `markerForeground` | `--chart-marker-foreground`       | Marker icon color             |
| `badgeBackground`  | `--chart-marker-badge-background` | Marker count badge background |
| `badgeForeground`  | `--chart-marker-badge-foreground` | Marker count badge text       |

### Data Series Colors

These are used for coloring different data series in multi-line charts:

| CSS Property | Description         |
| ------------ | ------------------- |
| `--chart-1`  | First series color  |
| `--chart-2`  | Second series color |
| `--chart-3`  | Third series color  |
| `--chart-4`  | Fourth series color |
| `--chart-5`  | Fifth series color  |

### Sequential Scale

For heatmaps, choropleths, and other binned or intensity-based charts, use the sequential scale tokens (`01` = lowest, `05` = highest):

| CSS Property                  | Description                           |
| ----------------------------- | ------------------------------------- |
| `--chart-scale-01`            | Empty / lowest intensity              |
| `--chart-scale-02`            | Level 1                               |
| `--chart-scale-03`            | Level 2                               |
| `--chart-scale-04`            | Level 3                               |
| `--chart-scale-05`            | Highest intensity                     |
| `--chart-scale-pattern-color` | Pattern stroke for zero / empty cells |

Import typed references from `@cortexcn/ui/charts`:

```tsx
import { chartScaleCssVars, CHART_SCALE_VARS } from "@/components/charts";

<ChoroplethFeatureComponent fill={chartScaleCssVars.scale03} />;
```

### Track & radial charts

Ring tracks, gauge inactive notches, and radar grid lines share the shadcn **`--border`** token:

| CSS Property | Used by                                                                       |
| ------------ | ----------------------------------------------------------------------------- |
| `--border`   | Ring track background, gauge track notches, `RadarGrid` / `RadarAxis` strokes |

```tsx
import { ringCssVars, radarCssVars } from "@/components/charts";

// ringCssVars.ringBackground → var(--border)
// radarCssVars.border → var(--border)
```

## Customizing Variables

Override CSS variables in your stylesheet to customize chart appearance:

```css
:root {
  /* Light mode */
  --chart-background: oklch(1 0 0);
  --chart-foreground: oklch(0.145 0.004 285);
  --chart-grid: oklch(0.9 0 0);
  --chart-crosshair: oklch(0.4 0.18 274);
  --chart-indicator-color: oklch(0.21 0.006 285);

  /* Series colors */
  --chart-1: oklch(0.32 0 none);
  --chart-2: oklch(0.41 0 none);
  --chart-3: oklch(0.54 0 none);

  /* Sequential scale (heatmap / choropleth) */
  --chart-scale-01: oklch(0.98 0.003 106);
  --chart-scale-02: oklch(0.92 0.008 106);
  --chart-scale-03: oklch(0.82 0.015 106);
  --chart-scale-04: oklch(0.68 0.02 106);
  --chart-scale-05: oklch(0.55 0.025 106);
  --chart-scale-pattern-color: oklch(0.96 0.005 106);

  /* Ring / gauge / radar tracks */
  --border: oklch(0.92 0.004 286.32);
}

.dark {
  /* Dark mode overrides */
  --chart-background: oklch(0.145 0 0);
  --chart-foreground: oklch(0.45 0 0);
  --chart-grid: oklch(0.25 0 0);
  --chart-indicator-color: oklch(1 0 0);
}
```

## Example: Custom Indicator Theming

The [Custom Indicator](https://ui.cortexcn.dev/docs/utility/custom-indicator) pattern uses `--chart-indicator-color`:

```tsx
<motion.rect
  fill="var(--chart-indicator-color)"
  height={2}
  width={barWidth}
  x={barX}
/>
```

Or using the typed object:

```tsx
import { chartCssVars } from "@/components/charts";

<motion.rect
  fill={chartCssVars.indicatorColor}
  height={2}
  width={barWidth}
  x={barX}
/>;
```

## Related

- [Custom Indicator](https://ui.cortexcn.dev/docs/utility/custom-indicator) - Building animated indicators
- [useChart](https://ui.cortexcn.dev/docs/utility/use-chart) - Accessing chart context

---

# Axis

> X and Y axis components for line and area charts

Source: https://ui.cortexcn.dev/docs/utility/axis

Axis components add value and date labels to line and area charts.

## Components

- **[X Axis](https://ui.cortexcn.dev/docs/utility/axis/x-axis)** — Date labels along the bottom (horizontal axis)
- **[Y Axis](https://ui.cortexcn.dev/docs/utility/axis/y-axis)** — Value labels along the left (vertical axis)

Both components must be used inside a chart (`LineChart` or `AreaChart`) and render via portal into the chart container.

---

# X Axis

> Date labels for the horizontal axis in line and area charts

Source: https://ui.cortexcn.dev/docs/utility/axis/x-axis

## Installation

```bash
npx shadcn@latest add @cortexcn/x-axis
```

## Usage

The XAxis component displays date labels along the bottom of line and area charts. It must be used inside a chart component (`LineChart` or `AreaChart`).

```tsx
import { LineChart, Line, XAxis, ChartTooltip } from "@/components/charts";

<LineChart data={data}>
  <Line dataKey="value" />
  <XAxis />
  <ChartTooltip />
</LineChart>;
```

## Props

| Prop              | Type                 | Default  | Description                                                                                        |
| ----------------- | -------------------- | -------- | -------------------------------------------------------------------------------------------------- |
| `numTicks`        | `number`             | `5`      | Number of ticks to show (including first and last)                                                 |
| `tickerHalfWidth` | `number`             | `50`     | Width of the date ticker box for fade calculation when tooltip is visible                          |
| `tickMode`        | `"data" \| "domain"` | `"data"` | `"data"` snaps labels to data rows (aligned with crosshair); `"domain"` uses even calendar spacing |

## Behavior

- **Data-aligned labels**: By default, XAxis picks evenly spaced data rows for tick labels so crosshair and tooltip line up with the axis. Use `tickMode="domain"` for calendar-even spacing when alignment is not needed.
- **Crosshair fade**: When the tooltip is visible, labels near the crosshair fade to reduce visual clutter and improve readability.
- **Client-side only**: Renders via portal after mount to avoid SSR issues.

## Theming

Labels use the `text-chart-label` class, which inherits from your theme's muted foreground color.

---

# Y Axis

> Value labels for the vertical axis in line and area charts

Source: https://ui.cortexcn.dev/docs/utility/axis/y-axis

## Installation

```bash
npx shadcn@latest add @cortexcn/y-axis
```

## Usage

The YAxis component displays value labels along the left or right side of time-series charts (`LineChart`, `AreaChart`, `ComposedChart`, `ScatterChart`, and vertical `BarChart`). It must be used inside the chart shell. Ensure your chart has sufficient margin for the labels.

```tsx
import {
  LineChart,
  Line,
  XAxis,
  YAxis,
  ChartTooltip,
} from "@/components/charts";

<LineChart data={data} margin={{ left: 50 }}>
  <Line dataKey="value" />
  <YAxis />
  <XAxis />
  <ChartTooltip />
</LineChart>;
```

## Props

| Prop                 | Type                        | Default  | Description                                                                                      |
| -------------------- | --------------------------- | -------- | ------------------------------------------------------------------------------------------------ |
| `yAxisId`            | `string \| number`          | `"left"` | Scale group (pair with `yAxisId` on `Line` / `Area`)                                             |
| `orientation`        | `"left" \| "right"`         | `"left"` | Which side of the chart renders tick labels                                                      |
| `numTicks`           | `number`                    | `5`      | Approximate tick count hint for d3 `scale.ticks()` (actual labels may differ). Valid range: 1–10 |
| `formatLargeNumbers` | `boolean`                   | `true`   | Format values ≥1000 as "1k", "2k", etc.                                                          |
| `formatValue`        | `(value: number) => string` | —        | Custom tick formatter (overrides `formatLargeNumbers`)                                           |

## Multiple Y axes (biaxial)

Assign each series and axis the same `yAxisId`, and use `orientation="right"` on the secondary `YAxis`. Increase `margin.right` (and `margin.left` if needed) so labels fit.

```tsx
<LineChart data={data} margin={{ left: 56, right: 56 }}>
  <Line dataKey="uv" yAxisId="left" />
  <Line dataKey="pv" yAxisId="right" stroke="var(--chart-2)" />
  <YAxis yAxisId="left" />
  <YAxis yAxisId="right" orientation="right" />
  <XAxis />
</LineChart>
```

## Margin

YAxis renders labels in the chart's left margin. Use `margin={{ left: 50 }}` (or more) on your chart to leave space for the labels.

## Theming

Labels use the `text-chart-label` class, which inherits from your theme's muted foreground color.

---

# Background

> Pattern fill for the plot area when grid lines are hidden, with presets, an edge fade, and an enter animation

Source: https://ui.cortexcn.dev/docs/utility/background

## Installation

```bash
npx shadcn@latest add @cortexcn/background
```

## Usage

Use `Background` instead of `Grid` when you want a textured plot fill rather than reference lines. It must be a child of a cartesian chart (`LineChart`, `AreaChart`, `BarChart`, `ScatterChart`, `CandlestickChart`, `ComposedChart`, `LiveLineChart`, and other charts that provide chart context).

```tsx
import {
  LineChart,
  Line,
  Background,
  ChartTooltip,
  XAxis,
} from "@/components/charts";

<LineChart data={data}>
  <Background pattern="diagonal" />
  <Line dataKey="value" />
  <XAxis />
  <ChartTooltip />
</LineChart>;
```

`Background` renders behind series layers. On time-series charts it sits outside the series clip reveal and fades in after the chart finishes loading.

## Props

| Prop                   | Type                                                                                               | Default             | Description                                             |
| ---------------------- | -------------------------------------------------------------------------------------------------- | ------------------- | ------------------------------------------------------- |
| `pattern`              | `"diagonal" \| "horizontal" \| "vertical" \| "cross" \| "dots" \| "circles" \| "accent" \| "none"` | `"diagonal"`        | Pattern preset (`"none"` renders nothing)               |
| `color`                | `string`                                                                                           | `var(--chart-grid)` | Pattern stroke or dot color                             |
| `scale`                | `number`                                                                                           | `1`                 | Tile scale multiplier                                   |
| `strokeWidth`          | `number`                                                                                           | preset default      | Line stroke width for line-based patterns               |
| `radius`               | `number`                                                                                           | preset default      | Dot or circle radius for `dots` / `circles`             |
| `complement`           | `boolean`                                                                                          | `false`             | Alternate tile fill for circle patterns                 |
| `fill`                 | `string`                                                                                           | —                   | Solid fill inside circles                               |
| `dotFill`              | `boolean`                                                                                          | `true`              | Dot grid only — hollow dots when `false`                |
| `tileBackground`       | `string`                                                                                           | —                   | Background color inside each pattern tile               |
| `showFill`             | `boolean`                                                                                          | `true`              | Apply the pattern texture to the plot area              |
| `opacity`              | `number`                                                                                           | `1`                 | Pattern fill opacity                                    |
| `fadeHorizontal`       | `boolean`                                                                                          | `true`              | Fade pattern at left and right edges                    |
| `fadeVertical`         | `boolean`                                                                                          | `true`              | Fade pattern at top and bottom edges                    |
| `fadeHorizontalLength` | `number`                                                                                           | `10`                | Horizontal fade zone as % of plot width per edge (0–45) |
| `fadeVerticalLength`   | `number`                                                                                           | `10`                | Vertical fade zone as % of plot height per edge (0–45)  |

Patterns use [@visx/pattern](https://visx.airbnb.tech/docs/pattern) under the hood (`PatternLines` and `PatternCircles`).

## Examples

### Diagonal (default)

### Dot grid

### Cross hatch

### No edge fade

## Grid vs Background

Use [`Grid`](https://ui.cortexcn.dev/docs/utility/grid) for reference lines. Use `Background` when you want a subtle pattern fill without ticks. They are typically mutually exclusive — pick one visual treatment for the plot area.

---

# Brush

> Time-range brush for zooming area and line charts with a mini-chart strip and draggable selection handles

Source: https://ui.cortexcn.dev/docs/utility/brush

## Installation

`ChartBrush` and `ChartBrushLayout` ship with time-series charts. Install the [area chart](https://ui.cortexcn.dev/docs/components/area-chart) (or [line chart](https://ui.cortexcn.dev/docs/components/line-chart)) registry item, then import from your charts package:

```tsx
import {
  AreaChart,
  Area,
  ChartBrush,
  ChartBrushLayout,
  Grid,
  XAxis,
  ChartTooltip,
} from "@/components/charts";
```

## Usage

Wrap the main chart in `ChartBrushLayout`. Render a simplified mini chart in `brushStrip` with `ChartBrush` as a child. Pass `xDomain`, `xDomainSlotCount`, and `tweenYDomainOnXDomainChange` to the main chart so it zooms and tweens the y-scale as the brush changes.

```tsx
<ChartBrushLayout
  data={data}
  enabled
  height={72}
  brushStrip={(layout) => (
    <AreaChart
      animationDuration={0}
      data={data}
      status="ready"
      style={{ aspectRatio: "unset", height: "100%" }}
    >
      <Area
        dataKey="value"
        fillOpacity={0.15}
        animate={false}
        showHighlight={false}
      />
      <ChartBrush
        initialSelection={layout.brushSelection ?? undefined}
        onSelectionChange={layout.onBrushSelectionChange}
      />
    </AreaChart>
  )}
>
  {(layout) => (
    <AreaChart
      data={data}
      tweenYDomainOnXDomainChange
      xDomain={layout.xDomain}
      xDomainSlotCount={layout.xDomainSlotCount}
      yDomainTween
    >
      <Grid horizontal />
      <Area dataKey="value" fillOpacity={0.35} />
      <XAxis />
      <ChartTooltip />
    </AreaChart>
  )}
</ChartBrushLayout>
```

Works the same with `LineChart` and `Line` in the brush strip and main chart. See [Area Chart](https://ui.cortexcn.dev/docs/components/area-chart#brush-zoom) and [Line Chart](https://ui.cortexcn.dev/docs/components/line-chart#brush-zoom) for chart-specific notes.

## ChartBrushLayout

Orchestrates the main chart and optional brush strip. Owns brush selection state and derives `xDomain` for the main chart.

| Prop         | Type                        | Default  | Description                                      |
| ------------ | --------------------------- | -------- | ------------------------------------------------ |
| `data`       | `Record<string, unknown>[]` | required | Full dataset for the brush strip and main chart  |
| `xDataKey`   | `string`                    | `"date"` | Key in data for x-axis values                    |
| `enabled`    | `boolean`                   | required | When `false`, children render without brush zoom |
| `height`     | `number`                    | required | Brush strip height in pixels                     |
| `brushStrip` | `(layout) => ReactNode`     | —        | Mini chart + `ChartBrush` below the main chart   |
| `children`   | `(layout) => ReactNode`     | required | Main chart render function                       |
| `className`  | `string`                    | —        | Wrapper class name                               |

The `layout` argument provides:

| Field                    | Type                                 | Description                              |
| ------------------------ | ------------------------------------ | ---------------------------------------- |
| `xDomain`                | `[Date, Date] \| undefined`          | Visible x-range for the main chart       |
| `xDomainSlotCount`       | `number \| undefined`                | Full dataset length for x-scale padding  |
| `brushSelection`         | `{ start: Date; end: Date } \| null` | Current brush window                     |
| `onBrushSelectionChange` | `(selection) => void`                | Pass to `ChartBrush` `onSelectionChange` |

## ChartBrush

Renders inside a time-series chart (typically the brush strip). Drag handles to pan and resize; the main chart zooms via `ChartBrushLayout`.

| Prop                  | Type                                   | Default        | Description                                           |
| --------------------- | -------------------------------------- | -------------- | ----------------------------------------------------- |
| `onSelectionChange`   | `(domain) => void`                     | —              | Fires while dragging with the selected date range     |
| `initialSelection`    | `{ start: Date; end: Date }`           | —              | Initial brush window                                  |
| `selection`           | `{ start: Date; end: Date }`           | —              | Controlled selection                                  |
| `brushDirection`      | `"horizontal" \| "vertical" \| "both"` | `"horizontal"` | Brush axis                                            |
| `blurPx`              | `number`                               | `1.5`          | Backdrop blur on dimmed track (0–5 px)                |
| `fadeOuterEdges`      | `boolean`                              | `true`         | Fade dimmed regions at outer track edges              |
| `selectionPattern`    | `{ preset; color }`                    | —              | Pattern fill inside the selection window              |
| `useWindowMoveEvents` | `boolean`                              | `true`         | Use window move events (recommended for brush strips) |

### Selection pattern presets

`selectionPattern.preset` accepts: `diagonal`, `horizontal`, `vertical`, `cross`, `dots`, or `accent`. Omit `selectionPattern` for a solid selection fill.

## Main chart props

When brush zoom is active, pass these to `AreaChart` or `LineChart`:

| Prop                          | Type           | Default | Description                                             |
| ----------------------------- | -------------- | ------- | ------------------------------------------------------- |
| `xDomain`                     | `[Date, Date]` | —       | Visible x-range from `layout.xDomain`                   |
| `xDomainSlotCount`            | `number`       | —       | `layout.xDomainSlotCount` (full data length)            |
| `tweenYDomainOnXDomainChange` | `boolean`      | `false` | Tween y-domain when the brush changes the visible range |

## CSS variables

| Variable               | Default             | Description               |
| ---------------------- | ------------------- | ------------------------- |
| `--chart-brush-border` | `var(--chart-grid)` | Brush handle border color |

---

# Custom Indicator

> Create custom tooltip indicators for charts using the useChart hook

Source: https://ui.cortexcn.dev/docs/utility/custom-indicator

## Preview

## Overview

Custom indicators allow you to replace the default tooltip crosshair and dots with your own animated elements. This is useful for creating unique visual feedback like rising lines, custom shapes, or other interactive effects.

The demo above shows a grouped bar chart with two series—one with a gradient fill and one with a diagonal pattern—each with its own animated line indicator that rises on hover.

## Disabling Default Indicators

First, disable the built-in indicators on `ChartTooltip`:

```tsx
<ChartTooltip
  showCrosshair={false} // Hides the vertical crosshair line
  showDots={false} // Hides the dots on bars/lines
/>
```

## Creating an Animated Line Indicator

### Step 1: Create the Animated Element

Use `motion/react` with `useSpring` for smooth spring animations:

```tsx
import { motion, useSpring } from "motion/react";
import { useEffect } from "react";

function AnimatedBarLine({
  barX,
  barTopY,
  barBottomY,
  width,
  isHovered,
}: {
  barX: number;
  barTopY: number;
  barBottomY: number;
  width: number;
  isHovered: boolean;
}) {
  // Spring animations for position and opacity
  const animatedY = useSpring(barBottomY, { stiffness: 300, damping: 30 });
  const animatedOpacity = useSpring(0, { stiffness: 300, damping: 30 });

  useEffect(() => {
    // Rise to bar top when hovered, drop to bottom when not
    animatedY.set(isHovered ? barTopY : barBottomY);
    animatedOpacity.set(isHovered ? 1 : 0);
  }, [isHovered, barTopY, barBottomY, animatedY, animatedOpacity]);

  return (
    <motion.rect
      fill="var(--chart-indicator-color)"
      height={2}
      style={{
        opacity: animatedOpacity,
        y: animatedY,
      }}
      width={width}
      x={barX}
    />
  );
}
```

### Step 2: Access Chart State with useChart

The `useChart` hook provides all the data needed to position your indicator:

```tsx
import { useChart } from "@/components/charts";

function BarHorizontalLineIndicator({ data, dataKeys }) {
  const {
    barScale, // Scale to get x position from category
    bandWidth, // Width of each bar group
    innerHeight, // Chart height (for bottom position)
    yScale, // Scale to get y position from value
    hoveredBarIndex, // Which bar group is currently hovered
    margin, // Chart margins
    containerRef, // Ref for portal rendering
  } = useChart();

  // For grouped bars, divide bandWidth by number of series
  const individualBarWidth = bandWidth / dataKeys.length;

  // ... render indicators
}
```

### Step 3: Render via Portal

Use a portal to render the SVG overlay in the chart container. For grouped bar charts with multiple series, calculate each bar's position within the group:

```tsx
import React, { useEffect } from "react";

function BarHorizontalLineIndicator({ data, dataKeys }) {
  const {
    barScale,
    bandWidth,
    innerHeight,
    margin,
    containerRef,
    hoveredBarIndex,
    yScale,
  } = useChart();
  const [mounted, setMounted] = React.useState(false);

  useEffect(() => {
    setMounted(true);
  }, []);

  const container = containerRef.current;
  if (!(mounted && container && bandWidth && barScale)) {
    return null;
  }

  const { createPortal } = require("react-dom");

  // Calculate individual bar width for grouped bars
  const barCount = dataKeys.length;
  const individualBarWidth = bandWidth / barCount;

  return createPortal(
    <svg
      aria-hidden="true"
      className="pointer-events-none absolute inset-0 z-50"
      height="100%"
      width="100%"
    >
      <g transform={`translate(${margin.left},${margin.top})`}>
        {data.map((d, i) => {
          const groupX = barScale(d.month) ?? 0;
          const isHovered = hoveredBarIndex === i;

          return dataKeys.map((dataKey, barIndex) => {
            const barTopY = yScale(d[dataKey]) ?? innerHeight;
            const barX = groupX + barIndex * individualBarWidth;

            return (
              <AnimatedBarLine
                key={`${d.month}-${dataKey}`}
                barX={barX}
                barTopY={barTopY}
                barBottomY={innerHeight}
                width={individualBarWidth}
                isHovered={isHovered}
              />
            );
          });
        })}
      </g>
    </svg>,
    container,
  );
}
```

### Step 4: Add to Your Chart

Add the custom indicator as a child of your chart component. You can use gradients and patterns for different series:

```tsx
import { PatternLines } from "@/components/charts";

<BarChart data={data} xDataKey="month" barGap={0}>
  <LinearGradient id="gradient" from="var(--chart-3)" to="transparent" />
  <PatternLines
    id="diagonalPattern"
    height={6}
    width={6}
    stroke="var(--chart-4)"
    strokeWidth={1.5}
    orientation={["diagonal"]}
  />
  <Grid horizontal />
  <Bar dataKey="revenue" fill="url(#gradient)" stroke="var(--chart-3)" />
  <Bar dataKey="cost" fill="url(#diagonalPattern)" stroke="var(--chart-4)" />
  <BarXAxis />
  <ChartTooltip showCrosshair={false} showDots={false} />
  <BarHorizontalLineIndicator data={data} dataKeys={["revenue", "cost"]} />
</BarChart>;
```

## Key useChart Values for Indicators

| Value             | Type                  | Description                                  |
| ----------------- | --------------------- | -------------------------------------------- |
| `hoveredBarIndex` | `number \| null`      | Index of the currently hovered bar           |
| `barScale`        | `ScaleBand`           | Band scale for categorical x-axis positions  |
| `bandWidth`       | `number`              | Width of each bar band                       |
| `yScale`          | `ScaleLinear`         | Linear scale for y-axis values               |
| `innerHeight`     | `number`              | Chart area height (excluding margins)        |
| `margin`          | `Margin`              | Chart margins `{ top, right, bottom, left }` |
| `containerRef`    | `RefObject`           | Ref to the chart container (for portals)     |
| `tooltipData`     | `TooltipData \| null` | Current tooltip data including position      |

## Theming

Use CSS variables for proper light/dark mode support:

```tsx
// Use chartCssVars or CSS variables directly
<motion.rect fill="var(--chart-indicator-color)" />
```

Available indicator variables:

- `--chart-indicator-color` - Primary indicator color
- `--chart-indicator-secondary-color` - Secondary/stroke color

See [Theming](https://ui.cortexcn.dev/docs/theming) for the full list.

---

# Grid

> A customizable grid component for charts with horizontal and vertical lines, edge fade, edge line hiding, and dashed styling

Source: https://ui.cortexcn.dev/docs/utility/grid

## Installation

```bash
npx shadcn@latest add @cortexcn/grid
```

## Usage

The Grid component adds visual reference lines to charts. It must be used inside a chart component (`LineChart`, `AreaChart`, `BarChart`, `ScatterChart`, `CandlestickChart`, `LiveLineChart`, and other cartesian charts).

```tsx
import { LineChart, Line, Grid, ChartTooltip } from "@/components/charts";

<LineChart data={data}>
  <Grid horizontal />
  <Line dataKey="value" />
  <ChartTooltip />
</LineChart>;
```

## Props

| Prop                          | Type       | Default                         | Description                                                                                                                                              |
| ----------------------------- | ---------- | ------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `horizontal`                  | `boolean`  | `true`                          | Show horizontal grid lines                                                                                                                               |
| `vertical`                    | `boolean`  | `false`                         | Show vertical grid lines                                                                                                                                 |
| `numTicksRows`                | `number`   | `5`                             | Number of horizontal lines                                                                                                                               |
| `numTicksColumns`             | `number`   | `10`                            | Number of vertical lines                                                                                                                                 |
| `rowTickValues`               | `number[]` | -                               | Explicit tick values for horizontal grid lines. When set, overrides `numTicksRows`. Use with Live Line Chart so grid rows align with `LiveYAxis` labels. |
| `stroke`                      | `string`   | `var(--chart-grid)`             | Line color                                                                                                                                               |
| `strokeOpacity`               | `number`   | `1`                             | Line opacity                                                                                                                                             |
| `strokeWidth`                 | `number`   | `1`                             | Line width                                                                                                                                               |
| `strokeDasharray`             | `string`   | `"4,4"`                         | Dash pattern (empty string for solid)                                                                                                                    |
| `highlightRowValues`          | `number[]` | —                               | Emphasize horizontal lines at specific y values (e.g. `[0]` for break-even)                                                                              |
| `highlightRowStroke`          | `string`   | `var(--chart-foreground-muted)` | Stroke for highlighted rows                                                                                                                              |
| `highlightRowStrokeOpacity`   | `number`   | `1`                             | Opacity for highlighted rows                                                                                                                             |
| `highlightRowStrokeWidth`     | `number`   | `1`                             | Width for highlighted rows                                                                                                                               |
| `highlightRowStrokeDasharray` | `string`   | `"0"`                           | Dash pattern for highlighted rows                                                                                                                        |
| `fadeHorizontal`              | `boolean`  | `true`                          | Fade horizontal lines at left/right edges                                                                                                                |
| `fadeVertical`                | `boolean`  | `false`                         | Fade vertical lines at top/bottom edges                                                                                                                  |
| `hideHorizontalEdgeLines`     | `boolean`  | `false`                         | Omit the first and last horizontal grid lines                                                                                                            |
| `hideVerticalEdgeLines`       | `boolean`  | `false`                         | Omit the first and last vertical grid lines                                                                                                              |

For a pattern fill instead of grid lines, use [`Background`](https://ui.cortexcn.dev/docs/utility/background) in place of `Grid`.

## Examples

### Horizontal Only (Default)

The most common configuration with horizontal reference lines.

### Vertical Only

Use vertical grid lines to emphasize time intervals.

### Both Horizontal and Vertical

Display a full grid for detailed reference.

### Solid Lines

Remove the dash pattern for solid grid lines.

### Without Edge Fade

Disable the edge fade effect for sharp line endings.

### Hide edge lines

Omit the outermost horizontal or vertical grid lines — useful when the chart border already provides a frame.

### Dense Grid

Increase the number of grid lines for more granular reference.

### Custom Styling

```tsx
<LineChart data={data}>
  <Grid
    horizontal
    vertical
    stroke="var(--border)"
    strokeOpacity={0.5}
    strokeWidth={0.5}
    strokeDasharray=""
    fadeHorizontal={false}
    fadeVertical={false}
  />
  <Line dataKey="value" />
</LineChart>
```

## Theming

The Grid uses CSS variables for theming:

```css
:root {
  --chart-grid: oklch(0.9 0 0);
}

.dark {
  --chart-grid: oklch(0.25 0 0);
}
```

---

# Legend

> A composable legend component for charts with progress bars, markers, and customizable layouts

Source: https://ui.cortexcn.dev/docs/utility/legend

## Installation

```bash
npx shadcn@latest add @cortexcn/legend
```

## Usage

The Legend uses a composable API where you define the layout once and it maps to each item in your data:

```tsx
const data = [
  { label: "Organic", value: 4250, maxValue: 5000, color: "#0ea5e9" },
  { label: "Paid", value: 3120, maxValue: 5000, color: "#a855f7" },
];

<Legend items={data} title="Traffic Sources">
  <LegendItemComponent>
    <LegendMarker />
    <LegendLabel />
    <LegendValue />
  </LegendItemComponent>
</Legend>;
```

## Components

### Legend

The root container that provides context and maps items.

| Prop             | Type                              | Default                   | Description            |
| ---------------- | --------------------------------- | ------------------------- | ---------------------- |
| `items`          | `LegendItemData[]`                | required                  | Array of legend items  |
| `hoveredIndex`   | `number \| null`                  | -                         | Controlled hover state |
| `onHoverChange`  | `(index: number \| null) => void` | -                         | Hover callback         |
| `title`          | `string`                          | -                         | Title above the legend |
| `titleClassName` | `string`                          | `"text-sm font-semibold"` | Title styling          |
| `className`      | `string`                          | `""`                      | Container class        |

### LegendItemComponent

Wrapper for each legend item. Handles hover interactions and animations.

| Prop        | Type     | Default | Description          |
| ----------- | -------- | ------- | -------------------- |
| `className` | `string` | `""`    | Item container class |

### LegendMarker

Color indicator dot.

| Prop        | Type     | Default         | Description      |
| ----------- | -------- | --------------- | ---------------- |
| `className` | `string` | `"h-2.5 w-2.5"` | Size and styling |

### LegendLabel

Displays the item label.

| Prop        | Type     | Default                 | Description   |
| ----------- | -------- | ----------------------- | ------------- |
| `className` | `string` | `"text-sm font-medium"` | Label styling |

### LegendValue

Displays the item value with optional percentage.

| Prop                  | Type                             | Default                  | Description          |
| --------------------- | -------------------------------- | ------------------------ | -------------------- |
| `className`           | `string`                         | `"text-sm tabular-nums"` | Value styling        |
| `showPercentage`      | `boolean`                        | `false`                  | Show percentage      |
| `percentageClassName` | `string`                         | `"text-xs tabular-nums"` | Percentage styling   |
| `formatValue`         | `(value: number) => string`      | `toLocaleString()`       | Value formatter      |
| `formatPercentage`    | `(percentage: number) => string` | `${p.toFixed(0)}%`       | Percentage formatter |

### LegendProgress

Progress bar using base-ui Progress component.

| Prop                 | Type     | Default   | Description        |
| -------------------- | -------- | --------- | ------------------ |
| `height`             | `string` | `"h-1.5"` | Track height class |
| `trackClassName`     | `string` | `""`      | Track styling      |
| `indicatorClassName` | `string` | `""`      | Indicator styling  |

## Data Shape

```ts
interface LegendItemData {
  label: string; // Display label
  value: number; // Current value
  maxValue?: number; // Max value (for progress/percentage)
  color: string; // Item color
}
```

## Examples

### Simple Legend

### With Progress Bars

### Horizontal Layout

### Custom Value Formatting

```tsx
<Legend items={revenueData}>
  <LegendItemComponent className="flex items-center gap-3">
    <LegendMarker />
    <LegendLabel className="flex-1" />
    <LegendValue
      formatValue={(v) => `$${(v / 1000).toFixed(0)}k`}
      showPercentage
      formatPercentage={(p) => `(${p.toFixed(1)}%)`}
    />
  </LegendItemComponent>
</Legend>
```

### Synced with Chart

Connect the legend to a chart for bidirectional hover interactions:

```tsx
import { useState } from "react";
import {
  RingChart,
  Ring,
  RingCenter,
  Legend,
  LegendItemComponent,
  LegendMarker,
  LegendLabel,
  LegendValue,
} from "@/components/charts";

function SyncedChart() {
  const [hoveredIndex, setHoveredIndex] = useState<number | null>(null);

  return (
    <div className="flex items-center gap-8">
      <RingChart
        data={data}
        hoveredIndex={hoveredIndex}
        onHoverChange={setHoveredIndex}
      >
        {data.map((_, i) => (
          <Ring key={i} index={i} />
        ))}
        <RingCenter />
      </RingChart>

      <Legend
        items={data}
        hoveredIndex={hoveredIndex}
        onHoverChange={setHoveredIndex}
      >
        <LegendItemComponent className="flex items-center gap-3">
          <LegendMarker />
          <LegendLabel className="flex-1" />
          <LegendValue />
        </LegendItemComponent>
      </Legend>
    </div>
  );
}
```

## Hooks

### useLegend

Access the legend context from any child component:

```tsx
import { useLegend } from "@/components/charts";

function CustomComponent() {
  const { items, hoveredIndex, setHoveredIndex } = useLegend();
  // ...
}
```

### useLegendItem

Access the current item data from within a LegendItemComponent:

```tsx
import { useLegendItem } from "@/components/charts";

function CustomItemContent() {
  const { item, index, isHovered, isFaded, percentage } = useLegendItem();
  // ...
}
```

## Theming

The Legend uses CSS variables for theming:

```css
:root {
  --legend: oklch(1 0 0);
  --legend-foreground: oklch(0.141 0.005 285.823);
  --legend-muted: oklch(0.967 0.001 286.375);
  --legend-muted-foreground: oklch(0.552 0.016 285.938);
  --legend-track: oklch(0.92 0.004 286.32);
}

.dark {
  --legend: oklch(0.21 0.006 285.885);
  --legend-foreground: oklch(0.985 0 0);
  --legend-muted: oklch(0.274 0.006 286.033);
  --legend-muted-foreground: oklch(0.705 0.015 286.067);
  --legend-track: oklch(0.274 0.006 286.033);
}
```

## Dependencies

The LegendProgress component uses base-ui for accessible progress bars:

```bash
pnpm add @base-ui/react
```

---

# Projection Line

> Forecast segment extending a line series past the last data point, with a dashed stroke, a gradient, and a horizon marker

Source: https://ui.cortexcn.dev/docs/utility/projection-line

## Installation

```bash
npx shadcn@latest add @cortexcn/projection-line
```

## Usage

`ProjectionLine` draws a segment from the last data row (the anchor) into the future. It renders outside the series reveal clip so the horizon stays visible while the main line animates in.

Build the path with `buildProjectionPath`, or pass manual `{ date, value }[]` points. Pair with [`LineSeriesTerminalMarker`](https://ui.cortexcn.dev/docs/utility/projection-line#terminal-marker) at the anchor when you want a ring at the hand-off.

```tsx
import {
  buildProjectionPath,
  ChartTooltip,
  Grid,
  Line,
  LineChart,
  LineSeriesTerminalMarker,
  ProjectionLine,
  XAxis,
} from "@/components/charts";

const projectionPath = buildProjectionPath({
  sourceData: chartData,
  seriesKey: "value",
  mode: "target",
  pathDensity: "endpoints",
  horizonPoints: 6,
  endValue: 301,
});

<LineChart data={chartData}>
  <Grid horizontal />
  <Line dataKey="value" strokeWidth={2} />
  <LineSeriesTerminalMarker dataKey="value" />
  <ProjectionLine
    data={projectionPath}
    strokeDasharray="1,4"
    curveKind="bezier"
    strokeStyle="gradient"
    gradientStart="oklch(0.979 0.037 110.273)"
    gradientEnd="oklch(0.59 0.17 166.38)"
    showEndMarker
  />
  <XAxis />
  <ChartTooltip />
</LineChart>;
```

The chart extends its x-domain to fit the projection horizon. Projections are intended for line charts without [brush zoom](https://ui.cortexcn.dev/docs/utility/brush) — the two features are not supported together.

## ProjectionLine props

| Prop              | Type                    | Default          | Description                                       |
| ----------------- | ----------------------- | ---------------- | ------------------------------------------------- |
| `data`            | `ProjectionPoint[]`     | required         | Anchor + horizon points (`{ date, value }`)       |
| `yAxisId`         | `string \| number`      | `"left"`         | Y-scale group id                                  |
| `stroke`          | `string`                | `var(--chart-3)` | Solid stroke color                                |
| `strokeStyle`     | `"solid" \| "gradient"` | `"solid"`        | Solid or path-aligned gradient stroke             |
| `gradientStart`   | `string`                | `stroke`         | Gradient start when `strokeStyle` is `"gradient"` |
| `gradientEnd`     | `string`                | `var(--chart-5)` | Gradient end when `strokeStyle` is `"gradient"`   |
| `strokeWidth`     | `number`                | `2`              | Stroke width                                      |
| `curveKind`       | `"linear" \| "bezier"`  | `"linear"`       | Straight segment or horizontal-tangent S-curve    |
| `strokeDasharray` | `string`                | `"6,4"`          | Dash pattern                                      |
| `strokeOpacity`   | `number`                | `1`              | Stroke opacity                                    |
| `showEndMarker`   | `boolean`               | `true`           | Horizon endpoint dot (`ProjectionLineEndMarker`)  |
| `endpointRadius`  | `number`                | `5`              | Horizon marker radius                             |

## buildProjectionPath

| Option          | Type                                  | Default              | Description                            |
| --------------- | ------------------------------------- | -------------------- | -------------------------------------- |
| `sourceData`    | `Record<string, unknown>[]`           | required             | Chart rows                             |
| `seriesKey`     | `string`                              | required             | Y value key                            |
| `xDataKey`      | `string`                              | `"date"`             | X value key                            |
| `mode`          | `"auto" \| "target" \| "manual"`      | required             | How future points are generated        |
| `autoMethod`    | `"linearRegression" \| "lastSegment"` | `"linearRegression"` | Slope for `mode="auto"`                |
| `pathDensity`   | `"stepped" \| "endpoints"`            | `"endpoints"`        | Stepped path vs anchor + end only      |
| `horizonPoints` | `number`                              | `6`                  | Future intervals for auto/target modes |
| `endValue`      | `number`                              | —                    | Target Y when `mode="target"`          |
| `points`        | `ProjectionPoint[]`                   | —                    | Manual path when `mode="manual"`       |
| `startIndex`    | `number`                              | last row             | Anchor row index                       |

## Terminal marker

`LineSeriesTerminalMarker` renders a hollow ring at the last data point for the given `dataKey`. It fades in after the clip reveal completes.

| Prop          | Type               | Default          | Description              |
| ------------- | ------------------ | ---------------- | ------------------------ |
| `dataKey`     | `string`           | required         | Series to anchor         |
| `yAxisId`     | `string \| number` | `"left"`         | Y-scale group id         |
| `fill`        | `string`           | `transparent`    | Dot fill                 |
| `stroke`      | `string`           | `var(--chart-1)` | Ring color               |
| `radius`      | `number`           | `5`              | Dot radius               |
| `ringGap`     | `number`           | `0`              | Gap between dot and ring |
| `strokeWidth` | `number`           | `1.5`            | Ring stroke width        |

## Examples

### Auto forecast with terminal marker

### Gradient stroke

## Gallery

See **Projection** on the [line chart gallery](https://ui.cortexcn.dev/charts/line-chart).

---

# Reference Area

> Shaded Y band for target ranges and thresholds on cartesian charts, with a solid or pattern fill, dashed edges, and Y-axis tick coloring

Source: https://ui.cortexcn.dev/docs/utility/reference-area

## Installation

```bash
npx shadcn@latest add @cortexcn/reference-area
```

## Usage

`ReferenceArea` draws a horizontal band between two Y data values. Place it as a child of any cartesian chart (`LineChart`, `AreaChart`, `BarChart`, `ScatterChart`, `CandlestickChart`, `ComposedChart`, `LiveLineChart`). It renders in the underlay layer — above grid and background, behind series.

```tsx
import {
  LineChart,
  Line,
  Grid,
  ReferenceArea,
  ChartTooltip,
  XAxis,
} from "@/components/charts";

<LineChart data={data}>
  <Grid horizontal />
  <ReferenceArea y1={160} y2={220} strokeStyle="dashed" showMarkers />
  <Line dataKey="value" />
  <XAxis />
  <ChartTooltip />
</LineChart>;
```

Omit `y1` or `y2` to extend the band to the top or bottom of the plot. Use `axisLabelColor` to tint Y-axis tick labels whose values fall inside the band.

## Props

| Prop                    | Type                    | Default                                 | Description                                                    |
| ----------------------- | ----------------------- | --------------------------------------- | -------------------------------------------------------------- |
| `y1`                    | `number`                | —                                       | Lower Y data bound (extends to plot top when omitted)          |
| `y2`                    | `number`                | —                                       | Upper Y data bound (extends to plot bottom when omitted)       |
| `x1`                    | `Date \| number`        | —                                       | Starting X data coordinate (extends to plot left when omitted) |
| `x2`                    | `Date \| number`        | —                                       | Ending X data coordinate (extends to plot right when omitted)  |
| `yAxisId`               | `string \| number`      | `"left"`                                | Y-scale group id                                               |
| `fill`                  | `string`                | muted mix on `--chart-foreground-muted` | Solid fill when `pattern` is `"none"`                          |
| `fillOpacity`           | `number`                | `1`                                     | Fill opacity                                                   |
| `pattern`               | Pattern preset id       | `"none"`                                | Pattern fill inside the band                                   |
| `patternColor`          | `string`                | —                                       | Pattern stroke or tile color                                   |
| `patternScale`          | `number`                | —                                       | Pattern tile scale                                             |
| `patternStrokeWidth`    | `number`                | —                                       | Line stroke width for line-based patterns                      |
| `patternRadius`         | `number`                | —                                       | Dot or circle radius for `dots` / `circles`                    |
| `patternComplement`     | `boolean`               | —                                       | Alternate tile fill for circle patterns                        |
| `patternFill`           | `string`                | —                                       | Solid fill inside circles                                      |
| `patternDotFill`        | `boolean`               | —                                       | Dot grid only — hollow dots when `false`                       |
| `patternTileBackground` | `string`                | —                                       | Background color inside each pattern tile                      |
| `stroke`                | `string`                | —                                       | Edge line color                                                |
| `strokeWidth`           | `number`                | `1`                                     | Edge line width                                                |
| `strokeStyle`           | `"solid" \| "dashed"`   | `"solid"`                               | Edge line style                                                |
| `strokeDasharray`       | `string`                | `"4,4"`                                 | Dash array when `strokeStyle` is `"dashed"`                    |
| `fadeEdges`             | `boolean`               | `true`                                  | Fade fill and edges at left/right                              |
| `fadeEdgesLength`       | `number`                | `10`                                    | Horizontal fade zone as % of plot width per edge (0–45)        |
| `axisLabelColor`        | `string`                | —                                       | Y-axis tick label color for values inside the band             |
| `showMarkers`           | `boolean`               | `false`                                 | Inward bracket markers at the horizontal center                |
| `markerColor`           | `string`                | —                                       | Bracket marker color                                           |
| `markerSize`            | `number`                | —                                       | Bracket marker size                                            |
| `ifOverflow`            | `"hidden" \| "visible"` | `"hidden"`                              | Clip band to the plot when bounds exceed the domain            |

Pattern presets match [`Background`](https://ui.cortexcn.dev/docs/utility/background) (`diagonal`, `dots`, `cross`, …).

## Examples

### Dashed band with markers

### Pattern fill with axis labels

### Colored markers

## Gallery

See **Reference Band** examples on each cartesian chart gallery: [line](https://ui.cortexcn.dev/charts/line-chart), [area](https://ui.cortexcn.dev/charts/area-chart), [bar](https://ui.cortexcn.dev/charts/bar-chart), [composed](https://ui.cortexcn.dev/charts/composed-chart), [scatter](https://ui.cortexcn.dev/charts/scatter-chart), [candlestick](https://ui.cortexcn.dev/charts/candlestick-chart), [live line](https://ui.cortexcn.dev/charts/live-line-chart), and [profit/loss line](https://ui.cortexcn.dev/charts/profit-loss-line).

---

# Tooltip

> An interactive tooltip component for charts with crosshair, dots, date picker, and customizable content

Source: https://ui.cortexcn.dev/docs/utility/tooltip

## Installation

```bash
npx shadcn@latest add @cortexcn/chart-tooltip
```

## Usage

The ChartTooltip component provides hover interactions for charts. It must be used inside a chart component (`LineChart`, `AreaChart`, `BarChart`).

```tsx
import { LineChart, Line, Grid, ChartTooltip } from "@/components/charts";

<LineChart data={data}>
  <Grid horizontal />
  <Line dataKey="value" />
  <ChartTooltip />
</LineChart>;
```

## Props

| Prop                  | Type                                     | Default                           | Description                                                                                   |
| --------------------- | ---------------------------------------- | --------------------------------- | --------------------------------------------------------------------------------------------- |
| `showDatePill`        | `boolean`                                | `true`                            | Show animated date ticker at bottom                                                           |
| `showCrosshair`       | `boolean`                                | `true`                            | Show vertical crosshair line                                                                  |
| `showDots`            | `boolean`                                | `true`                            | Show dots on data points                                                                      |
| `indicatorColor`      | `string \| (point) => string`            | —                                 | Crosshair and dot color; pass a function for dynamic colors                                   |
| `indicatorDasharray`  | `string`                                 | —                                 | SVG dash pattern for the crosshair (e.g. `"4,4"`). Omit for solid                             |
| `indicatorFadeEdges`  | `"both" \| "top" \| "bottom" \| "none"`  | `"both"`                          | Vertical crosshair fade; `none` = solid line                                                  |
| `indicatorFadeLength` | `number`                                 | `10`                              | Fade zone size (% of crosshair height) when fading                                            |
| `matchCrosshair`      | `boolean`                                | `false`                           | When `true`, the panel uses the crosshair spring and moves in sync                            |
| `damping`             | `number`                                 | `20`                              | Panel follow damping (default). `0` = instant. Ignored when `matchCrosshair` is `true`        |
| `springConfig`        | `{ stiffness: number; damping: number }` | chart config                      | Full spring override for crosshair, dots, and date pill                                       |
| `boxSpringConfig`     | `{ stiffness: number; damping: number }` | chart config                      | Full spring override for the floating tooltip panel                                           |
| `backgroundColor`     | `string`                                 | `var(--chart-tooltip-background)` | Panel background (CSS variable or color value)                                                |
| `panelStyle`          | `CSSProperties`                          | —                                 | Inline styles for tooltip background and blur                                                 |
| `dotVariant`          | `"dot" \| "ring"`                        | `"dot"`                           | Dot style on series markers                                                                   |
| `dotRadiusFraction`   | `number`                                 | —                                 | Ring corner radius as a fraction of side length (0 = square, 0.5 = circle). Ring variant only |
| `dotScale`            | `number`                                 | `1`                               | Size multiplier for ring indicators. Ring variant only                                        |
| `dotStrokeWidth`      | `number`                                 | `1.5`                             | Ring stroke width in pixels. Ring variant only                                                |
| `dotColor`            | `string \| (point, line) => string`      | —                                 | Override dot/ring color (e.g. when fill is gradient/pattern)                                  |
| `content`             | `(props) => ReactNode`                   | -                                 | Custom content renderer                                                                       |
| `rows`                | `(point) => TooltipRow[]`                | -                                 | Custom row generator                                                                          |
| `children`            | `ReactNode`                              | -                                 | Additional content (e.g., markers)                                                            |
| `className`           | `string`                                 | `""`                              | Additional CSS class                                                                          |

### TooltipRow Interface

```ts
interface TooltipRow {
  color: string; // Dot color
  label: string; // Row label
  value: string | number; // Display value
}
```

## Anatomy

The tooltip has several visual components:

1. **Crosshair** - Vertical line that follows the cursor
2. **Dots** - Circles on each data point at the hovered position
3. **Tooltip Box** - Content panel with title and rows
4. **Date Pill** - Animated date ticker at the bottom

Each component can be shown/hidden independently.

## Examples

### Default Tooltip

Full-featured tooltip with crosshair, dots, and date pill.

### Solid crosshair

Remove vertical fade with `indicatorFadeEdges="none"` for a flat crosshair line.

### Crosshair fade

Fade the crosshair from the top, bottom, both ends, or not at all. Use `indicatorFadeLength` to control how far the fade extends (percentage of chart height).

### Dashed crosshair

Pass an SVG dash pattern to `indicatorDasharray`.

### Match crosshair

By default the tooltip panel eases independently with `damping={20}`. Set `matchCrosshair` to lock the panel to the crosshair spring.

### Panel damping

The default panel uses `damping={20}` without any props. Increase `damping` for heavier lag, or set `damping={0}` for instant follow.

### Crosshair Only

Minimal tooltip with just the crosshair line and tooltip box.

### Minimal (Box Only)

Just the tooltip content box, no visual indicators.

### Custom Row Labels

Use the `rows` prop to customize row labels and value formatting.

### With Bar Chart

The tooltip adapts to bar charts, showing category names instead of dates.

### Fully Custom Content

Use the `content` prop for complete control over the tooltip layout.

## Animation

The tooltip features smooth animations:

- **Tooltip panel** - By default the panel eases with `damping={20}`. Set `matchCrosshair` to share the crosshair spring, or tune lag with `damping` (`0`–`100`) or `boxSpringConfig`.
- **Crosshair** - Spring physics for snappy following (`springConfig`)
- **Crosshair style** - Solid by default; pass `indicatorDasharray="4,4"` (or any SVG dash pattern) for a dashed line.
- **Tooltip Box** - Scale/fade animation with flip detection (`boxSpringConfig`)
- **Date Pill** - Slot machine-style number animation
- **Dots** - Fade in/out with the tooltip

All animations use motion/react for fluid, natural movement.

```tsx
<ChartTooltip
  indicatorDasharray="6,4"
  damping={60}
  indicatorColor="var(--chart-2)"
/>
```

## Theming

The tooltip uses CSS variables for theming:

```css
:root {
  --chart-background: oklch(1 0 0);
  --chart-crosshair: oklch(0.4 0.1828 274.34);
}

.dark {
  --chart-background: oklch(0.145 0 0);
  --chart-crosshair: oklch(0.45 0 0);
}
```

The tooltip box itself uses a semi-transparent dark background with blur for universal readability.

---

# useChart Hook

> Access chart state and context for building custom chart components

Source: https://ui.cortexcn.dev/docs/utility/use-chart

## Overview

The `useChart` hook provides access to the chart's internal state, scales, dimensions, and tooltip data. Use it to build custom components that integrate with the chart system.

```tsx
import { useChart } from "@/components/charts";

function MyCustomComponent() {
  const { tooltipData, hoveredBarIndex, yScale, innerHeight } = useChart();
  // ... use chart state
}
```

## Requirements

The hook must be used within a chart component (`LineChart`, `AreaChart`, or `BarChart`). It will throw an error if used outside of a chart context.

```tsx
// Correct: Inside a chart
<BarChart data={data} xDataKey="month">
  <MyCustomComponent /> {/* useChart works here */}
</BarChart>

// Error: Outside a chart
<MyCustomComponent /> {/* useChart will throw */}
```

## Return Values

### Dimensions

| Property      | Type     | Description                                  |
| ------------- | -------- | -------------------------------------------- |
| `width`       | `number` | Total chart width in pixels                  |
| `height`      | `number` | Total chart height in pixels                 |
| `innerWidth`  | `number` | Chart area width (excluding margins)         |
| `innerHeight` | `number` | Chart area height (excluding margins)        |
| `margin`      | `Margin` | Chart margins `{ top, right, bottom, left }` |
| `columnWidth` | `number` | Width of a single data column                |

### Scales

| Property    | Type                     | Description                                         |
| ----------- | ------------------------ | --------------------------------------------------- |
| `xScale`    | `ScaleTime`              | Time scale for x-axis (line/area charts)            |
| `yScale`    | `ScaleLinear`            | Linear scale for y-axis values                      |
| `barScale`  | `ScaleBand \| undefined` | Band scale for categorical x-axis (bar charts only) |
| `bandWidth` | `number \| undefined`    | Width of each bar band (bar charts only)            |

### Tooltip State

| Property             | Type                          | Description                            |
| -------------------- | ----------------------------- | -------------------------------------- |
| `tooltipData`        | `TooltipData \| null`         | Current tooltip data when hovering     |
| `setTooltipData`     | `Dispatch`                    | Setter for tooltip data                |
| `hoveredBarIndex`    | `number \| null \| undefined` | Index of hovered bar (bar charts only) |
| `setHoveredBarIndex` | `Function \| undefined`       | Setter for hovered bar index           |

### TooltipData Structure

```tsx
interface TooltipData {
  point: Record<string, unknown>; // The data point being hovered
  index: number; // Index in the data array
  x: number; // X position in pixels
  yPositions: Record<string, number>; // Y positions keyed by dataKey
  xPositions?: Record<string, number>; // X positions (grouped bars)
}
```

### Container & Animation

| Property            | Type                        | Description                                  |
| ------------------- | --------------------------- | -------------------------------------------- |
| `containerRef`      | `RefObject<HTMLDivElement>` | Ref to chart container (for portals)         |
| `isLoaded`          | `boolean`                   | Whether chart has finished initial animation |
| `animationDuration` | `number`                    | Animation duration in milliseconds           |

### Data & Configuration

| Property       | Type                        | Description                                  |
| -------------- | --------------------------- | -------------------------------------------- |
| `data`         | `Record<string, unknown>[]` | The chart's data array                       |
| `lines`        | `LineConfig[]`              | Registered line/bar configurations           |
| `xAccessor`    | `Function`                  | Function to get Date from data point         |
| `barXAccessor` | `Function \| undefined`     | Function to get category string (bar charts) |
| `dateLabels`   | `string[]`                  | Pre-computed date labels for ticker          |

### Bar Chart Specific

| Property       | Type                         | Description                          |
| -------------- | ---------------------------- | ------------------------------------ |
| `orientation`  | `"vertical" \| "horizontal"` | Bar chart orientation                |
| `stacked`      | `boolean \| undefined`       | Whether bars are stacked             |
| `stackOffsets` | `Map`                        | Stack offset values for stacked bars |

## Common Use Cases

### Reading Hover Position

```tsx
function HoverIndicator() {
  const { tooltipData, innerHeight, margin } = useChart();

  if (!tooltipData) return null;

  return (
    <div
      style={{
        position: "absolute",
        left: tooltipData.x + margin.left,
        top: margin.top,
        height: innerHeight,
      }}
    >
      {/* Custom indicator */}
    </div>
  );
}
```

### Accessing Bar Positions

```tsx
function BarOverlay() {
  const { barScale, bandWidth, hoveredBarIndex, data } = useChart();

  if (!barScale || hoveredBarIndex === null) return null;

  const hoveredData = data[hoveredBarIndex];
  const x = barScale(hoveredData.category);

  return <rect x={x} width={bandWidth} /* ... */ />;
}
```

### Using Scales for Custom Rendering

```tsx
function CustomMarker({ value, category }) {
  const { yScale, barScale, innerHeight } = useChart();

  const y = yScale(value);
  const x = barScale?.(category) ?? 0;

  return <circle cx={x} cy={y} r={5} fill="red" />;
}
```

## Related

- [Custom Indicator](https://ui.cortexcn.dev/docs/utility/custom-indicator) - Building custom tooltip indicators
- [Theming](https://ui.cortexcn.dev/docs/theming) - Theming with CSS variables
