API
Callout
A bordered box for notes and status messages, set apart from the surrounding text.
Installation
pnpm dlx zazz-ui add calloutnpx zazz-ui add calloutyarn dlx zazz-ui add calloutbunx zazz-ui add calloutRun zazz-ui init first if the project has no zazz/ folder yet.
Examples
Aside
A quieter surface for tips and context that readers can skip.
Scheduled maintenance
The dashboard is read-only on Saturday from 2 to 4 a.m. UTC.
Payment received
Your invoice is paid, and a receipt is on its way to your inbox.
Your trial ends in 3 days
Add a payment method to keep your projects running.
Deleting a workspace can't be undone
Its projects, files, and members are removed for good.
<div
style="
--display: grid;
--gap: 4;
"
>
<aside data-ui="callout" aria-labelledby="callout-note">
<p
id="callout-note"
data-ui="text-sm"
style="
--display: flex;
--items: center;
--gap: 2;
--font-weight: strong;
"
>
<svg
style="
--shrink: 0;
--size: 4;
"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 20 20"
fill="currentColor"
aria-hidden="true"
>
<path
fill-rule="evenodd"
d="M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-7-4a1 1 0 11-2 0 1 1 0 012 0zM9 9a.75.75 0 000 1.5h.253a.25.25 0 01.244.304l-.459 2.066A1.75 1.75 0 0010.747 15H11a.75.75 0 000-1.5h-.253a.25.25 0 01-.244-.304l.459-2.066A1.75 1.75 0 009.253 9H9z"
clip-rule="evenodd"
/>
</svg>
Note
</p>
<p data-ui="text-sm">Callouts set supporting information apart from the text around it.</p>
</aside>
<div data-ui="callout" data-callout-variant="muted">
<p
data-ui="text-sm"
style="
--display: flex;
--items: center;
--gap: 2;
--font-weight: strong;
"
>
<svg
style="
--shrink: 0;
--size: 4;
"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 20 20"
fill="currentColor"
aria-hidden="true"
>
<path
fill-rule="evenodd"
d="M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-7-4a1 1 0 11-2 0 1 1 0 012 0zM9 9a.75.75 0 000 1.5h.253a.25.25 0 01.244.304l-.459 2.066A1.75 1.75 0 0010.747 15H11a.75.75 0 000-1.5h-.253a.25.25 0 01-.244-.304l.459-2.066A1.75 1.75 0 009.253 9H9z"
clip-rule="evenodd"
/>
</svg>
Aside
</p>
<p data-ui="text-sm">A quieter surface for tips and context that readers can skip.</p>
</div>
<div data-ui="callout" data-callout-variant="info">
<p
data-ui="text-sm"
style="
--display: flex;
--items: center;
--gap: 2;
--font-weight: strong;
"
>
<svg
style="
--shrink: 0;
--size: 4;
"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 20 20"
fill="currentColor"
aria-hidden="true"
>
<path
fill-rule="evenodd"
d="M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-7-4a1 1 0 11-2 0 1 1 0 012 0zM9 9a.75.75 0 000 1.5h.253a.25.25 0 01.244.304l-.459 2.066A1.75 1.75 0 0010.747 15H11a.75.75 0 000-1.5h-.253a.25.25 0 01-.244-.304l.459-2.066A1.75 1.75 0 009.253 9H9z"
clip-rule="evenodd"
/>
</svg>
Scheduled maintenance
</p>
<p data-ui="text-sm">The dashboard is read-only on Saturday from 2 to 4 a.m. UTC.</p>
</div>
<div data-ui="callout" data-callout-variant="success">
<p
data-ui="text-sm"
style="
--display: flex;
--items: center;
--gap: 2;
--font-weight: strong;
"
>
<svg
style="
--shrink: 0;
--size: 4;
"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 20 20"
fill="currentColor"
aria-hidden="true"
>
<path
fill-rule="evenodd"
d="M10 18a8 8 0 100-16 8 8 0 000 16zm3.857-9.809a.75.75 0 00-1.214-.882l-3.483 4.79-1.88-1.88a.75.75 0 10-1.06 1.061l2.5 2.5a.75.75 0 001.137-.089l4-5.5z"
clip-rule="evenodd"
/>
</svg>
Payment received
</p>
<p data-ui="text-sm">Your invoice is paid, and a receipt is on its way to your inbox.</p>
</div>
<div data-ui="callout" data-callout-variant="warning">
<p
data-ui="text-sm"
style="
--display: flex;
--items: center;
--gap: 2;
--font-weight: strong;
"
>
<svg
style="
--shrink: 0;
--size: 4;
"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
fill="currentColor"
aria-hidden="true"
>
<path
fill-rule="evenodd"
d="M9.401 3.003c1.155-2 4.043-2 5.197 0l7.355 12.748c1.154 2-.29 4.5-2.599 4.5H4.645c-2.309 0-3.752-2.5-2.598-4.5L9.4 3.003zM12 8.25a.75.75 0 01.75.75v3.75a.75.75 0 01-1.5 0V9a.75.75 0 01.75-.75zm0 8.25a.75.75 0 100-1.5.75.75 0 000 1.5z"
clip-rule="evenodd"
/>
</svg>
Your trial ends in 3 days
</p>
<p data-ui="text-sm">Add a payment method to keep your projects running.</p>
</div>
<div data-ui="callout" data-callout-variant="destructive">
<p
data-ui="text-sm"
style="
--display: flex;
--items: center;
--gap: 2;
--font-weight: strong;
"
>
<svg
style="
--shrink: 0;
--size: 4;
"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 20 20"
fill="currentColor"
aria-hidden="true"
>
<path
fill-rule="evenodd"
d="M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-8-5a.75.75 0 01.75.75v4.5a.75.75 0 01-1.5 0v-4.5A.75.75 0 0110 5zm0 10a1 1 0 100-2 1 1 0 000 2z"
clip-rule="evenodd"
/>
</svg>
Deleting a workspace can't be undone
</p>
<p data-ui="text-sm">Its projects, files, and members are removed for good.</p>
</div>
</div>/**
* callout.css — Callout ([data-ui~="callout"])
*
* @layer variables, components
* @requires _layers.css, _variables.css, _properties.css (--_*-resolved)
* @uses oklch(from …): status tints
* @tokens --ui-callout-* (@layer variables; named after the utilities they back)
* @see badge.css (status tint and border formulas; the test keeps them in sync)
* @presets data-callout-variant="muted" | "info" | "success" | "warning" | "destructive"
*
* A callout is an aside or alert: a padded grid with a gap, a border, and a
* radius. The default matches an outline card and muted a muted card. Info,
* success, and warning take the matching badge's tint and border, with the
* role mixed toward --color-foreground for text; destructive is the badge's
* solid fill.
* Every variant keeps the 1px border (muted makes it transparent), so every
* variant is the same size.
* Its parts are plain elements laid out with utilities. Use <aside> for a
* side note, or a <div> with role="status" or role="alert" for a message
* that follows something the user did.
* Every utility-backed declaration reads one chain, highest first:
* var(--_<utility>-resolved, var(--_callout-<utility>, var(--ui-callout-<utility>)))
*/
@layer variables {
:root {
--ui-callout-bg: var(--color-card);
--ui-callout-text: var(--color-card-foreground);
--ui-callout-rounded: var(--radius-md);
--ui-callout-shadow: none;
--ui-callout-border-width: 1px;
--ui-callout-border-style: solid;
--ui-callout-border-color: var(--color-border);
/* dual-mode: a scale number or a length */
--ui-callout-gap: var(--space-xs);
--ui-callout-p: var(--space-sm);
}
}
/* Variant privates: non-inheriting so a variant never cascades into a nested callout. */
@property --_callout-bg {
syntax: "*";
inherits: false;
}
@property --_callout-text {
syntax: "*";
inherits: false;
}
@property --_callout-border-color {
syntax: "*";
inherits: false;
}
@layer ui.components {
:where([data-ui~="callout"]) {
display: grid;
--_gap-len: var(--_gap-resolved, var(--ui-callout-gap));
--_gap-num: var(--_gap-resolved, var(--ui-callout-gap));
gap: calc(var(--_gap-len) + var(--_gap-num) * var(--spacing));
--_p-len: var(--_p-resolved, var(--ui-callout-p));
--_p-num: var(--_p-resolved, var(--ui-callout-p));
padding: calc(var(--_p-len) + var(--_p-num) * var(--spacing));
color: var(--_text-resolved, var(--_callout-text, var(--ui-callout-text)));
background-color: var(--_bg-resolved, var(--_callout-bg, var(--ui-callout-bg)));
border-width: var(--_border-width-resolved, var(--ui-callout-border-width));
border-style: var(--_border-style-resolved, var(--ui-callout-border-style));
border-color: var(
--_border-color-resolved,
var(--_callout-border-color, var(--ui-callout-border-color))
);
border-radius: var(--_rounded-resolved, var(--ui-callout-rounded));
box-shadow: var(--_shadow-resolved, var(--ui-callout-shadow));
}
/* ===========================================================================
CALLOUT VARIANTS — data-callout-variant writes the privates
=========================================================================== */
:where([data-ui~="callout"][data-callout-variant="muted"]) {
--_callout-bg: var(--color-muted);
--_callout-text: var(--color-foreground);
--_callout-border-color: transparent;
}
/* status variants: the soft status colors buttons and badges use (see
button.css), plus a faint status border that outlines the block */
:where([data-ui~="callout"][data-callout-variant="info"]) {
--_callout-bg: light-dark(
oklch(from var(--color-info) l c h / 0.1),
oklch(from var(--color-info) l c h / 0.2)
);
--_callout-text: light-dark(
oklch(from var(--color-info) min(l, 0.45) c h),
oklch(from var(--color-info) max(l, 0.82) c h)
);
--_callout-border-color: oklch(from var(--color-info) l c h / 0.2);
}
:where([data-ui~="callout"][data-callout-variant="success"]) {
--_callout-bg: light-dark(
oklch(from var(--color-success) l c h / 0.1),
oklch(from var(--color-success) l c h / 0.2)
);
--_callout-text: light-dark(
oklch(from var(--color-success) min(l, 0.45) c h),
oklch(from var(--color-success) max(l, 0.82) c h)
);
--_callout-border-color: oklch(from var(--color-success) l c h / 0.2);
}
:where([data-ui~="callout"][data-callout-variant="warning"]) {
--_callout-bg: light-dark(
oklch(from var(--color-warning) l c h / 0.1),
oklch(from var(--color-warning) l c h / 0.2)
);
--_callout-text: light-dark(
oklch(from var(--color-warning) min(l, 0.45) c h),
oklch(from var(--color-warning) max(l, 0.82) c h)
);
--_callout-border-color: oklch(from var(--color-warning) l c h / 0.2);
}
:where([data-ui~="callout"][data-callout-variant="destructive"]) {
--_callout-bg: light-dark(
oklch(from var(--color-destructive) l c h / 0.1),
oklch(from var(--color-destructive) l c h / 0.2)
);
--_callout-text: light-dark(
oklch(from var(--color-destructive) min(l, 0.45) c h),
oklch(from var(--color-destructive) max(l, 0.82) c h)
);
--_callout-border-color: oklch(from var(--color-destructive) l c h / 0.2);
}
}Attributes
| Attribute | Kind | Values | Notes |
|---|---|---|---|
data-ui="callout" | Identity | free value | Identity token in data-ui. |
data-callout-variant | Preset | destructive info muted success warning | Preset: a named bundle of values. |
Hooks
Set a hook on :root, on a subtree, or inline on one element. A state hook (--…--hover) themes that state only; the primitive keeps its other states.
| Hook | Default | State |
|---|---|---|
--ui-callout-bg | var(--color-card) | — |
--ui-callout-border-color | var(--color-border) | — |
--ui-callout-border-style | solid | — |
--ui-callout-border-width | 1px | — |
--ui-callout-gap | var(--space-xs) | — |
--ui-callout-p | var(--space-sm) | — |
--ui-callout-rounded | var(--radius-md) | — |
--ui-callout-shadow | none | — |
--ui-callout-text | var(--color-card-foreground) | — |