export type ProductMedia = { id: string; src: string; alt?: string; /** Small rendition (about 150px); used by the quick-add sheet, cart lines and gallery thumbnails. */ thumb?: string; /** Responsive candidates for `src`, e.g. "a-400.jpg 400w, a-800.jpg 800w"; the product card forwards it to its ``. */ srcSet?: string; /** Rendered width hint paired with `srcSet`, e.g. "(min-width: 768px) 25vw, 50vw". */ sizes?: string; type?: "image" | "video"; poster?: string; }; export type ProductBadgeTone = "accent" | "neutral" | "success" | "warning" | "danger" | "info" | "inverse"; export type ProductBadge = { label: string; tone?: ProductBadgeTone; }; export type OptionAxisType = "swatch" | "chip" | "image-tile" | "pack"; export type OptionValue = { id: string; label: string; /** Any CSS colour; product data, so it is the one place a literal colour is allowed. */ swatch?: string; image?: string; hint?: string; /** Quantity of the base unit this value contains, for per-unit pricing on pack axes. */ quantity?: number; }; export type OptionAxis = { id: string; label: string; type: OptionAxisType; values: OptionValue[]; guide?: { label: string; onClick: () => void; }; }; export type VariantSelection = Record; export type ProductVariant = { id: string; /** Axis id to option value id; a variant with every axis set is fully specified. */ options: VariantSelection; price: number; mrp?: number; /** Undefined means untracked and sellable; 0 means sold out. */ stock?: number; backorder?: boolean; sku?: string; mediaIds?: string[]; }; export type StockState = "in-stock" | "low-stock" | "out-of-stock" | "backorder"; export type PriceFormat = { currency?: string; locale?: string; };