# Sales pipeline dashboard

> A dark sales pipeline board: KPI counters roll up, and a deal card is dragged from Qualified to Won with a celebratory toast.

- Category: Developer tools
- Version: 1.0
- Source: https://ownlyplans.com/bhaskar/sales-pipeline-dashboard/

## Overview

A CRM-style pipeline you can paste into Claude, Cursor or Lovable. Three KPI tiles count up, four stage columns hold deal cards and one highlighted deal glides stage to stage until the Won column total updates. Topic inspired by OpenDesign's public dashboard prompt list; this prompt and design are written from scratch.

## Tech stack

- CSS
- Dashboard
- HTML

## Build steps

### 1. Paste the prompt

Paste into your AI tool. It builds the whole dashboard in one go.

Prompt:

```text
Build a single-file HTML sales pipeline dashboard, 1280x720 desktop layout, dark navy theme (background #0a1020, panels #0e1730, cards #16213d, accent blue #2563eb, success green #10b981). System fonts only, no libraries.
Header: gradient square logo, title "Sales pipeline", a pill "Q4 - EMEA", three overlapping avatar circles on the right.
KPI row: three tiles (Open value, Win rate, Avg cycle). Numbers count up from 0 using a CSS @property integer animation (no JavaScript): $1840k, 34%, 21 days.
Board: four columns Lead, Qualified, Proposal, Won, each with a header (name and count), 2-3 deal cards (company, source line, value on the right) and a thin gradient progress bar pinned to the bottom of the column.
Motion (one 8 second loop, everything fades out at the end and restarts): one highlighted deal card "Acme renewal $48k" in Qualified lifts (scale 1.04, slight rotation, blue glow), slides into Proposal, pauses, then slides into Won. When it lands, a green toast "+$48,000 won" pops in and the Won total cross-fades from $212k to $260k. The progress bars grow in at the start.
Respect prefers-reduced-motion. Return only the complete HTML.
```

### 2. Check the KPI counters

The three tiles should roll up from zero without any script.

### 3. Check the deal moving

The Acme card should glide Qualified, Proposal, Won and the Won total should change.

**Done when:** You can see it working in the browser.

### 4. Reuse it

Swap the company names, currency and stage names for your own pipeline.

## Assets

### prompt.md — The full prompt.

~~~~
# Sales pipeline dashboard

Copy this prompt into Claude, Cursor or Lovable.

```text
Build a single-file HTML sales pipeline dashboard, 1280x720 desktop layout, dark navy theme (background #0a1020, panels #0e1730, cards #16213d, accent blue #2563eb, success green #10b981). System fonts only, no libraries.
Header: gradient square logo, title "Sales pipeline", a pill "Q4 - EMEA", three overlapping avatar circles on the right.
KPI row: three tiles (Open value, Win rate, Avg cycle). Numbers count up from 0 using a CSS @property integer animation (no JavaScript): $1840k, 34%, 21 days.
Board: four columns Lead, Qualified, Proposal, Won, each with a header (name and count), 2-3 deal cards (company, source line, value on the right) and a thin gradient progress bar pinned to the bottom of the column.
Motion (one 8 second loop, everything fades out at the end and restarts): one highlighted deal card "Acme renewal $48k" in Qualified lifts (scale 1.04, slight rotation, blue glow), slides into Proposal, pauses, then slides into Won. When it lands, a green toast "+$48,000 won" pops in and the Won total cross-fades from $212k to $260k. The progress bars grow in at the start.
Respect prefers-reduced-motion. Return only the complete HTML.
```
~~~~

### index.html.md — Complete code of the result in the video.

~~~~
# index.html

The finished result as one file. Save it as index.html and open it.

```html
<!doctype html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>Sales pipeline dashboard</title><style>*{box-sizing:border-box;margin:0;padding:0}
html,body{width:1280px;height:720px;overflow:hidden}
body{font-family:ui-sans-serif,system-ui,-apple-system,"Segoe UI",Roboto,sans-serif;-webkit-font-smoothing:antialiased}
@property --n{syntax:'<integer>';inherits:false;initial-value:0}
.stage{position:absolute;inset:0;animation:cyc 8s linear infinite both}
@keyframes cyc{0%{opacity:0}4%{opacity:1}94%{opacity:1}100%{opacity:0}}
body:not(.go) *,body:not(.go) *::before,body:not(.go) *::after{animation-play-state:paused!important}
.cnt::after{content:counter(n)}.cnt{counter-reset:n var(--n)}
@media (prefers-reduced-motion:reduce){*{animation:none!important}}


body{background:#0a1020;color:#e8eefc}
.top{position:absolute;left:40px;right:40px;top:28px;display:flex;align-items:center;gap:14px}
.dot{width:26px;height:26px;border-radius:8px;background:linear-gradient(135deg,#4cc9f0,#7b6cff)}
.top h1{font-size:21px;letter-spacing:-.02em}.pill{font-size:12px;padding:5px 11px;border-radius:99px;background:#16203a;color:#9fb2d8}
.av{margin-left:auto;display:flex}.av i{width:30px;height:30px;border-radius:50%;border:2px solid #0a1020;margin-left:-8px;background:#3b82f6}.av i:nth-child(2){background:#f59e0b}.av i:nth-child(3){background:#34d399}
.kpis{position:absolute;left:40px;right:40px;top:84px;display:grid;grid-template-columns:repeat(3,1fr);gap:16px}
.k{background:#111a30;border:1px solid #1b2742;border-radius:16px;padding:16px 20px;animation:rise 8s both infinite}
.k:nth-child(2){animation-delay:.12s}.k:nth-child(3){animation-delay:.24s}
@keyframes rise{0%,3%{opacity:0;transform:translateY(14px)}10%,100%{opacity:1;transform:none}}
.k small{font-size:12px;color:#8aa0cc;text-transform:uppercase;letter-spacing:.08em}.k b{display:block;font-size:34px;letter-spacing:-.03em;margin-top:4px}
.c1{animation:c1 8s infinite both}@keyframes c1{0%,6%{--n:0}34%,100%{--n:1840}}
.c2{animation:c2 8s infinite both}@keyframes c2{0%,6%{--n:0}34%,100%{--n:34}}
.c3{animation:c3 8s infinite both}@keyframes c3{0%,6%{--n:0}34%,100%{--n:21}}
.cols{position:absolute;left:40px;right:40px;top:206px;display:grid;grid-template-columns:repeat(4,1fr);gap:16px}
.col{background:#0e1730;border:1px solid #18233f;border-radius:18px;height:420px;padding:14px;position:relative}
.col h3{font-size:13px;display:flex;justify-content:space-between;color:#a9bbe0;margin-bottom:12px}
.card{background:#16213d;border:1px solid #20305a;border-radius:12px;padding:12px 14px;margin-bottom:10px;height:74px}
.card b{font-size:14px;display:block}.card span{font-size:12px;color:#8aa0cc}.card em{float:right;font-style:normal;font-weight:700;color:#cfe0ff}
.mv{position:absolute;left:14px;top:120px;width:calc(100% - 28px);background:linear-gradient(135deg,#1e3a8a,#2563eb);border:1px solid #60a5fa;box-shadow:0 18px 40px -10px #2563ebaa,0 0 0 3px #60a5fa33;z-index:5;animation:mv 8s infinite both}
@keyframes mv{0%,20%{transform:translate(0,0) scale(1)}26%{transform:translate(0,-8px) scale(1.04) rotate(-1.5deg)}44%{transform:translate(calc(100% + 16px),-8px) scale(1.04) rotate(1deg)}50%,56%{transform:translate(calc(100% + 16px),0) scale(1)}62%{transform:translate(calc(100% + 16px),-8px) scale(1.04)}82%{transform:translate(calc(200% + 32px),-8px) scale(1.04) rotate(1deg)}88%,100%{transform:translate(calc(200% + 32px),0) scale(1)}}
.won{position:absolute;right:24px;top:300px;background:#064e3b;color:#6ee7b7;border:1px solid #10b981;border-radius:12px;padding:10px 14px;font-weight:700;font-size:14px;opacity:0;animation:won 8s infinite both;z-index:6}
@keyframes won{0%,86%{opacity:0;transform:translateY(10px) scale(.9)}90%,97%{opacity:1;transform:none}100%{opacity:0}}
.t1{animation:t1 8s infinite both}.t2{animation:t2 8s infinite both}
@keyframes t1{0%,84%{opacity:1}88%,100%{opacity:0}}@keyframes t2{0%,84%{opacity:0}88%,100%{opacity:1}}
.col h3 span{position:relative}.col h3 s{text-decoration:none;position:absolute;right:0;white-space:nowrap}
.bar{position:absolute;left:14px;right:14px;bottom:16px;height:8px;border-radius:9px;background:#16213d;overflow:hidden}.bar i{display:block;height:100%;border-radius:9px;background:linear-gradient(90deg,#4cc9f0,#7b6cff);animation:gr 8s infinite both}
@keyframes gr{0%,8%{width:0}40%,100%{width:var(--w)}}
</style></head><body><div class="stage">
<div class="top"><div class="dot"></div><h1>Sales pipeline</h1><span class="pill">Q4 · EMEA</span><div class="av"><i></i><i></i><i></i></div></div>
<div class="kpis"><div class="k"><small>Open value</small><b>$<span class="cnt c1"></span>k</b></div><div class="k"><small>Win rate</small><b><span class="cnt c2"></span>%</b></div><div class="k"><small>Avg cycle</small><b><span class="cnt c3"></span> days</b></div></div>
<div class="cols">
<div class="col"><h3>Lead <span>6</span></h3><div class="card"><em>$12k</em><b>Brightwave</b><span>Inbound · Webinar</span></div><div class="card"><em>$9k</em><b>Kestrel Labs</b><span>Outbound</span></div><div class="card"><em>$21k</em><b>Norden AB</b><span>Referral</span></div><div class="bar"><i style="--w:70%"></i></div></div>
<div class="col"><h3>Qualified <span>4</span></h3><div class="card"><em>$33k</em><b>Orbit Retail</b><span>Demo booked</span></div><div class="card mv"><em>$48k</em><b>Acme renewal</b><span>Champion: Priya S.</span></div><div class="card"><em>$61k</em><b>Helio Bank</b><span>Security review</span></div><div class="bar"><i style="--w:55%"></i></div></div>
<div class="col"><h3>Proposal <span>3</span></h3><div class="card"><em>$27k</em><b>Tidal Foods</b><span>Pricing sent</span></div><div class="card"><em>$54k</em><b>Vantage IO</b><span>Legal</span></div><div class="bar"><i style="--w:40%"></i></div></div>
<div class="col"><h3>Won <span class="t1">$212k</span><span class="t2" style="position:absolute;right:14px;top:14px;color:#6ee7b7">$260k</span></h3><div class="card"><em>$72k</em><b>Lumen Co</b><span>Signed Oct 28</span></div><div class="card"><em>$140k</em><b>Pine &amp; Co</b><span>Signed Nov 02</span></div><div class="bar"><i style="--w:85%;background:linear-gradient(90deg,#34d399,#10b981)"></i></div></div>
</div><div class="won">+$48,000 won · Acme renewal</div></div><script>window.start=function(){document.body.classList.add("go")};if(!/[?&]rec/.test(location.search))start();</script></body></html>
```
~~~~


## Build instructions by tool

### Claude Code

Open a terminal in an empty folder, run `claude`, then paste the prompt.

```text
Build the "Sales pipeline dashboard" app from the OwnlyPlans blueprint at https://ownlyplans.com/bhaskar/sales-pipeline-dashboard/.
Stack: CSS, Dashboard, HTML.
Follow the plan's steps in order: Paste the prompt → Check the KPI counters → Check the deal moving → Reuse it.
Download the full plan (Markdown) from the link above and keep it in the project root as PLAN.md.
Ask me before adding anything not in the plan. (Prepared for Claude Code.)
```

### Cursor

Open an empty folder in Cursor, start an Agent chat, then paste the prompt.

```text
Build the "Sales pipeline dashboard" app from the OwnlyPlans blueprint at https://ownlyplans.com/bhaskar/sales-pipeline-dashboard/.
Stack: CSS, Dashboard, HTML.
Follow the plan's steps in order: Paste the prompt → Check the KPI counters → Check the deal moving → Reuse it.
Download the full plan (Markdown) from the link above and keep it in the project root as PLAN.md.
Ask me before adding anything not in the plan. (Prepared for Cursor.)
```

### Lovable

Start a new Lovable project and paste the prompt as your first message.

```text
Build the "Sales pipeline dashboard" app from the OwnlyPlans blueprint at https://ownlyplans.com/bhaskar/sales-pipeline-dashboard/.
Stack: CSS, Dashboard, HTML.
Follow the plan's steps in order: Paste the prompt → Check the KPI counters → Check the deal moving → Reuse it.
Download the full plan (Markdown) from the link above and keep it in the project root as PLAN.md.
Ask me before adding anything not in the plan. (Prepared for Lovable.)
```

## Definition of done

- Every build step is complete and the app runs locally.
- The main user flow works end to end.
- Share your build on OwnlyPlans with a demo link, build time and tool.
