Admin
Design system
Every shared component in each of its states, with the file that holds it.
Tokens
Dark first; every color has a light value under [data-theme=light].
src/app/globals.css
Surfaces, page first
Text and lines
Accent: selection and focus only
Direction and data states
Heat: heat cells, solid verdicts, gauge bands
Type: Inter, tabular numerals, weights 400 to 700, sentence case
Spacing, radius, rows, motion
Spacing 0, 2, 4, 8, 12, 16, 24, 32, 40, 48, 64 px. Radius 2 bars, 4 badges and tooltips, 6 segments, 8 buttons and inputs, 12 menus and dense panels, 16 the few cards left. Table rows 38px, one line. Motion: subtle and purposeful, 120 to 250ms (see Motion below).
Page header, tabs and section head
The header above is a PageHeader: breadcrumb, title with its ?, purpose line, and the meta row admin pages keep.
page-header.tsx · page-info.tsx · page-tabs.tsx · section-head.tsx · ai-tag.tsx
PageInfo: the ? beside a title opens how to read the page, its sources and its timing, never the scoring method; click, tap or Enter, Escape closes, a long text scrolls
AiTag: the only mark on AI text; its model and what it read go in the page's ?
Tabs: views of one page, the current path marked; they scroll with an edge fade on a phone
Section head: 16px title, one line in fg-2; the files or source on the right on admin pages only
Latest release
Each economy's newest CPI print against consensus.
Sample source · updated 31 Oct, 16:00 UTC
Values and states
value.tsx · symbol-name.tsx · state-label.tsx · src/lib/format.ts
Change: sign and color in tables, a known 0 in fg-3; an arrow only on a lone headline change
Score: a known 0 against a missing value
Price: the instrument's decimals, separators from the locale
Symbol and name on one line; the name cuts, whole on hover
State labels: admin views only; user views show a dash
Verdicts, heat and shares
Blue is bullish or a beat, red bearish or a miss; violet never means direction.
bias-badge.tsx · bias-label.tsx · heat.tsx · crowd-bar.tsx · src/app/cot/columns.tsx
BiasBadge tinted: a factor or a ranking row (the engine's level as its word)
BiasBadge solid: a section verdict or a sub-total (its points as the word)
BiasBadge without points: a plain dash with the reason on hover, never Neutral
BiasLabel: the engine's level as words with arrows, where a badge is too heavy (Help)
HeatScore: ±2 strong, ±1 faint, 0 gray
CrowdBar: retail long and short share in a table cell
LongShortBar plain: a labelled long share with its 40% and 60% marks (COT)
Score dial and gauge
A partial score shows the range its missing inputs could reach; no score is a dashed track, never a neutral one.
score-dial.tsx · score-gauge.tsx · score-gauge-geometry.ts
ScoreDial: complete, partial and no score
ScoreSummary (the dial, total, coverage and three solid sub-totals) and FactorGrid (every factor in five sections) need a full score, so they show live on Instrument detail and the Forex scorecard.
ScoreGauge: partial, 1 missing, could move ±1
1 missing could move it from +6 to +8: Bullish or Strong bullish.
ScoreGauge small: complete, partial and no score
Charts
Horizontal grid only; a level chart has both crosshair lines, a score or bar chart the vertical one. Bars start at zero.
score-history-chart.tsx · price-chart.tsx · price-score-chart.tsx · chart-frame.tsx · chart-view.tsx · _economic-data/release-bars.tsx, on shadcn chart (Recharts)
Score history
Price
Price and daily score
Daily candles. Below, the daily total score as stored after each session; a gap is a day with no stored score. ▲ and ▼ mark a day the bias moved to a higher or lower band.
Release bars
Blue beat, red miss, gray in line, outlined with no consensus; the tick is the consensus.
- Beat
- Miss
- In line
- No consensus
- Consensus
Show as table
One icon button, its label on hover: at the end of a chart's head, or once in the page header when the page is mostly charts.
Score history, no data yet
No score history yet.
Price, no data yet
No prices yet.
Data table
One 38px line a row, on the page; group heads bold over a rule; detail on hover.
data-table.tsx · data-table-layout.ts · edge-fade.ts, on shadcn table and TanStack Table
| Technical | Positioning | ||||||
|---|---|---|---|---|---|---|---|
| Trend | Seas. | COT | |||||
| Scored | |||||||
XAGUSDSilver spot | 31.84 | +1.12% | +6 | Bullish | Trend: +2 | Seas.: +1 | COT: +1 |
USOILWTI crude, futures | 71.36 | −0.84% | −4 | Bearish | Trend: −2 | Seas.: 0 | COT: −1 |
XAUUSDGold spot | 2,718.40 | +0.69% | +7 | Strong bullish | Trend: +2 | Seas.: +1 | COT: +2 |
EURUSDEuro / US dollar | 1.0842 | −0.21% | −5 | Bearish | Trend: −1 | Seas.: −1 | COT: −2 |
| No 18-part score | |||||||
NVDANVIDIA, stock | 138.27 | +2.35% | No value | No 18-part score | |||
Fixed layout, never scrolls from 768px wide. The heat cells hide when the table is under 960px wide and 1 day under 768px; group rows keep spanning the columns that remain. On a phone a table that still does not fit scrolls, and its hidden edge fades. Click a header to sort within each group; missing values stay last. XAUUSD shows the selected row.
Controls
A page's controls sit in the header's title row; a section's on its head's right.
ui/button.tsx · segmented-control.tsx · picker.tsx · search-input.tsx · switch-field.tsx · info-tip.tsx, on shadcn toggle-group, dropdown-menu, input-group, kbd, switch, label, tooltip
Buttons
Segmented control
Picker menu
Search
Toggle
Tooltip and focus ring
Loading, empty and error
Skeletons shaped like the content, never spinners; empty and error say what happened and what to do.
table-skeleton.tsx · status-panel.tsx, on shadcn skeleton and empty
No releases match
No high importance releases for the selected countries this week.
Could not load COT history
The request timed out. The table still shows the 20 Oct report.
Motion
Subtle and purposeful: panels and menus open and close, loading and streaming show they are working. Nothing decorative, nothing that delays reading data; reduced motion turns it all off.
src/app/globals.css · ui/popover, dropdown-menu, tooltip, sheet, skeleton · sidebar.tsx · page-tabs.tsx · ask-panel.tsx
One-shot, on change
- animate-pop-in150ms ease-out · Menus, popovers, tooltips open; 4px from the trigger's side
- animate-pop-out120ms ease-in · Menus and popovers close
- animate-fade-in150ms ease-out · Ask's Latest button
- animate-fade-out120ms ease-in · Tooltips close
- animate-rise-in200ms ease-out · A new question, Thinking and an error in Ask
- animate-slide-in-right240ms ease-standard · Ask panel opens, 768px and up
- animate-slide-out-right200ms ease-in · Ask panel closes, 768px and up
- animate-slide-in-up250ms ease-standard · Ask panel opens on a phone
- animate-slide-out-down200ms ease-in · Ask panel closes on a phone
- animate-slide-in-left240ms ease-standard · Sidebar opens over the page, below 1180px
Loops, while something loads or streams
Transitions, 200ms ease-standard
Hover and press colors; the sidebar's width as it collapses; a sidebar family's height as it opens (expandable, where the browser can animate to auto); the page column's margin as Ask docks (240ms); a tab's underline growing from its middle.