Workflow Step

Individual step in a process.

Current step 2

Verify identity

current

html

<div class="workflow-step workflow-step--horizontal" data-status="current" style="--accent:#F5C2E0;">
  <span class="workflow-step__badge">
    <span class="workflow-step__current-flag" aria-current="step">Current step</span>
    <span class="workflow-step__number">2</span>
    <svg class="workflow-step__check" viewBox="0 0 20 20" aria-hidden="true"><path d="M4 10.5l3.5 3.5L16 5.5" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg>
  </span>
  <div class="workflow-step__body">
    <p class="workflow-step__name">Verify identity</p>
    <span class="workflow-step__status">current</span>
  </div>
</div>
<style>
.workflow-step { display: flex; align-items: center; gap: 12px; width: 300px; padding: 14px; background: #FAF7F2; color: #241430; font: 14px/1.4 system-ui, sans-serif; border-radius: 12px; box-shadow: 0 6px 18px rgba(36,20,48,.1); box-sizing: border-box; }
.workflow-step--vertical { flex-direction: column; align-items: flex-start; width: 200px; }
.workflow-step__badge { position: relative; width: 30px; height: 30px; border-radius: 50%; display: grid; place-items: center; font-weight: 700; font-size: 13px; flex-shrink: 0; background: #24143014; color: #241430b3; }
.workflow-step__current-flag { display: none; }
.workflow-step[data-status="current"] .workflow-step__current-flag { display: inline; position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0,0,0,0); white-space: nowrap; }
.workflow-step__check { width: 14px; height: 14px; display: none; }
.workflow-step[data-status="completed"] .workflow-step__badge { background: var(--accent); color: #7A1440; }
.workflow-step[data-status="completed"] .workflow-step__number { display: none; }
.workflow-step[data-status="completed"] .workflow-step__check { display: block; }
.workflow-step[data-status="current"] .workflow-step__badge { background: #241430; color: #FAF7F2; box-shadow: 0 0 0 3px var(--accent); }
.workflow-step[data-status="upcoming"] .workflow-step__badge { background: #24143014; color: #241430b3; }
.workflow-step__name { margin: 0; font-weight: 700; font-size: 13.5px; }
.workflow-step__status { display: inline-block; margin-top: 2px; font-size: 11.5px; font-weight: 700; text-transform: capitalize; color: #241430b3; }
</style>

tailwind

<div class="workflow-step-tw workflow-step-tw--horizontal flex items-center gap-3 w-[300px] p-3.5 bg-[#FAF7F2] text-[#241430] font-sans text-sm rounded-xl shadow box-border" data-status="current" style="--accent:#F5C2E0;">
  <span class="workflow-step-tw__badge relative w-[30px] h-[30px] rounded-full grid place-items-center font-bold text-[13px] flex-shrink-0 bg-[#24143014] text-[#241430]/70">
    <span class="workflow-step-tw__current-flag" aria-current="step">Current step</span>
    <span class="workflow-step-tw__number">2</span>
    <svg class="workflow-step-tw__check w-3.5 h-3.5" viewBox="0 0 20 20" aria-hidden="true"><path d="M4 10.5l3.5 3.5L16 5.5" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg>
  </span>
  <div>
    <p class="m-0 font-bold text-[13.5px]">Verify identity</p>
    <span class="inline-block mt-0.5 text-[11.5px] font-bold capitalize text-[#241430]/70">current</span>
  </div>
</div>
<style>
.workflow-step-tw--vertical { flex-direction: column; align-items: flex-start; width: 200px; }
.workflow-step-tw__current-flag { display: none; }
.workflow-step-tw[data-status="current"] .workflow-step-tw__current-flag { display: inline; position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0,0,0,0); white-space: nowrap; }
.workflow-step-tw__check { display: none; }
.workflow-step-tw[data-status="completed"] .workflow-step-tw__badge { background: var(--accent); color: #7A1440; }
.workflow-step-tw[data-status="completed"] .workflow-step-tw__number { display: none; }
.workflow-step-tw[data-status="completed"] .workflow-step-tw__check { display: block; }
.workflow-step-tw[data-status="current"] .workflow-step-tw__badge { background: #241430; color: #FAF7F2; box-shadow: 0 0 0 3px var(--accent); }
</style>

react

export function WorkflowStep({
  stepNumber = 2,
  name = "Verify identity",
  status = "current",
  orientation = "horizontal",
  accent = "#F5C2E0",
}) {
  const badgeStyle = {
    completed: { background: accent, color: "#7A1440" },
    current: { background: "#241430", color: "#FAF7F2", boxShadow: `0 0 0 3px ${accent}` },
    upcoming: { background: "#24143014", color: "#241430b3" },
  }[status] ?? {};
  const vertical = orientation === "vertical";
  return (
    <div style={{ display: "flex", flexDirection: vertical ? "column" : "row", alignItems: vertical ? "flex-start" : "center",
      gap: 12, width: vertical ? 200 : 300, padding: 14, background: "#FAF7F2", color: "#241430",
      fontFamily: "system-ui, sans-serif", fontSize: 14, borderRadius: 12, boxShadow: "0 6px 18px rgba(36,20,48,.1)",
      boxSizing: "border-box" }}>
      <span style={{ position: "relative", width: 30, height: 30, borderRadius: "50%", display: "grid",
        placeItems: "center", fontWeight: 700, fontSize: 13, flexShrink: 0, ...badgeStyle }}>
        {status === "current" && (
          <span aria-current="step" style={{ position: "absolute", width: 1, height: 1, overflow: "hidden",
            clip: "rect(0,0,0,0)", whiteSpace: "nowrap" }}>Current step</span>
        )}
        {status === "completed" ? (
          <svg width="14" height="14" viewBox="0 0 20 20" aria-hidden="true"><path d="M4 10.5l3.5 3.5L16 5.5" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" /></svg>
        ) : stepNumber}
      </span>
      <div>
        <p style={{ margin: 0, fontWeight: 700, fontSize: 13.5 }}>{name}</p>
        <span style={{ display: "inline-block", marginTop: 2, fontSize: 11.5, fontWeight: 700, textTransform: "capitalize", color: "#241430b3" }}>{status}</span>
      </div>
    </div>
  );
}