Task timeline with durations/dependencies.
| Task | Start | End |
|---|---|---|
| Research | Week 1 | Week 2 |
| Design | Week 2 | Week 3 |
| Build | Week 3 | Week 5 |
| Test | Week 5 | Week 5.5 |
| Launch | Week 6 | Week 6 |
<figure class="gantt-demo gantt-demo--comfortable" style="--accent:#E8A020;">
<figcaption class="gantt-demo__title">Q3 launch plan</figcaption>
<div class="gantt-demo__chart">
<div class="gantt-demo__header" aria-hidden="true">
<span class="gantt-demo__tick">Week 1</span>
<span class="gantt-demo__tick">Week 2</span>
<span class="gantt-demo__tick">Week 3</span>
<span class="gantt-demo__tick">Week 4</span>
<span class="gantt-demo__tick">Week 5</span>
<span class="gantt-demo__tick">Week 6</span>
</div>
<div class="gantt-demo__row">
<span class="gantt-demo__label">Research</span>
<div class="gantt-demo__track">
<div class="gantt-demo__bar" style="left:0%;width:33.3%;">Research</div>
</div>
</div>
<div class="gantt-demo__row">
<span class="gantt-demo__label">Design</span>
<div class="gantt-demo__track">
<div class="gantt-demo__bar" style="left:16.7%;width:33.3%;">Design</div>
<div class="gantt-demo__dep" style="left:49.5%;width:16.8%;" aria-hidden="true"></div>
</div>
</div>
<div class="gantt-demo__row">
<span class="gantt-demo__label">Build</span>
<div class="gantt-demo__track">
<div class="gantt-demo__bar gantt-demo__bar--critical" style="left:33.3%;width:50%;">Build</div>
</div>
</div>
<div class="gantt-demo__row">
<span class="gantt-demo__label">Test</span>
<div class="gantt-demo__track">
<div class="gantt-demo__bar" style="left:66.7%;width:25%;">Test</div>
</div>
</div>
<div class="gantt-demo__row">
<span class="gantt-demo__label">Launch</span>
<div class="gantt-demo__track">
<div class="gantt-demo__bar gantt-demo__bar--milestone" style="left:91.7%;width:8.3%;">Launch</div>
</div>
</div>
</div>
<table class="gantt-demo__summary">
<caption>Task summary</caption>
<thead>
<tr><th scope="col">Task</th><th scope="col">Start</th><th scope="col">End</th></tr>
</thead>
<tbody>
<tr><th scope="row">Research</th><td>Week 1</td><td>Week 2</td></tr>
<tr><th scope="row">Design</th><td>Week 2</td><td>Week 3</td></tr>
<tr><th scope="row">Build</th><td>Week 3</td><td>Week 5</td></tr>
<tr><th scope="row">Test</th><td>Week 5</td><td>Week 5.5</td></tr>
<tr><th scope="row">Launch</th><td>Week 6</td><td>Week 6</td></tr>
</tbody>
</table>
</figure>
<style>
.gantt-demo { font: 13px/1.4 system-ui, sans-serif; color: #241430; background: #FAF7F2; border: 1.5px solid #24143022; border-radius: 12px; padding: 18px; box-sizing: border-box; }
.gantt-demo__title { font-size: 15px; font-weight: 600; margin-bottom: 14px; }
.gantt-demo__chart { display: flex; flex-direction: column; gap: 10px; }
.gantt-demo--compact .gantt-demo__chart { gap: 4px; }
.gantt-demo__header { display: flex; padding-left: 90px; margin-bottom: 4px; }
.gantt-demo__tick { flex: 1; font-size: 10px; color: #24143099; text-transform: uppercase; letter-spacing: .03em; }
.gantt-demo__row { display: flex; align-items: center; gap: 8px; }
.gantt-demo__label { width: 82px; flex-shrink: 0; font-size: 12px; font-weight: 600; }
.gantt-demo__track { position: relative; flex: 1; height: 22px; background: #24143010; border-radius: 6px; }
.gantt-demo--compact .gantt-demo__track { height: 16px; }
.gantt-demo__bar { position: absolute; top: 0; bottom: 0; background: var(--accent); border-radius: 6px; color: #241430; font-size: 11px; font-weight: 600; display: flex; align-items: center; padding: 0 8px; white-space: nowrap; overflow: hidden; }
.gantt-demo__bar--critical { background: #241430; color: #FAF7F2; }
.gantt-demo__bar--milestone { background: #F5C2E0; }
.gantt-demo__dep { position: absolute; top: -10px; height: 2px; background: #24143055; }
.gantt-demo__summary { margin-top: 16px; width: 100%; border-collapse: collapse; font-size: 11px; }
.gantt-demo__summary caption { text-align: left; font-size: 11px; color: #24143099; margin-bottom: 4px; }
.gantt-demo__summary th, .gantt-demo__summary td { text-align: left; padding: 3px 8px 3px 0; border-bottom: 1px solid #24143014; }
</style><figure class="gantt-tw gantt-tw--comfortable font-sans text-[13px] text-[#241430] bg-[#FAF7F2] border-[1.5px] border-[#24143022] rounded-xl p-[18px] box-border" style="--accent:#E8A020;">
<figcaption class="text-[15px] font-semibold mb-3.5">Q3 launch plan</figcaption>
<div class="gantt-tw__chart flex flex-col gap-2.5">
<div class="gantt-tw__header flex pl-[90px] mb-1" aria-hidden="true">
<span class="flex-1 text-[10px] uppercase tracking-wide text-[#241430]/60">Week 1</span>
<span class="flex-1 text-[10px] uppercase tracking-wide text-[#241430]/60">Week 2</span>
<span class="flex-1 text-[10px] uppercase tracking-wide text-[#241430]/60">Week 3</span>
<span class="flex-1 text-[10px] uppercase tracking-wide text-[#241430]/60">Week 4</span>
<span class="flex-1 text-[10px] uppercase tracking-wide text-[#241430]/60">Week 5</span>
<span class="flex-1 text-[10px] uppercase tracking-wide text-[#241430]/60">Week 6</span>
</div>
<div class="flex items-center gap-2">
<span class="w-[82px] shrink-0 text-xs font-semibold">Research</span>
<div class="gantt-tw__track relative flex-1 bg-[#24143010] rounded-md">
<div class="gantt-tw__bar absolute inset-y-0 rounded-md text-[#241430] text-[11px] font-semibold flex items-center px-2 whitespace-nowrap overflow-hidden" style="left:0%;width:33.3%;background:#E8A020;">Research</div>
</div>
</div>
<div class="flex items-center gap-2">
<span class="w-[82px] shrink-0 text-xs font-semibold">Design</span>
<div class="gantt-tw__track relative flex-1 bg-[#24143010] rounded-md">
<div class="gantt-tw__bar absolute inset-y-0 rounded-md text-[#241430] text-[11px] font-semibold flex items-center px-2 whitespace-nowrap overflow-hidden" style="left:16.7%;width:33.3%;background:#E8A020;">Design</div>
<div class="absolute h-0.5 bg-[#24143055]" style="top:-10px;left:49.5%;width:16.8%;" aria-hidden="true"></div>
</div>
</div>
<div class="flex items-center gap-2">
<span class="w-[82px] shrink-0 text-xs font-semibold">Build</span>
<div class="gantt-tw__track relative flex-1 bg-[#24143010] rounded-md">
<div class="gantt-tw__bar absolute inset-y-0 rounded-md text-[#FAF7F2] text-[11px] font-semibold flex items-center px-2 whitespace-nowrap overflow-hidden bg-[#241430]" style="left:33.3%;width:50%;">Build</div>
</div>
</div>
<div class="flex items-center gap-2">
<span class="w-[82px] shrink-0 text-xs font-semibold">Test</span>
<div class="gantt-tw__track relative flex-1 bg-[#24143010] rounded-md">
<div class="gantt-tw__bar absolute inset-y-0 rounded-md text-[#241430] text-[11px] font-semibold flex items-center px-2 whitespace-nowrap overflow-hidden" style="left:66.7%;width:25%;background:#E8A020;">Test</div>
</div>
</div>
<div class="flex items-center gap-2">
<span class="w-[82px] shrink-0 text-xs font-semibold">Launch</span>
<div class="gantt-tw__track relative flex-1 bg-[#24143010] rounded-md">
<div class="gantt-tw__bar absolute inset-y-0 rounded-md text-[#241430] text-[11px] font-semibold flex items-center px-2 whitespace-nowrap overflow-hidden bg-[#F5C2E0]" style="left:91.7%;width:8.3%;">Launch</div>
</div>
</div>
</div>
<table class="gantt-tw__summary mt-4 w-full border-collapse text-[11px]">
<caption class="text-left text-[11px] text-[#241430]/60 mb-1">Task summary</caption>
<thead>
<tr><th scope="col" class="text-left py-1 pr-2 border-b border-[#24143014]">Task</th><th scope="col" class="text-left py-1 pr-2 border-b border-[#24143014]">Start</th><th scope="col" class="text-left py-1 pr-2 border-b border-[#24143014]">End</th></tr>
</thead>
<tbody>
<tr><th scope="row" class="text-left py-1 pr-2 border-b border-[#24143014] font-normal">Research</th><td class="py-1 pr-2 border-b border-[#24143014]">Week 1</td><td class="py-1 pr-2 border-b border-[#24143014]">Week 2</td></tr>
<tr><th scope="row" class="text-left py-1 pr-2 border-b border-[#24143014] font-normal">Design</th><td class="py-1 pr-2 border-b border-[#24143014]">Week 2</td><td class="py-1 pr-2 border-b border-[#24143014]">Week 3</td></tr>
<tr><th scope="row" class="text-left py-1 pr-2 border-b border-[#24143014] font-normal">Build</th><td class="py-1 pr-2 border-b border-[#24143014]">Week 3</td><td class="py-1 pr-2 border-b border-[#24143014]">Week 5</td></tr>
<tr><th scope="row" class="text-left py-1 pr-2 border-b border-[#24143014] font-normal">Test</th><td class="py-1 pr-2 border-b border-[#24143014]">Week 5</td><td class="py-1 pr-2 border-b border-[#24143014]">Week 5.5</td></tr>
<tr><th scope="row" class="text-left py-1 pr-2 font-normal">Launch</th><td class="py-1 pr-2">Week 6</td><td class="py-1 pr-2">Week 6</td></tr>
</tbody>
</table>
</figure>
<style>
.gantt-tw--compact .gantt-tw__chart { gap: 4px; }
.gantt-tw--compact .gantt-tw__track { height: 16px; }
.gantt-tw__track { height: 22px; }
</style>export function GanttChart({
title = "Q3 launch plan",
unit = "Week",
density = "comfortable",
accent = "#E8A020",
dependency = true,
}) {
const rows = [
{ label: "Research", left: 0, width: 33.3, fill: accent, text: "#241430" },
{ label: "Design", left: 16.7, width: 33.3, fill: accent, text: "#241430" },
{ label: "Build", left: 33.3, width: 50, fill: "#241430", text: "#FAF7F2" },
{ label: "Test", left: 66.7, width: 25, fill: accent, text: "#241430" },
{ label: "Launch", left: 91.7, width: 8.3, fill: "#F5C2E0", text: "#241430" },
];
const summary = [
{ label: "Research", start: 1, end: 2 },
{ label: "Design", start: 2, end: 3 },
{ label: "Build", start: 3, end: 5 },
{ label: "Test", start: 5, end: 5.5 },
{ label: "Launch", start: 6, end: 6 },
];
const trackHeight = density === "compact" ? 16 : 22;
const rowGap = density === "compact" ? 4 : 10;
return (
<figure style={{ fontFamily: "system-ui, sans-serif", fontSize: 13, color: "#241430", background: "#FAF7F2", border: "1.5px solid #24143022", borderRadius: 12, padding: 18, boxSizing: "border-box" }}>
<figcaption style={{ fontSize: 15, fontWeight: 600, marginBottom: 14 }}>{title}</figcaption>
<div style={{ display: "flex", flexDirection: "column", gap: rowGap }}>
<div style={{ display: "flex", paddingLeft: 90, marginBottom: 4 }} aria-hidden="true">
{[1, 2, 3, 4, 5, 6].map((n) => (
<span key={n} style={{ flex: 1, fontSize: 10, color: "#24143099", textTransform: "uppercase", letterSpacing: ".03em" }}>{unit} {n}</span>
))}
</div>
{rows.map((r) => (
<div key={r.label} style={{ display: "flex", alignItems: "center", gap: 8 }}>
<span style={{ width: 82, flexShrink: 0, fontSize: 12, fontWeight: 600 }}>{r.label}</span>
<div style={{ position: "relative", flex: 1, height: trackHeight, background: "#24143010", borderRadius: 6 }}>
<div style={{ position: "absolute", top: 0, bottom: 0, left: `${r.left}%`, width: `${r.width}%`, background: r.fill, color: r.text, borderRadius: 6, fontSize: 11, fontWeight: 600, display: "flex", alignItems: "center", padding: "0 8px", whiteSpace: "nowrap", overflow: "hidden" }}>{r.label}</div>
{dependency && r.label === "Design" && (
<div style={{ position: "absolute", top: -10, left: "49.5%", width: "16.8%", height: 2, background: "#24143055" }} aria-hidden="true" />
)}
</div>
</div>
))}
</div>
<table style={{ marginTop: 16, width: "100%", borderCollapse: "collapse", fontSize: 11 }}>
<caption style={{ textAlign: "left", fontSize: 11, color: "#24143099", marginBottom: 4 }}>Task summary</caption>
<thead>
<tr>
<th scope="col" style={{ textAlign: "left", padding: "3px 8px 3px 0", borderBottom: "1px solid #24143014" }}>Task</th>
<th scope="col" style={{ textAlign: "left", padding: "3px 8px 3px 0", borderBottom: "1px solid #24143014" }}>Start</th>
<th scope="col" style={{ textAlign: "left", padding: "3px 8px 3px 0", borderBottom: "1px solid #24143014" }}>End</th>
</tr>
</thead>
<tbody>
{summary.map((s) => (
<tr key={s.label}>
<th scope="row" style={{ textAlign: "left", fontWeight: 400, padding: "3px 8px 3px 0", borderBottom: "1px solid #24143014" }}>{s.label}</th>
<td style={{ padding: "3px 8px 3px 0", borderBottom: "1px solid #24143014" }}>{unit} {s.start}</td>
<td style={{ padding: "3px 8px 3px 0", borderBottom: "1px solid #24143014" }}>{unit} {s.end}</td>
</tr>
))}
</tbody>
</table>
</figure>
);
}