Skip to content
KaufmannCommerce UI
Foundations · v0.1⌘ K

Kaufmann Commerce UI / Promise family

Offer Card

The public sellable promise: editorial meaning, current price and projected availability, without collapsing the Offer into its stock-bearing Items.

Editorial offers

A quieter market-facing alternative to the general Product Card, designed for warm storefront compositions.

Live specimen

Row density

The same card lying down, for dense lists and search results. The media becomes a fixed thumb so rows align on a common left edge; the description clamps to two lines rather than being dropped.

Live specimen

Edge states

Unavailable and changed-price, side by side with an ordinary card. Both are designed states, not error styling.

Live specimen

Two prices that mean different things

compareAtPrice is a standing comparison — a recommended or former retail price — and renders struck through beside the current one. previousPrice is something else entirely: what this Offer projected before the projection you are looking at now. It exists so a price cannot be silently swapped under someone who already saw the old one.

They are deliberately styled apart. A changed price is stated plainly in the metadata voice — Changed from €15.00 — and never borrows the discount's presentation, because a change is not a saving and the card may not imply one.

Availability is projectedA sold-out card disables its action and desaturates its media. That reflects the projection this page was built with — it is not a live reading of stock, and nothing here is reserved.

Offer is not Item

The component accepts an Offer projection and keeps optional items as stable references. It never claims that the public card itself owns stock. A bundle can therefore remain one customer-facing promise while resolving several operational Items later.

Astro
---
import { OfferCard } from "@kaufmann/ui";
---

<OfferCard offer={offer} />                      <!-- editorial (default) -->
<OfferCard offer={offer} density="compact" />    <!-- no description -->
<OfferCard offer={offer} density="row" />        <!-- lying down, for lists -->