Gate

Condition that must be met before progression.

Deploy gate: production release

Gate closed — resolve blocking conditions

html

<div class="gate gate--closed">
  <h3 class="gate__title">Deploy gate: production release</h3>
  <ul class="gate__conditions">
    <li class="gate__condition gate__condition--met">
      <span class="gate__cond-icon"><svg viewBox="0 0 16 16" width="16" height="16" fill="none" aria-hidden="true"><path d="M3 8.5l3 3 7-7" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg></span>
      <span>All tests passing — Met</span>
    </li>
    <li class="gate__condition">
      <span class="gate__cond-icon"><svg viewBox="0 0 16 16" width="16" height="16" fill="none" aria-hidden="true"><path d="M4 4l8 8M12 4l-8 8" stroke="currentColor" stroke-width="2" stroke-linecap="round"/></svg></span>
      <span>Security review approved — Not met</span>
    </li>
    <li class="gate__condition gate__condition--met">
      <span class="gate__cond-icon"><svg viewBox="0 0 16 16" width="16" height="16" fill="none" aria-hidden="true"><path d="M3 8.5l3 3 7-7" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg></span>
      <span>No open P1 incidents — Met</span>
    </li>
  </ul>
  <p class="gate__banner">Gate closed — resolve blocking conditions</p>
</div>
<style>
.gate { font: 15px/1.5 system-ui, sans-serif; max-width: 380px; padding: 20px; background: #FAF7F2; color: #241430; border-radius: 14px; border: 1.5px solid #24143020; }
.gate__title { margin: 0 0 12px; font-size: 16px; font-weight: 700; }
.gate__conditions { list-style: none; margin: 0 0 14px; padding: 0; display: flex; flex-direction: column; gap: 6px; }
.gate__condition { display: flex; align-items: center; gap: 8px; font-size: 14px; color: #b23b3b; }
.gate__condition--met { color: #2f8a52; }
.gate__cond-icon { display: inline-flex; }
.gate__banner { margin: 0; padding: 10px 12px; border-radius: 8px; font-weight: 600; font-size: 14px; }
.gate--closed .gate__banner { background: #b23b3b1a; color: #b23b3b; }
.gate--open .gate__banner { background: #2f8a521a; color: #2f8a52; }
</style>

tailwind

<div class="gate-tw font-sans max-w-[380px] p-5 bg-[#FAF7F2] text-[#241430] rounded-2xl border-[1.5px] border-[#24143020] gate-tw--closed">
  <h3 class="m-0 mb-3 text-base font-bold">Deploy gate: production release</h3>
  <ul class="list-none m-0 mb-3.5 p-0 flex flex-col gap-1.5">
    <li class="flex items-center gap-2 text-sm" style="color:#2f8a52">
      <span class="inline-flex"><svg viewBox="0 0 16 16" width="16" height="16" fill="none" aria-hidden="true"><path d="M3 8.5l3 3 7-7" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg></span>
      <span>All tests passing — Met</span>
    </li>
    <li class="flex items-center gap-2 text-sm" style="color:#b23b3b">
      <span class="inline-flex"><svg viewBox="0 0 16 16" width="16" height="16" fill="none" aria-hidden="true"><path d="M4 4l8 8M12 4l-8 8" stroke="currentColor" stroke-width="2" stroke-linecap="round"/></svg></span>
      <span>Security review approved — Not met</span>
    </li>
    <li class="flex items-center gap-2 text-sm text-[#2f8a52]">
      <span class="inline-flex"><svg viewBox="0 0 16 16" width="16" height="16" fill="none" aria-hidden="true"><path d="M3 8.5l3 3 7-7" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg></span>
      <span>No open P1 incidents — Met</span>
    </li>
  </ul>
  <p class="m-0 py-2.5 px-3 rounded-lg font-semibold text-sm">Gate closed — resolve blocking conditions</p>
</div>
<style>
.gate-tw--closed p { background: #b23b3b1a; color: #b23b3b; }
.gate-tw--open p { background: #2f8a521a; color: #2f8a52; }
</style>

react

export function Gate({
  gateTitle = "Deploy gate: production release",
  condition1 = "All tests passing",
  condition1Met = true,
  condition2 = "Security review approved",
  condition2Met = false,
  open = false,
}) {
  const rows = [
    { label: condition1, met: condition1Met },
    { label: condition2, met: condition2Met },
    { label: "No open P1 incidents", met: true },
  ];
  return (
    <div style={{ fontFamily: "system-ui, sans-serif", maxWidth: 380, padding: 20, background: "#FAF7F2",
      color: "#241430", borderRadius: 14, border: "1.5px solid #24143020" }}>
      <h3 style={{ margin: "0 0 12px", fontSize: 16, fontWeight: 700 }}>{gateTitle}</h3>
      <ul style={{ listStyle: "none", margin: "0 0 14px", padding: 0, display: "flex", flexDirection: "column", gap: 6 }}>
        {rows.map((r, i) => (
          <li key={i} style={{ display: "flex", alignItems: "center", gap: 8, fontSize: 14, color: r.met ? "#2f8a52" : "#b23b3b" }}>
            <span style={{ display: "inline-flex" }} dangerouslySetInnerHTML={{ __html: r.met ? "<svg viewBox=\"0 0 16 16\" width=\"16\" height=\"16\" fill=\"none\" aria-hidden=\"true\"><path d=\"M3 8.5l3 3 7-7\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg>" : "<svg viewBox=\"0 0 16 16\" width=\"16\" height=\"16\" fill=\"none\" aria-hidden=\"true\"><path d=\"M4 4l8 8M12 4l-8 8\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\"/></svg>" }} />
            <span>{r.label} — {r.met ? "Met" : "Not met"}</span>
          </li>
        ))}
      </ul>
      <p style={{ margin: 0, padding: "10px 12px", borderRadius: 8, fontWeight: 600, fontSize: 14,
        background: open ? "#2f8a521a" : "#b23b3b1a", color: open ? "#2f8a52" : "#b23b3b" }}>
        {open ? "Gate open — ready to proceed" : "Gate closed — resolve blocking conditions"}
      </p>
    </div>
  );
}