Dashboard
QI Hub
Org-wide view across both coordinators · Thu Aug 14, 2026
Your layout · saved Aug 12
State · Edit mode with widget gallery drawer
Drop a widget here
or pick one from the gallery →
Widget gallery
Book & Growth
Book growth
Opened vs closed per month
Added
Active files
Current book size with trend
Added
Exchange-type mix
Delayed · reverse · improvement
Deadlines & Risk
Deadline-risk exposure
Files by days to deadline
Added
Deadline concentrations
45/180 density · next 8 weeks
Team & Workload
Coordinator workload
Active files vs load ceiling
Added
E-sign cycle time
Median request → signed
Intake
Intake pipeline
Received → accepted funnel
Intake sources
CRM API · direct · referral
Funds Operations
Funds-pipeline throughput
Escrow movement counts
Disbursement approvals
Dual-approval queue status
Governance & Audit
Governance panel
Approvals · audit events · exports
Pinned report view
Any saved custom report, live
Widgets only ever show data your role can already read. No new access is granted by adding one.
State · Widget editor dialog — Metric tab (left) and Pin-a-saved-report tab (right)
Edit widget
Metric
Pin a saved report view
Widget title
Metric
Files by days to statutory deadline
Filters
Date range · Next 30 days
Coordinator · All coordinators
All types
Delayed
Reverse
Improvement
Chart type
Preview
uses your live data
47 matching files · updates as you change filters
≤ 3 days
3
4 – 7 days
6
8 – 14 days
11
15 – 30 days
27
changes apply to your layout only
Edit widget
Metric
Pin a saved report view
Saved report views
from Reports › Custom Views
Deadlines this month
Open files by coordinator
Funds held > $1M
A pinned view renders as a live table using the report's own columns and filters. Edit the definition
in Reports › Custom Views — the widget follows it automatically.
pinned views respect the report's read scope
State · Empty dashboard (first visit, or after removing all widgets)
Your dashboard is empty
Start from the default QI Hub layout — book growth, deadline risk,
coordinator workload, and governance — or build your own from the widget gallery.
State · Loading skeleton (widgets shimmer in place — no spinners)
Chrome and accents match surfaces/qi-hub-tier.html: the violet
--tier ramp marks the tier above the
indigo QI-office console. Charts hold one violet primary series with a slate comparison series; red and amber appear
only where a statutory deadline earns them. All axes start at zero with labeled gridlines.
Naming: the tier's product name was decided as QI Admin on 2026-08-28 and renamed QI Hub on
2026-09-05 (issue 3026). Every occurrence renders through a
single
.tier-name token (sidebar badge, breadcrumb, page badge, empty-state
copy) — a future rename drops in there and nowhere else.
Honesty constraints: no fee or revenue widgets exist here — fee financials are not part of the product, so the
executive story is volume, throughput, deadline risk, workload balance, and governance. Intake source copy is
"Received via CRM API" (a factual channel label, not a sync claim). Funds throughput shows movement counts, not
amounts, and states the dual-approval rule.
Layout model: each QI Hub user owns one layout, persisted server-side to their profile (never localStorage).
"Reset to default" restores the org default; "Share with QI Hub team" offers this layout as a named starting
point for other QI Hub users — it never overwrites anyone's saved layout. Widgets and pinned report views
inherit the viewer's read scope; adding a widget can never widen access, and dashboard reads are audit-logged
like every other access on this tier.
Build contract — QI Hub dashboard builder
1 · The rail is chrome, not a surface. It is painted from
--console-rail-* and stays dark in both themes; its tier accent comes from
--console-rail-tier-*. Nothing on the rail may reach for --tier,
--tier-ink or the --ink ramp — those flip with the theme and the rail does not, so
--tier-ink would land at 1.4:1 on the rail in light. The active nav item is marked by fill, border
and label colour; there is no coloured side-stripe anywhere on this page.2 · Read-only means read-only. This tier sits above coordinator operations and holds no exchange, no document and no fund. Nothing here initiates a disbursement, adjusts a statutory date, clears a KYC check or requests a signature — the widgets report, the office console acts. Adding a widget can never widen access: every widget and pinned view inherits the viewer's existing read scope, and dashboard reads are audit-logged like every other access on this tier.
3 · Deadline colour is earned, never decorative. Red and amber appear only on the two nearest deadline buckets and on the ≤ 7-day count. The concentration heatmap is violet — density, not danger — because a busy week is not a late week. An overdue clock must never render in a satisfied or neutral state anywhere this data is re-used.
4 · Four-eyes is reported as a fact, not a target. The governance panel states 12 of 12 dual-approved and names the 2 still awaiting a second approver. Approver ≠ proposer is enforced in the disbursement workflow, not by this surface; the count here must read from the same audit events, never from a separate tally.
5 · Layouts persist server-side, per user. One layout per QI Hub user, stored on the profile — never
localStorage. Share with QI Hub team offers this layout as a named
starting point and never overwrites anyone's saved layout; Reset to default restores the org
default.6 · Chart rules. One primary series in
--tier against a
--series-muted comparison series; every axis starts at zero with labelled gridlines; the
heatmap holds four intensity steps rather than five, because a fifth step cannot carry a legible numeral in
both themes. Counts are counts — funds throughput shows movements, never amounts.7 · The controls in this mockup are spans; in code they are buttons. The kebab menus, layout chip, dialog tabs, type chips, pin rows, drag handles and close buttons must ship as real
<button> elements with accessible names, so the keyboard and screen-reader paths exist and
the shared :focus-visible ring applies. The hover and active states are already defined here.8 · The tier's name is one token. Every occurrence of "QI Hub" renders through
.tier-name — sidebar badge, breadcrumb, page badge, empty-state copy. A future rename drops in
there and nowhere else.Fully tokenized against
../tokens.css — no raw hex, in the stylesheet or in any inline style
attribute. Light and dark are both designed. --tier, --tier-2,
--series-muted, --scrim and the --console-rail-* family are
[PROPOSED]: add them to packages/web-app/src/index.css in :root and
.dark before writing a call site. All names, figures and references are synthetic demo data.