One system for reading risk at a glance.
Journal Trading is a trading journal, KPI dashboard and strategy backtester used during live sessions — often for hours at a stretch, often beside a live chart. This system optimizes for high data density, low chrome, fast P&L legibility and a calm dark-first surface that doesn't fight for attention against the charts it frames.
Principles
Dark is the working surface
Like Bloomberg Terminal, TradingView and most execution platforms, dark mode is the default — it reduces eye strain across long sessions and lets P&L color (green/red) read with more contrast than on white. Light mode is a fully-supported alternative, never an afterthought, but every density and contrast decision is tuned for dark first.
Color is never the only signal
Gains and losses always carry a sign (+/−) and, where relevant, an icon or direction arrow in addition to color. Roughly 1 in 12 men are colorblind to red/green — the exact pair this domain leans on hardest — so color is decoration on top of a legible number, never the message itself.
Numbers align, always
Every price, percentage, P&L and metric uses tabular figures (IBM Plex Mono) so columns of numbers line up vertically and can be scanned, not read. Prose stays in the humanist sans.
Chrome recedes, data leads
Borders are hairlines, shadows are shallow, and brand color is spent on one primary action per view. The interface is a frame for charts and numbers, not a second thing competing with them.
Color
2.1Brand primitives
Sourced directly from the Journal Trading mark (Journal.svg): deep navy as the grounding surface, its exact 246.81° gradient — #009AC8 to #1BB980 — as the single primary action color, and magenta reserved exclusively for AI/Coach surfaces so assistant content is always identifiable at a glance.
2.2P&L & status — fixed, validated, never themed
The good/critical pair below is run through automated CVD (color-vision-deficiency) simulation — deuteranopia and protanopia — and passes adjacent-pair separation in both light and dark. These four hexes are constants: they never shift with brand theming and are never reassigned to a chart series.
Status colors ship with an icon and/or label — never color alone — per §7 Accessibility.
2.3Chart categorical palette
For multi-strategy comparison, equity curves and backtest overlays. Order is the safety mechanism: hues are assigned in this fixed sequence and never cycled or reassigned when a filter changes the series count — validated against both light and dark chart surfaces with worst-adjacent-pair ΔE ≥ 8 (OKLab). Scatter/bubble/small-multiple forms that show all pairs at once are capped at the first 3 slots.
2.4Neutrals & ink
| Token | Role | Light | Dark |
|---|---|---|---|
| --bg-primary | App background | #ECF1FC | #08111C |
| --bg-surface | Card / panel | #FFFFFF | #0F1C2C |
| --text-primary | Headings, values | #0E1620 | #EEF3F9 |
| --text-secondary | Body copy | #33404E | #B9C6D4 |
| --text-muted | Labels, axis ticks | #5C6B7A | #7E8FA0 |
| --border-hairline | Dividers, card borders | #D6DEE6 | #1E3247 |
Typography
IBM Plex Sans for interface text — a humanist grotesque with real character that avoids the "safe default" faces (Inter, Space Grotesk) common to templated fintech UI. IBM Plex Mono for every number, ticker, price and code value — its terminal lineage suits a product built around reading figures fast.
Spacing & grid
4px base unit. Layout gaps and paddings are drawn only from this scale — never arbitrary values.
Dashboard grid: 12 columns, 24px gutter, 1280px content max-width, 16px page margin on mobile. Widgets snap to a 4×4 minimum cell.
Elevation & radius
Radius: 6px controls, 10px cards, 12px chat bubbles and modals, 100px pills. Shadows stay shallow — density is expressed with hairline borders (1px, --border-hairline) before reaching for elevation.
Motion
| Token | Duration | Easing | Used for |
|---|---|---|---|
| --dur-instant | 80ms | ease-out | Hover, focus rings, button press |
| --dur-fast | 150ms | ease-out | Tab switch, tooltip, badge state |
| --dur-base | 220ms | cubic-bezier(.2,.8,.2,1) | Panel open/close, dropdown |
| --dur-slow | 360ms | cubic-bezier(.2,.8,.2,1) | Modal, drawer |
Live data (price ticks, KPI updates) never animates position or triggers layout shift — only the value and a brief color flash (120ms) on the cell background communicate the change. Chart redraws crossfade, they never jump-cut. All motion respects prefers-reduced-motion.
Forms & inputs
Checkbox, radio and switch all fill with --brand-gradient-ui when active — never the blue that browser default styling reaches for. accent-color can't express a gradient, so these are custom-built controls, not native styling.
Badges & status
KPI tiles
The primary dashboard unit. Value first, delta second, trend third — in that visual weight order. Every P&L value carries an explicit sign.
Data tables
Tables sit on a fixed white surface (--table-bg) in both themes — the one deliberate exception to the dark-first rule — so a dense grid of numbers stands apart from the navy app chrome, the same way the source product's trade cards do. Rows highlight on hover with a brand-cyan wash; the header stays pinned while the body scrolls. Monospace tabular figures right-aligned, colored P&L with an explicit sign.
| Date | Symbol | Side | Entry | Exit | P&L | Result |
|---|---|---|---|---|---|---|
| 09/24 | ES | Long | 5721.25 | 5734.50 | +$662.50 | Win |
| 09/24 | NQ | Short | 19842.00 | 19861.75 | −$395.00 | Loss |
| 09/23 | EURUSD | Long | 1.0842 | 1.0842 | $0.00 | BE |
Calendar heatmap
Daily P&L calendar — a signature Journal Trading pattern. Intensity is fixed per state (win/loss/flat), not scaled by magnitude, so the grid stays scannable rather than turning into a second heatmap encoding.
Modals & toasts
Delete strategy "ORB v3"?
This removes 340 linked backtest runs. Trade journal entries are kept.
Chart color system
All charting is rendered by TradingView (the Advanced Chart / Lightweight Charts widget), not built from scratch — so the chart canvas keeps TradingView's own dark theme rather than being re-skinned into the app's surfaces. Two of TradingView's defaults are overridden at the widget config level: candle up/down colors are mapped to the app's own validated P&L pair, not TradingView's stock teal/red, so green and red mean the same thing on a candle as they do on a KPI tile.
Candlesticks & P&L
Bull/bear candles and every P&L delta use the fixed status pair (§2.2) — never the categorical palette, so a chart's directional read never collides with a strategy-comparison read.
Equity curves & overlays
Multi-strategy overlays draw from the 8-slot categorical order (§2.3), always in the same sequence regardless of which strategies are toggled on.
Chart anatomy — TradingView candles
The primary chart surface, styled to match the embedded TradingView widget: dark canvas regardless of app theme, price axis on the right, time axis on the bottom, an OHLC legend that updates on hover, and a crosshair with axis-anchored value labels.
Thin candle bodies with 1.5px wicks, a muted grid (--tv-grid) that never competes with price action, a right-anchored price tag on the crosshair, and a volume subpanel at 55% opacity. Colors come from the app's own --status-good / --status-critical pair, not TradingView's stock palette.
Pattern — Dashboard layout
Summary before detail: KPI row on top, charts and recent activity below. Nothing requires a scroll to answer "how am I doing."
Pattern — Backtesting results
Backtest output pairs a compact metrics table with the equity curve and trade distribution, so statistical performance (Sharpe, expectancy, max DD) sits next to its visual shape rather than in a separate tab.
| Total trades | 1,204 |
| Win rate | 57.3% |
| Profit factor | 1.84 |
| Sharpe ratio | 1.42 |
| Max drawdown | −8.2% |
| Expectancy / trade | +$34.90 |
Pattern — AI Coach chatbox
Magenta is used nowhere else in the system, so any assistant-authored content — the tag, the accent — is identifiable at a glance as AI, not human-entered journal content. Structured findings (a scored trade, a stat) render as a data card inside the bubble rather than prose alone.
Accessibility
Density vs. the 16px web default
Trading UIs run smaller than typical web guidance recommends — 11–13.5px is standard across TradingView, Bloomberg and most order tickets, because the job is scanning dozens of rows and price levels on one screen, not reading prose. This system keeps that convention but sets a hard floor: nothing ships below 11px, anything under 13px carries at least medium weight (600) to hold its shape at size, line-height stays ≥1.5 even in tables, and every size is a token on a rem-based scale so a viewer's browser zoom still works normally. What it doesn't do is chase the 16px body-text guideline literally — the trade-off is deliberate, and contrast and weight do the compensating instead of size.
Contrast
Body text ≥ 4.5:1, UI labels and icons ≥ 3:1 against their surface in both themes. Status colors below 3:1 on light (warning, serious) always ship with an icon + text label as relief. Filled buttons are checked at both ends of the gradient, not just the midpoint — see §7.
Color-vision deficiency
The P&L pair and the 8-slot categorical palette are validated by simulation (deuteranopia, protanopia, tritanopia). Sign (+/−) and position are always secondary encodings alongside color.
Keyboard & focus
Every interactive element has a visible 2px focus ring (--focus-ring). The command palette, table rows and chat input are fully keyboard-navigable.
Motion
prefers-reduced-motion disables crossfades and micro-interactions; live-data flashes and chart draws fall back to instant updates.