chart/docs/plan_light_dark_themes.md

126 lines
4.6 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Light and dark themes
**Status: tracked, not started.** A direction to refactor toward, not a project
with a date. Recorded 2026-08-14 from a contrast pass over the colours that
are actually in the tree.
The page is a warm paper theme. A dark theme that just inverts it will look
broken. Chrome is cheap. The chart colours were picked for cream, and many
of them are stored as hex on drawings, so a CSS flip does not restyle lines
already placed.
## What is already factored
`:root` in `static/style.css` owns the chrome:
```css
:root {
color-scheme: light;
--bg: #e8dfcf;
--panel: #f7f1e6;
--chart-bg: #fbf7ef;
--fg: #2c2924;
--muted: #746c60;
--line: #d2c5b2;
--accent: #b7771d;
--green: #27825c;
--red: #bd4545;
}
```
Lightweight Charts already reads `--chart-bg` and `--muted` at `create()`.
Sidebar, comments, tooltips and most chrome follow the tokens. Flipping
those variables restyles the frame. It does not restyle the series.
## What is hardcoded for cream paper
**Candles** — `#20b8a6` / `#ef5b3f` with borders and wicks `#087f76` /
`#b9342d`. Mid-luminance, already the usual trading pair. Fine on dark.
**Timeframe and kind colours** (`ConfluenceChart.tfColors`,
`kindColors`, and the layer swatches):
| Role | Hex | On dark |
|---|---|---|
| 1m | `#82909f` | usable |
| 5m / manual | `#65b7cf` | fine |
| 1h | `#efb643` | fine |
| 1d MA | `#d96073` | fine |
| VWAP | `#b07ad6` | fine |
| prior-day H/L/C | `#9fb0c4` | fine |
**Grid** — `rgba(128,128,128,.10)`. Invisible on a dark plot. Needs a
higher alpha, or a token.
**Accent** — `#b7771d` is a mid amber. On cream it reads as gold. On dark
it goes muddy/brown. Dark chrome wants a brighter accent, not the same hex.
**Price tag** — `#e0a34a` on `#1a1206`. Fine on both.
**Snap support/resistance** — `#27825c` / `#bd4545`. Fine.
**Current-price pulse** — `color-mix(..., var(--accent), white)`. On dark,
mix toward the chart background or a lighter accent, not white.
**Shadows** — `rgba(0,0,0,.16)`. Vanish on dark. Drop them or invert.
**`button.active`** — `color: var(--bg)` on `background: var(--accent)`.
Survives a token flip (dark text on gold instead of cream text on gold).
## The drawing palette is the real problem
Four stops per family, named `green1`–`green4` and so on, persisted as hex
on each drawing:
| | 1 (pastel) | 2 | 3 | 4 (dark) |
|---|---|---|---|---|
| green | `#A6D8AA` | `#4DB155` | `#258F33` | `#006D09` |
| red | `#FAADBC` | `#F45B78` | `#D13F62` | `#AF2850` |
| blue | `#A3CCFF` | `#4699FE` | `#1E76D8` | `#0054B3` |
| orange | `#F8C592` | `#F08A24` | `#D66B12` | `#B94E08` |
| teal | `#80D8D8` | `#00B0B1` | `#008E8F` | `#006C6E` |
| purple | `#DDBCEB` | `#BB79D7` | `#9858B3` | `#763790` |
Stop 1 pops on dark and fades into cream. Stop 4 reads on cream and
disappears on dark. A theme switch does not rewrite stored `#006D09`
lines. Invert-and-ship leaves those lines looking like they vanished.
## Colours that work on both
Stay in the middle of each row. Mid-luminance, reasonably saturated hues
contrast with both `#fbf7ef` and a warm dark plot (roughly OKLCH lightness
0.55–0.70). That is why the candles already work, and why stops 2–3 work:
`#4DB155` `#F45B78` `#4699FE` `#F08A24` `#00B0B1` `#BB79D7`
You cannot keep a four-stop range that is readable on both backgrounds.
Two ways out, pick one when this is built:
1. **Store the name, resolve the hex.** The labels already exist
(`green2`). Light and dark each map the name to a hex. Identity
survives; appearance follows the theme. New drawings and a one-shot
migration of known palette hexes onto names. Custom hexes stay hexes.
2. **A 1px opposite-luma hairline** on every series. The fill can then be
anything, including saved `#006D09`. Escape hatch for lines that never
get a name.
Do not invent a third palette that claims all eight extremes work on both.
They do not.
## What a dark theme is, and is not
It is a contrast pass: chrome tokens, grid alpha, accent, pulse mix,
shadows, and a decision about named vs hex drawings. It is not a
restyle of the product and not a reason to rebuild the chart.
Do not invert the cream hexes and ship. Do not delete stop 1 and stop 4
from the picker without deciding how existing drawings render. Do not
treat `prefers-color-scheme` as enough on its own — this is a trading
desk, not a marketing page; the choice has to be sticky and explicit,
with the system preference as a default only.
## When this is built
Change `docs/plan.md` in the same commit if any colour table or “paper
theme” description becomes false. This file then records the reasoning,
not the live tokens.