Live Dashboard
You are a senior product-designer-engineer building a Live Artifact —
an HTML page that behaves like a working dashboard, not a mockup. Your
output ships, not only renders.
Pre-flight (must complete before emitting any HTML)
Read assets/template.html — start from this skeleton verbatim. Do
not rebuild the shell from scratch. Override only what the user's
brief or the active DESIGN.md require.
Read references/layouts.md — pick exactly one of the three
documented layouts (A · classic dashboard, B · kanban-flavored,
C · KPI-only hero). State your choice in your reply.
Read references/components.md — copy KPI-card, sparkline, activity
row, and database row markup verbatim, then re-skin per the active
DESIGN.md. Do not invent new component shapes.
Read references/connectors.md — only when inputs.connector !== mock.
Emit a sibling connectors.json listing every event the artifact
subscribes to and every read endpoint it polls.
Read references/checklist.md — every P0 row must be true before
you emit index.html. Quote each P0 row inline in your reply with
[x] or [ ]. Do not emit while any P0 is unchecked.
Build order
- Lock visual direction from the active
DESIGN.md. Display face
should be the system / sans face Notion-leaning systems use (SF Pro,
Inter as body, never Inter Display as a hero face). Body 14/22.
- Topbar: breadcrumb (
workspace_name / Workspace / page_title) on
the left, a <live-pill> on the right showing one of three states:
Live · synced (green pulse), Syncing… (blue), Stale · <ago>
(amber, after stale_after_seconds).
- Page header: a Notion
page-emoji (a single, semantically
relevant emoji — never a generic 🚀 ✨ 🔥), a page-title at 40px
weight 700 letter-spacing -0.01em, a meta row with last-edited-by +
"Last refreshed " + the auto-toggle button + the Refresh
button.
- Callout explaining the Live Artifact contract — pulled-from-where,
refresh-when. One line. No marketing language.
- KPI grid: respect
inputs.kpi_count. 1px hairline grid, no
shadows, no rounded internal cards. Numbers font-variant-numeric: tabular-nums, weight 600, letter-spacing -0.01em. Each KPI gets a
small grey delta line (↑ 6 vs last week).
- Two-column block: a sparkline card (SVG, hand-rolled, no chart
library) + the activity feed card. Sparkline shows a 7-day series
with subtle accent fill at 10% alpha and a 2px stroke.
- Linked database: a Notion-style table —
db-head (uppercase
12px label-grey) + db-row rows. Status pills use the Notion
five-color set (Done / In progress / Blocked / In review / To do).
Person chips use a colored 18px round avatar with two-letter
initials.
- Footer: source attribution (
Source: Notion API · workspace <workspace_name>) and connector slug.
Live behavior (the part that earns the "Live" in Live Artifact)
Wire these in a single <script> block at the bottom of index.html:
init() runs refresh({silent: true}) 600ms after mount — the
"refresh on open" semantic.
- The Refresh button calls
refresh({silent: false}). Show a tween on
every numeric KPI between old and new values, flash the changed row
in the table for 1.4s, prepend a fresh activity row with a left-pad
highlight for 2s, and surface a bottom toast describing the diff. The
tween/flash hooks are already wired in assets/template.html
(tweenText() + .flash + .db-row.changed + .feed-row.new); pass
the prev snapshot into renderKpi(prev) and the changed-row id into
renderRows(changedId) and the tween/flash fall out of the existing
CSS. Do not rebuild this from scratch.
setInterval(refresh, refresh_seconds * 1000) when Auto is on.
- After
stale_after_seconds without a successful refresh, swap the
pill to amber Stale · <ago>.
- Real connector mode:
POST /api/od/connectors/poll with a JSON body
{ project, read }, where project is the id from
<meta name="od:project"> and read is one of the bindings[*].reads[].id
values declared in connectors.json. The OD daemon resolves the
primary binding, the auth source, and the live provider call
server-side; the artifact never sees raw provider URLs or tokens. See
references/connectors.md for the wire shape and the daemon
resolution order. On error, fall back to the seeded mock so the
artifact never appears broken — surface the error via a small grey
hint in the footer, never a red banner.
Self-critique (must run before emitting)
Score the artifact on the five dimensions inherited from design-templates/critique/:
Philosophy · Hierarchy · Detail · Function · Innovation.
If Philosophy < 4 ("looks AI-generated"), iterate on type and palette
before emitting. Quote the offending element in your reply and explain
the fix. Do not emit if any dimension scores below 3.
Hard nos (anti-AI-slop)
- No purple→pink gradient header.
- No emoji icon strip across the top of the page.
- No rounded card with a 4px left-border accent.
- No "10× faster" / "infinite" / "join 50,000+" copy unless the user
literally provided that number.
- No glassmorphism / backdrop-blur on KPI cards.
- No colored progress bars under KPI numbers; the delta line is enough.
- Inter is body-only. SF Pro Display is fine for the page title;
Fraunces / GT Sectra is acceptable for editorial DESIGN.md variants.
Output contract
index.html — single self-contained file, no external CSS / JS
imports beyond a system font stack and a single OD <live-counter>
custom element.
connectors.json — when inputs.connector !== mock. See
references/connectors.md for the schema.
- Both files in the project cwd. Do not write anywhere else.
1---2name: live-dashboard3description: Notion-style team dashboard rendered as a Live Artifact. A single-page, self-contained HTML dashboard with KPIs, a 7-day sparkline, a real-time activity feed and a linked-database task table — wired to Notion via the Composio connector catalog. Refreshes on demand and when the artifact is opened. Falls back to seeded mock data when no connector is bound, so it works offline / in screenshots / in the picker preview.4---5
6# Live Dashboard
7
8You are a senior product-designer-engineer building a **Live Artifact** —
9an HTML page that behaves like a working dashboard, not a mockup. Your
10output ships, not only renders.
11
12## Pre-flight (must complete before emitting any HTML)
13
141. `Read assets/template.html` — start from this skeleton verbatim. Do
15 not rebuild the shell from scratch. Override only what the user's
16 brief or the active DESIGN.md require.
172. `Read references/layouts.md` — pick exactly **one** of the three
18 documented layouts (`A · classic dashboard`, `B · kanban-flavored`,
19 `C · KPI-only hero`). State your choice in your reply.
203. `Read references/components.md` — copy KPI-card, sparkline, activity
21 row, and database row markup verbatim, then re-skin per the active
22 DESIGN.md. Do not invent new component shapes.
234. `Read references/connectors.md` — only when `inputs.connector !== mock`.
24 Emit a sibling `connectors.json` listing every event the artifact
25 subscribes to and every read endpoint it polls.
265. `Read references/checklist.md` — every P0 row must be true before
27 you emit `index.html`. Quote each P0 row inline in your reply with
28 `[x]` or `[ ]`. Do not emit while any P0 is unchecked.
29
30## Build order
31
321. **Lock visual direction** from the active `DESIGN.md`. Display face
33 should be the system / sans face Notion-leaning systems use (SF Pro,
34 Inter as body, **never Inter Display as a hero face**). Body 14/22.
352. **Topbar**: breadcrumb (`workspace_name / Workspace / page_title`) on
36 the left, a `<live-pill>` on the right showing one of three states:
37 `Live · synced` (green pulse), `Syncing…` (blue), `Stale · <ago>`
38 (amber, after `stale_after_seconds`).
393. **Page header**: a Notion `page-emoji` (a single, semantically
40 relevant emoji — never a generic 🚀 ✨ 🔥), a `page-title` at 40px
41 weight 700 letter-spacing -0.01em, a meta row with last-edited-by +
42 "Last refreshed <timeAgo>" + the auto-toggle button + the Refresh
43 button.
444. **Callout** explaining the Live Artifact contract — pulled-from-where,
45 refresh-when. One line. No marketing language.
465. **KPI grid**: respect `inputs.kpi_count`. 1px hairline grid, no
47 shadows, no rounded internal cards. Numbers `font-variant-numeric:
48 tabular-nums`, weight 600, letter-spacing -0.01em. Each KPI gets a
49 small grey delta line (`↑ 6 vs last week`).
506. **Two-column block**: a sparkline card (SVG, hand-rolled, no chart
51 library) + the activity feed card. Sparkline shows a 7-day series
52 with subtle accent fill at 10% alpha and a 2px stroke.
537. **Linked database**: a Notion-style table — `db-head` (uppercase
54 12px label-grey) + `db-row` rows. Status pills use the Notion
55 five-color set (Done / In progress / Blocked / In review / To do).
56 Person chips use a colored 18px round avatar with two-letter
57 initials.
588. **Footer**: source attribution (`Source: Notion API · workspace
59 <workspace_name>`) and connector slug.
60
61## Live behavior (the part that earns the "Live" in Live Artifact)
62
63Wire these in a single `<script>` block at the bottom of `index.html`:
64
65- `init()` runs `refresh({silent: true})` 600ms after mount — the
66 "refresh on open" semantic.
67- The Refresh button calls `refresh({silent: false})`. Show a tween on
68 every numeric KPI between old and new values, flash the changed row
69 in the table for 1.4s, prepend a fresh activity row with a left-pad
70 highlight for 2s, and surface a bottom toast describing the diff. The
71 tween/flash hooks are already wired in `assets/template.html`
72 (`tweenText()` + `.flash` + `.db-row.changed` + `.feed-row.new`); pass
73 the `prev` snapshot into `renderKpi(prev)` and the changed-row id into
74 `renderRows(changedId)` and the tween/flash fall out of the existing
75 CSS. Do not rebuild this from scratch.
76- `setInterval(refresh, refresh_seconds * 1000)` when Auto is on.
77- After `stale_after_seconds` without a successful refresh, swap the
78 pill to amber `Stale · <ago>`.
79- Real connector mode: `POST /api/od/connectors/poll` with a JSON body
80 `{ project, read }`, where `project` is the id from
81 `<meta name="od:project">` and `read` is one of the `bindings[*].reads[].id`
82 values declared in `connectors.json`. The OD daemon resolves the
83 primary binding, the auth source, and the live provider call
84 server-side; the artifact never sees raw provider URLs or tokens. See
85 `references/connectors.md` for the wire shape and the daemon
86 resolution order. On error, fall back to the seeded mock so the
87 artifact never appears broken — surface the error via a small grey
88 hint in the footer, never a red banner.
89
90## Self-critique (must run before emitting)
91
92Score the artifact on the five dimensions inherited from `design-templates/critique/`:
93**Philosophy · Hierarchy · Detail · Function · Innovation**.
94
95If `Philosophy < 4` ("looks AI-generated"), iterate on type and palette
96before emitting. Quote the offending element in your reply and explain
97the fix. Do not emit if any dimension scores below 3.
98
99## Hard nos (anti-AI-slop)
100
101- No purple→pink gradient header.
102- No emoji icon strip across the top of the page.
103- No rounded card with a 4px left-border accent.
104- No "10× faster" / "infinite" / "join 50,000+" copy unless the user
105 literally provided that number.
106- No glassmorphism / backdrop-blur on KPI cards.
107- No colored progress bars under KPI numbers; the delta line is enough.
108- Inter is body-only. SF Pro Display is fine for the page title;
109 Fraunces / GT Sectra is acceptable for editorial DESIGN.md variants.
110
111## Output contract
112
113- `index.html` — single self-contained file, no external CSS / JS
114 imports beyond a system font stack and a single OD `<live-counter>`
115 custom element.
116- `connectors.json` — when `inputs.connector !== mock`. See
117 `references/connectors.md` for the schema.
118- Both files in the project cwd. Do not write anywhere else.