AreaChart
A time series drawn on the server, this period in brand green with a 10% wash and an optional dashed comparison, with one interactive layer for the crosshair, the tooltip and keyboard access to every point.
Import
import { AreaChart } from '@nizivo/charts/area-chart';Static or interactive
Split. AreaChart's SVG, tick labels, legend and data table are server HTML. Its module imports
one client module, the ChartInteraction island, which it renders only when the status is 'ready'
and interaction is 'nizivo' (the default). With interaction="none" it renders no island and
the plot has no Tab stop. The data table is then the screen-reader path; pass
tableView="details" so sighted keyboard users can reach the values too.
As with Field and IconButton in @nizivo/react, the shell imports its leaf: Turbopack and
next dev ship a client module that a page's server code imports, rendered or not. To ship no
chart JavaScript, draw the chart with a part that imports no client module. The Next.js fixture's
page for this case (fixtures/next/app/chart-area-static, recorded in week 10) shows it: Turbopack
and next dev ship the imported island (1,056 B gzip under Turbopack in week 10; the island has
grown since, see Sizes), and webpack ships nothing
(fixtures/next/RESULTS.md, "Week 10"). Each charts page has its own route, so on this site the
island loads on this page and the BarChart page only. How to choose.
Long series. Measured on 2026-10-20 (M40) with a comparison series and USD values, a year of
daily points (365) is about 82 KB of server HTML (15.5 KB gzip) and 164 KB of RSC payload (28.8 KB
gzip), of which 23 KB is the island's props: about 64 B of JSON a point (week 10: about 335 B).
The same year bucketed weekly (52 points) is 14 KB of HTML (3.1 KB gzip) and 26 KB of RSC payload
(5 KB gzip). area-chart.server.test.tsx in packages/charts/test/ssr holds the island's props
to 50 to 80 B a point at 365 points. Bytes no longer force bucketing at 90 points (13.9 KB gzip in
all, the island's code included), but on Figma's 720 px plot a daily year leaves 2 px a point and
365 arrow-key steps, so above about 90 points, bucket daily data weekly before passing it in.
Examples
Basic
- This period
- Previous
| Date | This period | Previous |
|---|---|---|
| Thu, Oct 1 | $2,200 | $2,980 |
| Fri, Oct 2 | $2,712 | $3,014 |
| Sat, Oct 3 | $3,169 | $3,009 |
| Sun, Oct 4 | $3,527 | $2,970 |
| Mon, Oct 5 | $3,401 | $2,909 |
| Tue, Oct 6 | $3,513 | $2,839 |
| Wed, Oct 7 | $3,530 | $2,772 |
| Thu, Oct 8 | $3,495 | $2,723 |
| Fri, Oct 9 | $3,106 | $2,702 |
| Sat, Oct 10 | $3,136 | $2,719 |
| Sun, Oct 11 | $3,269 | $2,777 |
| Mon, Oct 12 | $3,525 | $2,876 |
| Tue, Oct 13 | $3,543 | $3,012 |
| Wed, Oct 14 | $4,013 | $3,174 |
| Thu, Oct 15 | $4,530 | $3,353 |
| Fri, Oct 16 | $5,036 | $3,533 |
| Sat, Oct 17 | $5,118 | $3,701 |
| Sun, Oct 18 | $5,455 | $3,845 |
| Mon, Oct 19 | $5,667 | $3,955 |
| Tue, Oct 20 | $5,760 | $4,025 |
| Wed, Oct 21 | $5,403 | $4,052 |
| Thu, Oct 22 | $5,365 | $4,041 |
| Fri, Oct 23 | $5,343 | $3,999 |
| Sat, Oct 24 | $5,389 | $3,936 |
| Sun, Oct 25 | $5,182 | $3,865 |
| Mon, Oct 26 | $5,462 | $3,800 |
| Tue, Oct 27 | $5,858 | $3,754 |
| Wed, Oct 28 | $6,341 | $3,739 |
| Thu, Oct 29 | $6,499 | $3,762 |
| Fri, Oct 30 | $6,998 | $3,826 |
import type { JSX } from 'react';
import { AreaChart } from '@nizivo/charts/area-chart';
interface Day {
date: string;
current: number;
previous: number;
}
// Thirty days of sales, as Figma 03 draws them (Oct 1–30, this period vs the previous one).
// Deterministic, so the visual lane's shots are stable.
const DAYS: Day[] = Array.from({ length: 30 }, (_, i) => ({
date: `2026-10-${String(i + 1).padStart(2, '0')}`,
current: Math.round(2200 + i * 150 + Math.sin(i / 2.2) * 620 + (i % 4) * 90),
previous: Math.round(2600 + i * 55 + Math.cos(i / 3) * 380),
}));
const USD = { style: 'currency', currency: 'USD', maximumFractionDigits: 0 } as const;
export function AreaChartExample(): JSX.Element {
return (
<AreaChart
title="Sales"
summary="Daily sales, Oct 1–30, vs previous period"
data={DAYS}
x="date"
y="current"
compare="previous"
format={USD}
/>
);
}
Single
One series, no comparison: no legend, no delta.
| Date | This period |
|---|---|
| Thu, Oct 1 | 52 |
| Fri, Oct 2 | 65 |
| Sat, Oct 3 | 75 |
| Sun, Oct 4 | 84 |
| Mon, Oct 5 | 81 |
| Tue, Oct 6 | 84 |
| Wed, Oct 7 | 84 |
| Thu, Oct 8 | 83 |
| Fri, Oct 9 | 74 |
| Sat, Oct 10 | 75 |
| Sun, Oct 11 | 78 |
| Mon, Oct 12 | 84 |
| Tue, Oct 13 | 84 |
| Wed, Oct 14 | 96 |
import type { JSX } from 'react';
import { AreaChart } from '@nizivo/charts/area-chart';
interface Day {
date: string;
current: number;
previous: number;
}
// Thirty days of sales, as Figma 03 draws them (Oct 1–30, this period vs the previous one).
// Deterministic, so the visual lane's shots are stable.
const DAYS: Day[] = Array.from({ length: 30 }, (_, i) => ({
date: `2026-10-${String(i + 1).padStart(2, '0')}`,
current: Math.round(2200 + i * 150 + Math.sin(i / 2.2) * 620 + (i % 4) * 90),
previous: Math.round(2600 + i * 55 + Math.cos(i / 3) * 380),
}));
export function AreaChartSingleExample(): JSX.Element {
return (
<AreaChart
title="Orders"
data={DAYS.slice(0, 14)}
x="date"
y={(day) => Math.round(day.current / 42)}
/>
);
}
Static
The data table as a native disclosure under the plot, and no keyboard layer (zero JS).
Show data table
| Date | This period |
|---|---|
| Thu, Oct 1 | $2,200 |
| Fri, Oct 2 | $2,712 |
| Sat, Oct 3 | $3,169 |
| Sun, Oct 4 | $3,527 |
| Mon, Oct 5 | $3,401 |
| Tue, Oct 6 | $3,513 |
| Wed, Oct 7 | $3,530 |
| Thu, Oct 8 | $3,495 |
| Fri, Oct 9 | $3,106 |
| Sat, Oct 10 | $3,136 |
| Sun, Oct 11 | $3,269 |
| Mon, Oct 12 | $3,525 |
| Tue, Oct 13 | $3,543 |
| Wed, Oct 14 | $4,013 |
| Thu, Oct 15 | $4,530 |
| Fri, Oct 16 | $5,036 |
| Sat, Oct 17 | $5,118 |
| Sun, Oct 18 | $5,455 |
| Mon, Oct 19 | $5,667 |
| Tue, Oct 20 | $5,760 |
| Wed, Oct 21 | $5,403 |
| Thu, Oct 22 | $5,365 |
| Fri, Oct 23 | $5,343 |
| Sat, Oct 24 | $5,389 |
| Sun, Oct 25 | $5,182 |
| Mon, Oct 26 | $5,462 |
| Tue, Oct 27 | $5,858 |
| Wed, Oct 28 | $6,341 |
| Thu, Oct 29 | $6,499 |
| Fri, Oct 30 | $6,998 |
import type { JSX } from 'react';
import { AreaChart } from '@nizivo/charts/area-chart';
interface Day {
date: string;
current: number;
previous: number;
}
// Thirty days of sales, as Figma 03 draws them (Oct 1–30, this period vs the previous one).
// Deterministic, so the visual lane's shots are stable.
const DAYS: Day[] = Array.from({ length: 30 }, (_, i) => ({
date: `2026-10-${String(i + 1).padStart(2, '0')}`,
current: Math.round(2200 + i * 150 + Math.sin(i / 2.2) * 620 + (i % 4) * 90),
previous: Math.round(2600 + i * 55 + Math.cos(i / 3) * 380),
}));
const USD = { style: 'currency', currency: 'USD', maximumFractionDigits: 0 } as const;
export function AreaChartStaticExample(): JSX.Element {
return (
<AreaChart
title="Sales"
data={DAYS}
x="date"
y="current"
format={USD}
interaction="none"
tableView="details"
/>
);
}
Status
Loading, empty and error keep the chart's box (§16.5).
import type { JSX } from 'react';
import { AreaChart } from '@nizivo/charts/area-chart';
interface Day {
date: string;
current: number;
previous: number;
}
// Thirty days of sales, as Figma 03 draws them (Oct 1–30, this period vs the previous one).
// Deterministic, so the visual lane's shots are stable.
const DAYS: Day[] = Array.from({ length: 30 }, (_, i) => ({
date: `2026-10-${String(i + 1).padStart(2, '0')}`,
current: Math.round(2200 + i * 150 + Math.sin(i / 2.2) * 620 + (i % 4) * 90),
previous: Math.round(2600 + i * 55 + Math.cos(i / 3) * 380),
}));
export function AreaChartStatusExample(): JSX.Element {
return (
<div>
<AreaChart title="Sales" status="loading" data={DAYS} x="date" y="current" />
<AreaChart title="Sales" data={[] as Day[]} x="date" y="current" />
<AreaChart title="Sales" status="error" data={DAYS} x="date" y="current" />
</div>
);
}
Right to left
Time mirrored for a right-to-left page that wants it (xDirection="rtl"; the default keeps ltr).
- هذه الفترة
- الفترة السابقة
| Date | هذه الفترة | الفترة السابقة |
|---|---|---|
| الخميس، ١ أكتوبر | ٢٬٢٠٠ | ٢٬٩٨٠ |
| الجمعة، ٢ أكتوبر | ٢٬٧١٢ | ٣٬٠١٤ |
| السبت، ٣ أكتوبر | ٣٬١٦٩ | ٣٬٠٠٩ |
| الأحد، ٤ أكتوبر | ٣٬٥٢٧ | ٢٬٩٧٠ |
| الاثنين، ٥ أكتوبر | ٣٬٤٠١ | ٢٬٩٠٩ |
| الثلاثاء، ٦ أكتوبر | ٣٬٥١٣ | ٢٬٨٣٩ |
| الأربعاء، ٧ أكتوبر | ٣٬٥٣٠ | ٢٬٧٧٢ |
| الخميس، ٨ أكتوبر | ٣٬٤٩٥ | ٢٬٧٢٣ |
| الجمعة، ٩ أكتوبر | ٣٬١٠٦ | ٢٬٧٠٢ |
| السبت، ١٠ أكتوبر | ٣٬١٣٦ | ٢٬٧١٩ |
| الأحد، ١١ أكتوبر | ٣٬٢٦٩ | ٢٬٧٧٧ |
| الاثنين، ١٢ أكتوبر | ٣٬٥٢٥ | ٢٬٨٧٦ |
| الثلاثاء، ١٣ أكتوبر | ٣٬٥٤٣ | ٣٬٠١٢ |
| الأربعاء، ١٤ أكتوبر | ٤٬٠١٣ | ٣٬١٧٤ |
| الخميس، ١٥ أكتوبر | ٤٬٥٣٠ | ٣٬٣٥٣ |
| الجمعة، ١٦ أكتوبر | ٥٬٠٣٦ | ٣٬٥٣٣ |
| السبت، ١٧ أكتوبر | ٥٬١١٨ | ٣٬٧٠١ |
| الأحد، ١٨ أكتوبر | ٥٬٤٥٥ | ٣٬٨٤٥ |
| الاثنين، ١٩ أكتوبر | ٥٬٦٦٧ | ٣٬٩٥٥ |
| الثلاثاء، ٢٠ أكتوبر | ٥٬٧٦٠ | ٤٬٠٢٥ |
| الأربعاء، ٢١ أكتوبر | ٥٬٤٠٣ | ٤٬٠٥٢ |
| الخميس، ٢٢ أكتوبر | ٥٬٣٦٥ | ٤٬٠٤١ |
| الجمعة، ٢٣ أكتوبر | ٥٬٣٤٣ | ٣٬٩٩٩ |
| السبت، ٢٤ أكتوبر | ٥٬٣٨٩ | ٣٬٩٣٦ |
| الأحد، ٢٥ أكتوبر | ٥٬١٨٢ | ٣٬٨٦٥ |
| الاثنين، ٢٦ أكتوبر | ٥٬٤٦٢ | ٣٬٨٠٠ |
| الثلاثاء، ٢٧ أكتوبر | ٥٬٨٥٨ | ٣٬٧٥٤ |
| الأربعاء، ٢٨ أكتوبر | ٦٬٣٤١ | ٣٬٧٣٩ |
| الخميس، ٢٩ أكتوبر | ٦٬٤٩٩ | ٣٬٧٦٢ |
| الجمعة، ٣٠ أكتوبر | ٦٬٩٩٨ | ٣٬٨٢٦ |
import type { JSX } from 'react';
import { AreaChart } from '@nizivo/charts/area-chart';
interface Day {
date: string;
current: number;
previous: number;
}
// Thirty days of sales, as Figma 03 draws them (Oct 1–30, this period vs the previous one).
// Deterministic, so the visual lane's shots are stable.
const DAYS: Day[] = Array.from({ length: 30 }, (_, i) => ({
date: `2026-10-${String(i + 1).padStart(2, '0')}`,
current: Math.round(2200 + i * 150 + Math.sin(i / 2.2) * 620 + (i % 4) * 90),
previous: Math.round(2600 + i * 55 + Math.cos(i / 3) * 380),
}));
export function AreaChartRtlExample(): JSX.Element {
return (
<div dir="rtl">
<AreaChart
title="المبيعات"
data={DAYS}
x="date"
y="current"
compare="previous"
locale="ar-EG"
format={{ maximumFractionDigits: 0 }}
axisFormat={{ maximumFractionDigits: 0 }}
xDirection="rtl"
labels={{ current: 'هذه الفترة', previous: 'الفترة السابقة', delta: 'مقارنة بالسابقة' }}
/>
</div>
);
}
Props
Server component. Props: AreaChartProps<T>. Source: src/area-chart/area-chart.tsx.
| Name | Type | Default | Description |
|---|---|---|---|
axes | ChartAxes"frame""none" | 'frame' | From |
axisFormat | Intl.NumberFormatOptions | `format` in compact notation with at most one fraction digit ("$8K") | The y labels. From |
compare | Accessor<T, number | null | undefined> | – | The comparison series, drawn dashed in chart/neutral (decorative: the table carries it). |
curve | CurveFactory | curveMonotoneX (no overshoot below the baseline) | Any d3-shape curve factory. |
datarequired | readonly T[] | – | In x order: one datum per point or bar. From |
dateFormat | Intl.DateTimeFormatOptions | { month: 'short', day: 'numeric' } ("Oct 1") | ISO plain dates on the x axis. From |
empty | ReactNode | – | Replaces the default empty message. From |
error | ReactNode | – | Replaces the default error message, for example an InlineError with a retry action. From |
format | Intl.NumberFormatOptions | Intl.NumberFormat's own ({}) | Values in the tooltip and the data table. From |
interaction | ChartInteractionMode"nizivo""none" | 'nizivo' | From |
labels | Partial<AreaChartLabels> | – | |
legend | ReactNode | – |
|
locale | string | 'en-US' | The BCP 47 locale every number and date is formatted in, once, on the server (§16.4). From |
longDateFormat | Intl.DateTimeFormatOptions | { weekday: 'short', month: 'short', day: 'numeric' } | ISO plain dates in the tooltip and the data table. From |
pending | boolean | – | A refresh is in flight while the chart shows data (§16.5): From |
render | RenderProp<ChartFrameState> | – | From |
status | DataStatus"ready""loading""empty""error" | 'ready'; a ready chart with no table rows renders as `'empty'`. | From |
summary | ReactNode | – | One line under the title, for example "Daily sales, Oct 1–30, vs previous period". From |
tableView | ChartTableView"hidden""details" | 'hidden' | From |
titlerequired | ReactNode | – | The figure's caption and its accessible name. From |
titleVisibility | ChartTitleVisibility"visible""hidden" | 'visible' |
From |
xrequired | Accessor<T, string> | – | The x value: an ISO plain date ( From |
xDirection | ChartXDirection"ltr""rtl""auto" | 'ltr' | From |
xTicks | ChartXTicks | – | From |
yrequired | Accessor<T, number | null | undefined> | – | The value. A value that is not a finite number is a gap (no point, no bar). From |
yTicks | number | 4 | About how many y labels; the value domain is niced for this count. From |
- Also takes every
<figure>attribute exceptchildren,title.
render takes an element, or, in client code, a function of the props and this state (ChartFrameState):
| Name | Type | Default | Description |
|---|---|---|---|
interactionrequired | ChartInteractionMode"nizivo""none" | – | As passed: whether the child claims keyboard access to its points. |
pendingrequired | boolean | – | |
statusrequired | DataStatus"ready""loading""empty""error" | – | The status as rendered: |
x, y and compare are an Accessor: a key of the datum whose values have the right type
(x="date", which a Server Component can pass), or a (datum, index) => value function. format
and axisFormat are plain Intl.NumberFormatOptions, as @nizivo/react's Delta and Meter take
them; there are no presets.
xTicks (ChartXTicks): at most max x labels (AreaChart: 6), the last point always labelled.
When every is not given, a daily date series rounds the step up to whole weeks (Figma 03's Oct 1,
8, 15, 22 and the forced 30).
| Name | Type | Default | Description |
|---|---|---|---|
every | number | – | Data points (or bars) between labels; the last one always has a label. Derived from |
max | number | – | At most this many labels, the first and last included. AreaChart: 6, BarChart: 8. |
The props marked as from CartesianChartOptions are the ones AreaChart and
BarChart share, with the same names and types (one API shape across the
charts, M40). The defaults are the same too, except xTicks.max: 6 here, 8 for BarChart.
labels takes Partial<AreaChartLabels>, which extends ChartFrameLabels (its members are under
Other exports). The English defaults, in areaChartLabels, on top of
ChartFrame's:
| Key | Default |
|---|---|
x | Date |
category | Category |
current | This period |
previous | Previous |
delta | vs previous |
missing | No value |
interaction | interactive chart |
hint | Arrow keys move between points; Home and End go to the first and last |
points | Chart points |
Other exports
AreaChartLabelstypeimport type { AreaChartLabels } from '@nizivo/charts/area-chart'AreaChart's strings (§16.4), with ChartFrame's. English defaults in
areaChartLabels.Name Type Default Description categoryrequiredstring– The data table's first column header when x holds labels (BarChart's
category).currentrequiredstring– The series' name in the legend, the tooltip and the table.
deltarequiredstring– After the tooltip's change, for example "+28.0% vs previous".
hintrequiredstring– The interactive layer's keyboard instructions.
interactionrequiredstring– The interactive layer's role, as assistive technology names it.
missingrequiredstring– A value the series does not have at that point (BarChart's
missingtoo).pointsrequiredstring– The interactive layer's name when
titleis not a string.previousrequiredstring– The comparison's name.
xrequiredstring– The data table's first column header when every x is an ISO plain date.
AreaChartPropstypeimport type { AreaChartProps } from '@nizivo/charts/area-chart'AreaChart's props: the shared cartesian options (
_core/api.ts), its own, and ChartFrame's, the<figure>'s attributes included.The props of
AreaChart, listed above.areaChartLabelsconstantimport { areaChartLabels } from '@nizivo/charts/area-chart'const areaChartLabels: AreaChartLabels
Data attributes and slots
Inside the ChartFrame root, which carries
nz-area-chart:
| Element | Attributes |
|---|---|
svg.nz-chart-svg | viewBox="0 0 100 100", preserveAspectRatio="none", aria-hidden; coordinates rounded to 2 decimals |
line.nz-chart-grid, line.nz-chart-baseline | One grid line per tick other than 0; the baseline at 0 |
path.nz-chart-area, path.nz-chart-line | data-series="current", or "previous" for the dashed comparison |
path.nz-area-chart-halo, .nz-area-chart-dot | The last value's dot |
div.nz-chart-interaction | The island's layer: role="application", tabindex="0", aria-label, aria-roledescription, aria-describedby |
CSS hooks
| Hook | Default | Read as |
|---|---|---|
--nz-area-chart-halo | var(--nz-surface, var(--nz-bg-surface)) |
|
Layers: nz.components. Classes: .nz-area-chart-dot, .nz-area-chart-halo. Runtime variables: --nz-surface.
Tokens this stylesheet reads (2)
--nz-bg-surface, --nz-chart-primary
--nz-area-chart-halo is the ring around the end dot: the surface behind the chart. When the hook is unset, the ring takes the shared --nz-surface that @nizivo/react's
Card declares for its children (KpiTile and TrendCard are Cards, so a
tinted tile's halo is its own surface), else --nz-bg-surface. Charts read --nz-surface only if
it is there: without @nizivo/react on the page it is unset and the halo is --nz-bg-surface, and
@nizivo/charts does not depend on @nizivo/react (M42). The aspect ratio is ChartFrame's --nz-chart-frame-aspect (18 / 7).
Accessibility
- The picture is
aria-hidden; the data table (one row per point, every series in a column) is the accessible alternative. The comparison line is decorative and its values are in the table. - With the island, the plot is one Tab stop: a
role="application"layer named by the title, with thelabels.interactionrole description and thelabels.hintdescription, both rendered on the server.applicationis the role that lets a screen reader pass the arrow keys through; it stays until the manual screen-reader pass (M40). - One polite live region (
aria-live="polite",aria-atomic="true"), empty in the server HTML, speaks the point a key move reaches: the date, then each series' name and value, joined with the separatorsIntl.ListFormatwrites inlocaleon the server. Hiding the card (Escape, the pointer leaving, leaving the layer) empties it, so the next key that shows the card speaks the active point again. A key that does not move the point (End at the last point) says nothing, as a slider at its end does. A pointer shows the point and says nothing (Figma 03). - The tooltip card is
aria-hidden: it repeats what the live region and the table say. - Against WCAG 1.4.13 (Content on Hover or Focus), the card is dismissable: Escape hides it
wherever focus is, a card the pointer opened included (Escape on the focused plot hides only the
card, so an enclosing dialog stays open). It is persistent: no timeout. It never hides while the
pointer is over the plot or the card, but it takes no pointer events, so it follows the point
under the pointer and cannot be held on one point: not "hoverable" in 1.4.13's sense.
chart-interaction.spec.tsxchecks this in Chromium, WebKit and Firefox. - Showing a point moves nothing in the layout, and moving it adds no layout shift: the crosshair
and the dots move by
translate(chart-interaction.spec.tsxsweeps a pointer across the plot). - Right to left: see Right to left for what a page sees before and after the island hydrates.
Keyboard
| Keys | Action |
|---|---|
| Tab | Focuses the layer. A keyboard focus shows and speaks the active point, the last point at first. |
| ArrowRight / ArrowLeft | The next or previous point on screen; on a mirrored plot (xDirection="rtl", or "auto" on a right-to-left page) ArrowRight goes back in time. |
| Home / End | The first or last point. |
| Escape | Hides the card, wherever focus is; the point stays active. |
Source: chart-interaction.client.tsx in packages/charts/src/_island, checked in Chromium, WebKit and
Firefox by chart-interaction.spec.tsx in packages/charts/test/browser. Touch: a tap shows the point
and keeps the card after the finger lifts (synthetic pointer events only; real touch hardware is
not tested).
Figma
Area Chart, 7275:13336: State=Default 7275:13337 and State=Hover 7275:13358, 720 × 280.
"Time series, 1 axis. Hover: crosshair + ringed dots + Chart Tooltip (Series=2)." The hover
variant places the duplicate tooltip set 747:287; code treats 7275:13303 as the source.
Figma's reveal path-trims the line and fades the area in after 120 ms; code reveals both by
clip-path, because pathLength with non-scaling strokes is unverified. Notes:
docs/figma/03-data-viz.md §4.4.
ChartFrame
The <figure> every chart renders in, around any renderer, Nizivo's or a third party's. It owns the caption, the legend slot, the HTML tick labels, the server-rendered data table and the loading, empty and error statuses.
BarChart
Counts per period, drawn on the server. Bars cap at 22 px, round only at the data end and sit under a value axis rounded out to whole ticks; one keyboard stop steps through the columns and shows each bar's tooltip card.