chart/docs/plan_light_dark_themes.md

4.6 KiB
Raw Permalink Blame History

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:

: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.