Defined sequence of states/actions.
Received
Order confirmed and queued
Completed Current UpcomingPacking
Items picked and boxed
Completed Current UpcomingShipped
Handed to courier
Completed Current UpcomingDelivered
Received by customer
Completed Current Upcoming<div class="workflow workflow--horizontal" data-current="packing" style="--accent:#A8E6C1;">
<h3 class="workflow__title">Order fulfilment</h3>
<ol class="workflow__stages">
<li class="workflow__stage workflow__stage--received">
<span class="workflow__dot" aria-hidden="true"></span>
<div class="workflow__stage-body">
<p class="workflow__stage-name">Received</p>
<p class="workflow__stage-desc">Order confirmed and queued</p>
<span class="workflow__badge workflow__badge--completed">Completed</span>
<span class="workflow__badge workflow__badge--current" aria-current="step">Current</span>
<span class="workflow__badge workflow__badge--upcoming">Upcoming</span>
</div>
</li>
<li class="workflow__stage workflow__stage--packing">
<span class="workflow__dot" aria-hidden="true"></span>
<div class="workflow__stage-body">
<p class="workflow__stage-name">Packing</p>
<p class="workflow__stage-desc">Items picked and boxed</p>
<span class="workflow__badge workflow__badge--completed">Completed</span>
<span class="workflow__badge workflow__badge--current" aria-current="step">Current</span>
<span class="workflow__badge workflow__badge--upcoming">Upcoming</span>
</div>
</li>
<li class="workflow__stage workflow__stage--shipped">
<span class="workflow__dot" aria-hidden="true"></span>
<div class="workflow__stage-body">
<p class="workflow__stage-name">Shipped</p>
<p class="workflow__stage-desc">Handed to courier</p>
<span class="workflow__badge workflow__badge--completed">Completed</span>
<span class="workflow__badge workflow__badge--current" aria-current="step">Current</span>
<span class="workflow__badge workflow__badge--upcoming">Upcoming</span>
</div>
</li>
<li class="workflow__stage workflow__stage--delivered">
<span class="workflow__dot" aria-hidden="true"></span>
<div class="workflow__stage-body">
<p class="workflow__stage-name">Delivered</p>
<p class="workflow__stage-desc">Received by customer</p>
<span class="workflow__badge workflow__badge--completed">Completed</span>
<span class="workflow__badge workflow__badge--current" aria-current="step">Current</span>
<span class="workflow__badge workflow__badge--upcoming">Upcoming</span>
</div>
</li>
</ol>
</div>
<style>
.workflow { width: 640px; max-width: 100%; padding: 20px; background: #FAF7F2; color: #241430; font: 14px/1.4 system-ui, sans-serif; border-radius: 14px; box-shadow: 0 8px 24px rgba(36,20,48,.12); box-sizing: border-box; }
.workflow__title { margin: 0 0 16px; font-size: 16px; }
.workflow__stages { list-style: none; margin: 0; padding: 0; display: flex; gap: 18px; }
.workflow--vertical .workflow__stages { flex-direction: column; gap: 14px; }
.workflow__stage { display: flex; gap: 10px; flex: 1; position: relative; }
.workflow--vertical .workflow__stage { flex: none; }
.workflow__dot { width: 10px; height: 10px; border-radius: 50%; background: #24143022; margin-top: 4px; flex-shrink: 0; }
.workflow__stage-name { margin: 0; font-weight: 700; font-size: 13.5px; }
.workflow__stage-desc { margin: 2px 0 6px; font-size: 12px; color: #241430b3; }
.workflow__badge { display: none; font-size: 11px; font-weight: 700; padding: 1px 8px; border-radius: 999px; text-transform: uppercase; letter-spacing: .03em; }
.workflow__badge--completed { display: inline-flex; background: #24143014; color: #241430b3; }
.workflow[data-current="received"] .workflow__stage--received .workflow__dot,
.workflow[data-current="packing"] .workflow__stage--packing .workflow__dot,
.workflow[data-current="shipped"] .workflow__stage--shipped .workflow__dot,
.workflow[data-current="delivered"] .workflow__stage--delivered .workflow__dot { background: var(--accent); }
.workflow[data-current="received"] .workflow__stage--received .workflow__badge--completed,
.workflow[data-current="packing"] .workflow__stage--packing .workflow__badge--completed,
.workflow[data-current="shipped"] .workflow__stage--shipped .workflow__badge--completed,
.workflow[data-current="delivered"] .workflow__stage--delivered .workflow__badge--completed { display: none; }
.workflow[data-current="received"] .workflow__stage--received .workflow__badge--current,
.workflow[data-current="packing"] .workflow__stage--packing .workflow__badge--current,
.workflow[data-current="shipped"] .workflow__stage--shipped .workflow__badge--current,
.workflow[data-current="delivered"] .workflow__stage--delivered .workflow__badge--current { display: inline-flex; background: var(--accent); color: #17532F; }
.workflow[data-current="received"] .workflow__stage--received ~ .workflow__stage .workflow__badge--completed,
.workflow[data-current="packing"] .workflow__stage--packing ~ .workflow__stage .workflow__badge--completed,
.workflow[data-current="shipped"] .workflow__stage--shipped ~ .workflow__stage .workflow__badge--completed { display: none; }
.workflow[data-current="received"] .workflow__stage--received ~ .workflow__stage .workflow__badge--upcoming,
.workflow[data-current="packing"] .workflow__stage--packing ~ .workflow__stage .workflow__badge--upcoming,
.workflow[data-current="shipped"] .workflow__stage--shipped ~ .workflow__stage .workflow__badge--upcoming { display: inline-flex; color: #241430b3; }
.workflow[data-current="received"] .workflow__stage--received ~ .workflow__stage .workflow__dot,
.workflow[data-current="packing"] .workflow__stage--packing ~ .workflow__stage .workflow__dot,
.workflow[data-current="shipped"] .workflow__stage--shipped ~ .workflow__stage .workflow__dot { background: #24143022; }
</style><div class="workflow-tw workflow-tw--horizontal w-[640px] max-w-full p-5 bg-[#FAF7F2] text-[#241430] font-sans text-sm rounded-2xl shadow-lg box-border" data-current="packing" style="--accent:#A8E6C1;">
<h3 class="m-0 mb-4 text-base">Order fulfilment</h3>
<ol class="workflow-tw__stages list-none m-0 p-0 flex gap-4">
<li class="workflow-tw__stage workflow-tw__stage--received flex gap-2.5 relative flex-1">
<span class="workflow-tw__dot w-2.5 h-2.5 rounded-full mt-1 flex-shrink-0" style="background:#24143022;"></span>
<div>
<p class="m-0 font-bold text-[13.5px]">Received</p>
<p class="mt-0.5 mb-1.5 text-xs text-[#241430]/70">Order confirmed and queued</p>
<span class="workflow-tw__badge workflow-tw__badge--completed inline-flex text-[11px] font-bold px-2 py-px rounded-full uppercase tracking-wide bg-[#24143014] text-[#241430]/70">Completed</span>
<span class="workflow-tw__badge workflow-tw__badge--current text-[11px] font-bold px-2 py-px rounded-full uppercase tracking-wide" aria-current="step">Current</span>
<span class="workflow-tw__badge workflow-tw__badge--upcoming text-[11px] font-bold px-2 py-px rounded-full uppercase tracking-wide">Upcoming</span>
</div>
</li>
<li class="workflow-tw__stage workflow-tw__stage--packing flex gap-2.5 relative flex-1">
<span class="workflow-tw__dot w-2.5 h-2.5 rounded-full mt-1 flex-shrink-0" style="background:#24143022;"></span>
<div>
<p class="m-0 font-bold text-[13.5px]">Packing</p>
<p class="mt-0.5 mb-1.5 text-xs text-[#241430]/70">Items picked and boxed</p>
<span class="workflow-tw__badge workflow-tw__badge--completed inline-flex text-[11px] font-bold px-2 py-px rounded-full uppercase tracking-wide bg-[#24143014] text-[#241430]/70">Completed</span>
<span class="workflow-tw__badge workflow-tw__badge--current text-[11px] font-bold px-2 py-px rounded-full uppercase tracking-wide" aria-current="step">Current</span>
<span class="workflow-tw__badge workflow-tw__badge--upcoming text-[11px] font-bold px-2 py-px rounded-full uppercase tracking-wide">Upcoming</span>
</div>
</li>
<li class="workflow-tw__stage workflow-tw__stage--shipped flex gap-2.5 relative flex-1">
<span class="workflow-tw__dot w-2.5 h-2.5 rounded-full mt-1 flex-shrink-0" style="background:#24143022;"></span>
<div>
<p class="m-0 font-bold text-[13.5px]">Shipped</p>
<p class="mt-0.5 mb-1.5 text-xs text-[#241430]/70">Handed to courier</p>
<span class="workflow-tw__badge workflow-tw__badge--completed inline-flex text-[11px] font-bold px-2 py-px rounded-full uppercase tracking-wide bg-[#24143014] text-[#241430]/70">Completed</span>
<span class="workflow-tw__badge workflow-tw__badge--current text-[11px] font-bold px-2 py-px rounded-full uppercase tracking-wide" aria-current="step">Current</span>
<span class="workflow-tw__badge workflow-tw__badge--upcoming text-[11px] font-bold px-2 py-px rounded-full uppercase tracking-wide">Upcoming</span>
</div>
</li>
<li class="workflow-tw__stage workflow-tw__stage--delivered flex gap-2.5 relative flex-1">
<span class="workflow-tw__dot w-2.5 h-2.5 rounded-full mt-1 flex-shrink-0" style="background:#24143022;"></span>
<div>
<p class="m-0 font-bold text-[13.5px]">Delivered</p>
<p class="mt-0.5 mb-1.5 text-xs text-[#241430]/70">Received by customer</p>
<span class="workflow-tw__badge workflow-tw__badge--completed inline-flex text-[11px] font-bold px-2 py-px rounded-full uppercase tracking-wide bg-[#24143014] text-[#241430]/70">Completed</span>
<span class="workflow-tw__badge workflow-tw__badge--current text-[11px] font-bold px-2 py-px rounded-full uppercase tracking-wide" aria-current="step">Current</span>
<span class="workflow-tw__badge workflow-tw__badge--upcoming text-[11px] font-bold px-2 py-px rounded-full uppercase tracking-wide">Upcoming</span>
</div>
</li>
</ol>
</div>
<style>
.workflow-tw--vertical .workflow-tw__stages { flex-direction: column; }
.workflow-tw--vertical .workflow-tw__stage { flex: none; }
.workflow-tw__badge--current, .workflow-tw__badge--upcoming { display: none; }
.workflow-tw[data-current="received"] .workflow-tw__stage--received .workflow-tw__dot,
.workflow-tw[data-current="packing"] .workflow-tw__stage--packing .workflow-tw__dot,
.workflow-tw[data-current="shipped"] .workflow-tw__stage--shipped .workflow-tw__dot,
.workflow-tw[data-current="delivered"] .workflow-tw__stage--delivered .workflow-tw__dot { background: var(--accent) !important; }
.workflow-tw[data-current="received"] .workflow-tw__stage--received .workflow-tw__badge--completed,
.workflow-tw[data-current="packing"] .workflow-tw__stage--packing .workflow-tw__badge--completed,
.workflow-tw[data-current="shipped"] .workflow-tw__stage--shipped .workflow-tw__badge--completed,
.workflow-tw[data-current="delivered"] .workflow-tw__stage--delivered .workflow-tw__badge--completed { display: none; }
.workflow-tw[data-current="received"] .workflow-tw__stage--received .workflow-tw__badge--current,
.workflow-tw[data-current="packing"] .workflow-tw__stage--packing .workflow-tw__badge--current,
.workflow-tw[data-current="shipped"] .workflow-tw__stage--shipped .workflow-tw__badge--current,
.workflow-tw[data-current="delivered"] .workflow-tw__stage--delivered .workflow-tw__badge--current { display: inline-flex; background: var(--accent); color: #17532F; }
.workflow-tw[data-current="received"] .workflow-tw__stage--received ~ .workflow-tw__stage .workflow-tw__badge--completed,
.workflow-tw[data-current="packing"] .workflow-tw__stage--packing ~ .workflow-tw__stage .workflow-tw__badge--completed,
.workflow-tw[data-current="shipped"] .workflow-tw__stage--shipped ~ .workflow-tw__stage .workflow-tw__badge--completed { display: none; }
.workflow-tw[data-current="received"] .workflow-tw__stage--received ~ .workflow-tw__stage .workflow-tw__badge--upcoming,
.workflow-tw[data-current="packing"] .workflow-tw__stage--packing ~ .workflow-tw__stage .workflow-tw__badge--upcoming,
.workflow-tw[data-current="shipped"] .workflow-tw__stage--shipped ~ .workflow-tw__stage .workflow-tw__badge--upcoming { display: inline-flex; color: #241430b3; }
</style>export function Workflow({
title = "Order fulfilment",
current = "packing",
orientation = "horizontal",
accent = "#A8E6C1",
showDescription = true,
}) {
const stages = [
{ key: "received", name: "Received", desc: "Order confirmed and queued" },
{ key: "packing", name: "Packing", desc: "Items picked and boxed" },
{ key: "shipped", name: "Shipped", desc: "Handed to courier" },
{ key: "delivered", name: "Delivered", desc: "Received by customer" },
];
const currentIndex = stages.findIndex((s) => s.key === current);
return (
<div style={{ width: 640, maxWidth: "100%", padding: 20, background: "#FAF7F2", color: "#241430",
fontFamily: "system-ui, sans-serif", fontSize: 14, borderRadius: 14, boxShadow: "0 8px 24px rgba(36,20,48,.12)",
boxSizing: "border-box" }}>
<h3 style={{ margin: "0 0 16px", fontSize: 16 }}>{title}</h3>
<ol style={{ listStyle: "none", margin: 0, padding: 0, display: "flex",
flexDirection: orientation === "vertical" ? "column" : "row", gap: orientation === "vertical" ? 14 : 18 }}>
{stages.map((stage, i) => {
const status = i < currentIndex ? "completed" : i === currentIndex ? "current" : "upcoming";
return (
<li key={stage.key} style={{ display: "flex", gap: 10, flex: orientation === "vertical" ? "none" : 1 }}>
<span aria-hidden="true" style={{ width: 10, height: 10, borderRadius: "50%", marginTop: 4, flexShrink: 0,
background: status === "upcoming" ? "#24143022" : accent }} />
<div>
<p style={{ margin: 0, fontWeight: 700, fontSize: 13.5 }}>{stage.name}</p>
{showDescription && <p style={{ margin: "2px 0 6px", fontSize: 12, color: "#241430b3" }}>{stage.desc}</p>}
<span aria-current={status === "current" ? "step" : undefined} style={{ fontSize: 11, fontWeight: 700,
padding: "1px 8px", borderRadius: 999, textTransform: "uppercase", letterSpacing: "0.03em",
background: status === "current" ? accent : status === "completed" ? "#24143014" : "transparent",
color: status === "current" ? "#17532F" : "#241430b3" }}>
{status}
</span>
</div>
</li>
);
})}
</ol>
</div>
);
}