@363045841yyt/klinechart-core 0.7.5 → 0.7.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (235) hide show
  1. package/README.md +8 -8
  2. package/README.zh-CN.md +8 -8
  3. package/dist/config/chartSettings.d.ts +27 -2
  4. package/dist/config/chartSettings.d.ts.map +1 -1
  5. package/dist/config/chartSettings.js +6 -0
  6. package/dist/config/chartSettings.js.map +1 -1
  7. package/dist/controllers/createChartController.d.ts.map +1 -1
  8. package/dist/controllers/createChartController.js +145 -21
  9. package/dist/controllers/createChartController.js.map +1 -1
  10. package/dist/controllers/index.d.ts +9 -1
  11. package/dist/controllers/index.d.ts.map +1 -1
  12. package/dist/controllers/index.js +9 -0
  13. package/dist/controllers/index.js.map +1 -1
  14. package/dist/controllers/types.d.ts +65 -8
  15. package/dist/controllers/types.d.ts.map +1 -1
  16. package/dist/engine/chart.d.ts +2 -12
  17. package/dist/engine/chart.d.ts.map +1 -1
  18. package/dist/engine/chart.js +32 -31
  19. package/dist/engine/chart.js.map +1 -1
  20. package/dist/engine/controller/interaction.d.ts +1 -1
  21. package/dist/engine/controller/interaction.d.ts.map +1 -1
  22. package/dist/engine/controller/interaction.js +10 -2
  23. package/dist/engine/controller/interaction.js.map +1 -1
  24. package/dist/engine/draw/pixelAlign.d.ts.map +1 -1
  25. package/dist/engine/draw/pixelAlign.js.map +1 -1
  26. package/dist/engine/drawing/interaction.d.ts +3 -3
  27. package/dist/engine/drawing/interaction.d.ts.map +1 -1
  28. package/dist/engine/drawing/interaction.js +38 -46
  29. package/dist/engine/drawing/interaction.js.map +1 -1
  30. package/dist/engine/drawing/plugin.js +1 -1
  31. package/dist/engine/drawing/plugin.js.map +1 -1
  32. package/dist/engine/renderers/Indicator/atr.d.ts.map +1 -1
  33. package/dist/engine/renderers/Indicator/atr.js +7 -4
  34. package/dist/engine/renderers/Indicator/atr.js.map +1 -1
  35. package/dist/engine/renderers/Indicator/boll.js +12 -12
  36. package/dist/engine/renderers/Indicator/boll.js.map +1 -1
  37. package/dist/engine/renderers/Indicator/cci.d.ts +1 -2
  38. package/dist/engine/renderers/Indicator/cci.d.ts.map +1 -1
  39. package/dist/engine/renderers/Indicator/cci.js +9 -9
  40. package/dist/engine/renderers/Indicator/cci.js.map +1 -1
  41. package/dist/engine/renderers/Indicator/ene.js +12 -12
  42. package/dist/engine/renderers/Indicator/ene.js.map +1 -1
  43. package/dist/engine/renderers/Indicator/expma.js +6 -6
  44. package/dist/engine/renderers/Indicator/expma.js.map +1 -1
  45. package/dist/engine/renderers/Indicator/fastk.d.ts +1 -2
  46. package/dist/engine/renderers/Indicator/fastk.d.ts.map +1 -1
  47. package/dist/engine/renderers/Indicator/fastk.js +7 -7
  48. package/dist/engine/renderers/Indicator/fastk.js.map +1 -1
  49. package/dist/engine/renderers/Indicator/kst.d.ts +1 -2
  50. package/dist/engine/renderers/Indicator/kst.d.ts.map +1 -1
  51. package/dist/engine/renderers/Indicator/kst.js +10 -10
  52. package/dist/engine/renderers/Indicator/kst.js.map +1 -1
  53. package/dist/engine/renderers/Indicator/ma.js +5 -5
  54. package/dist/engine/renderers/Indicator/ma.js.map +1 -1
  55. package/dist/engine/renderers/Indicator/macd.d.ts +1 -2
  56. package/dist/engine/renderers/Indicator/macd.d.ts.map +1 -1
  57. package/dist/engine/renderers/Indicator/macd.js +24 -24
  58. package/dist/engine/renderers/Indicator/macd.js.map +1 -1
  59. package/dist/engine/renderers/Indicator/macdLegend.js +6 -6
  60. package/dist/engine/renderers/Indicator/macdLegend.js.map +1 -1
  61. package/dist/engine/renderers/Indicator/mainIndicatorLegend.js +16 -16
  62. package/dist/engine/renderers/Indicator/mainIndicatorLegend.js.map +1 -1
  63. package/dist/engine/renderers/Indicator/mom.d.ts +1 -2
  64. package/dist/engine/renderers/Indicator/mom.d.ts.map +1 -1
  65. package/dist/engine/renderers/Indicator/mom.js +8 -8
  66. package/dist/engine/renderers/Indicator/mom.js.map +1 -1
  67. package/dist/engine/renderers/Indicator/rsi.d.ts +2 -3
  68. package/dist/engine/renderers/Indicator/rsi.d.ts.map +1 -1
  69. package/dist/engine/renderers/Indicator/rsi.js +15 -15
  70. package/dist/engine/renderers/Indicator/rsi.js.map +1 -1
  71. package/dist/engine/renderers/Indicator/scale/indicator_scale.d.ts +1 -2
  72. package/dist/engine/renderers/Indicator/scale/indicator_scale.d.ts.map +1 -1
  73. package/dist/engine/renderers/Indicator/scale/indicator_scale.js +5 -5
  74. package/dist/engine/renderers/Indicator/scale/indicator_scale.js.map +1 -1
  75. package/dist/engine/renderers/Indicator/stoch.d.ts +1 -2
  76. package/dist/engine/renderers/Indicator/stoch.d.ts.map +1 -1
  77. package/dist/engine/renderers/Indicator/stoch.js +10 -10
  78. package/dist/engine/renderers/Indicator/stoch.js.map +1 -1
  79. package/dist/engine/renderers/Indicator/structure.js +5 -5
  80. package/dist/engine/renderers/Indicator/structure.js.map +1 -1
  81. package/dist/engine/renderers/Indicator/wmsr.d.ts +1 -2
  82. package/dist/engine/renderers/Indicator/wmsr.d.ts.map +1 -1
  83. package/dist/engine/renderers/Indicator/wmsr.js +10 -10
  84. package/dist/engine/renderers/Indicator/wmsr.js.map +1 -1
  85. package/dist/engine/renderers/Indicator/zones.js +6 -6
  86. package/dist/engine/renderers/Indicator/zones.js.map +1 -1
  87. package/dist/engine/renderers/candle.d.ts +1 -1
  88. package/dist/engine/renderers/candle.d.ts.map +1 -1
  89. package/dist/engine/renderers/candle.js +21 -21
  90. package/dist/engine/renderers/candle.js.map +1 -1
  91. package/dist/engine/renderers/crosshair.js +3 -3
  92. package/dist/engine/renderers/crosshair.js.map +1 -1
  93. package/dist/engine/renderers/extremaMarkers.d.ts.map +1 -1
  94. package/dist/engine/renderers/extremaMarkers.js +12 -12
  95. package/dist/engine/renderers/extremaMarkers.js.map +1 -1
  96. package/dist/engine/renderers/gridLines.js +3 -3
  97. package/dist/engine/renderers/gridLines.js.map +1 -1
  98. package/dist/engine/renderers/lastPrice.js +7 -7
  99. package/dist/engine/renderers/lastPrice.js.map +1 -1
  100. package/dist/engine/renderers/paneTitle.d.ts +5 -24
  101. package/dist/engine/renderers/paneTitle.d.ts.map +1 -1
  102. package/dist/engine/renderers/paneTitle.js +16 -11
  103. package/dist/engine/renderers/paneTitle.js.map +1 -1
  104. package/dist/engine/renderers/subVolume.d.ts.map +1 -1
  105. package/dist/engine/renderers/subVolume.js +23 -20
  106. package/dist/engine/renderers/subVolume.js.map +1 -1
  107. package/dist/engine/renderers/timeAxis.js +9 -9
  108. package/dist/engine/renderers/timeAxis.js.map +1 -1
  109. package/dist/engine/renderers/webgl/candleSurface.d.ts +4 -4
  110. package/dist/engine/renderers/webgl/candleSurface.d.ts.map +1 -1
  111. package/dist/engine/renderers/webgl/candleSurface.js +72 -60
  112. package/dist/engine/renderers/webgl/candleSurface.js.map +1 -1
  113. package/dist/engine/renderers/yAxis.d.ts.map +1 -1
  114. package/dist/engine/renderers/yAxis.js +5 -5
  115. package/dist/engine/renderers/yAxis.js.map +1 -1
  116. package/dist/engine/subPaneManager.d.ts +2 -0
  117. package/dist/engine/subPaneManager.d.ts.map +1 -1
  118. package/dist/engine/subPaneManager.js +25 -1
  119. package/dist/engine/subPaneManager.js.map +1 -1
  120. package/dist/index.d.ts +1 -0
  121. package/dist/index.d.ts.map +1 -1
  122. package/dist/index.js +1 -0
  123. package/dist/index.js.map +1 -1
  124. package/dist/plugin/types.d.ts +5 -1
  125. package/dist/plugin/types.d.ts.map +1 -1
  126. package/dist/plugin/types.js.map +1 -1
  127. package/dist/semantic/controller.d.ts +1 -2
  128. package/dist/semantic/controller.d.ts.map +1 -1
  129. package/dist/semantic/index.d.ts +1 -1
  130. package/dist/semantic/index.d.ts.map +1 -1
  131. package/dist/tokens/colorPresetSettings.d.ts +15 -0
  132. package/dist/tokens/colorPresetSettings.d.ts.map +1 -0
  133. package/dist/tokens/colorPresetSettings.js +65 -0
  134. package/dist/tokens/colorPresetSettings.js.map +1 -0
  135. package/dist/tokens/index.d.ts +17 -0
  136. package/dist/tokens/index.d.ts.map +1 -0
  137. package/dist/tokens/index.js +16 -0
  138. package/dist/tokens/index.js.map +1 -0
  139. package/dist/tokens/mergeTheme.d.ts +17 -0
  140. package/dist/tokens/mergeTheme.d.ts.map +1 -0
  141. package/dist/tokens/mergeTheme.js +43 -0
  142. package/dist/tokens/mergeTheme.js.map +1 -0
  143. package/dist/tokens/theme-china.d.ts +45 -0
  144. package/dist/tokens/theme-china.d.ts.map +1 -0
  145. package/dist/tokens/theme-china.js +116 -0
  146. package/dist/tokens/theme-china.js.map +1 -0
  147. package/dist/tokens/theme-dark.d.ts +21 -0
  148. package/dist/tokens/theme-dark.d.ts.map +1 -0
  149. package/dist/tokens/theme-dark.js +228 -0
  150. package/dist/tokens/theme-dark.js.map +1 -0
  151. package/dist/tokens/theme-light.d.ts +23 -0
  152. package/dist/tokens/theme-light.d.ts.map +1 -0
  153. package/dist/tokens/theme-light.js +234 -0
  154. package/dist/tokens/theme-light.js.map +1 -0
  155. package/dist/tokens/themeToCssVars.d.ts +74 -0
  156. package/dist/tokens/themeToCssVars.d.ts.map +1 -0
  157. package/dist/tokens/themeToCssVars.js +108 -0
  158. package/dist/tokens/themeToCssVars.js.map +1 -0
  159. package/dist/tokens/types.d.ts +335 -0
  160. package/dist/tokens/types.d.ts.map +1 -0
  161. package/dist/tokens/types.js +20 -0
  162. package/dist/tokens/types.js.map +1 -0
  163. package/dist/utils/kLineDraw/axis.d.ts +8 -7
  164. package/dist/utils/kLineDraw/axis.d.ts.map +1 -1
  165. package/dist/utils/kLineDraw/axis.js +24 -24
  166. package/dist/utils/kLineDraw/axis.js.map +1 -1
  167. package/dist/version.d.ts +1 -1
  168. package/dist/version.js +1 -1
  169. package/package.json +6 -6
  170. package/src/config/chartSettings.ts +11 -2
  171. package/src/controllers/createChartController.ts +158 -29
  172. package/src/controllers/index.ts +33 -0
  173. package/src/controllers/types.ts +79 -8
  174. package/src/engine/chart.ts +32 -37
  175. package/src/engine/controller/interaction.ts +9 -2
  176. package/src/engine/draw/pixelAlign.ts +0 -2
  177. package/src/engine/drawing/interaction.ts +38 -47
  178. package/src/engine/drawing/plugin.ts +1 -1
  179. package/src/engine/renderers/Indicator/atr.ts +7 -3
  180. package/src/engine/renderers/Indicator/boll.ts +12 -12
  181. package/src/engine/renderers/Indicator/cci.ts +11 -10
  182. package/src/engine/renderers/Indicator/ene.ts +12 -12
  183. package/src/engine/renderers/Indicator/expma.ts +6 -6
  184. package/src/engine/renderers/Indicator/fastk.ts +9 -8
  185. package/src/engine/renderers/Indicator/kst.ts +12 -11
  186. package/src/engine/renderers/Indicator/ma.ts +5 -5
  187. package/src/engine/renderers/Indicator/macd.ts +27 -25
  188. package/src/engine/renderers/Indicator/macdLegend.ts +6 -6
  189. package/src/engine/renderers/Indicator/mainIndicatorLegend.ts +16 -16
  190. package/src/engine/renderers/Indicator/mom.ts +11 -10
  191. package/src/engine/renderers/Indicator/rsi.ts +18 -15
  192. package/src/engine/renderers/Indicator/scale/indicator_scale.ts +6 -6
  193. package/src/engine/renderers/Indicator/stoch.ts +12 -11
  194. package/src/engine/renderers/Indicator/structure.ts +5 -5
  195. package/src/engine/renderers/Indicator/wmsr.ts +13 -12
  196. package/src/engine/renderers/Indicator/zones.ts +7 -7
  197. package/src/engine/renderers/candle.ts +21 -21
  198. package/src/engine/renderers/crosshair.ts +3 -3
  199. package/src/engine/renderers/extremaMarkers.ts +13 -12
  200. package/src/engine/renderers/gridLines.ts +3 -3
  201. package/src/engine/renderers/lastPrice.ts +7 -7
  202. package/src/engine/renderers/paneTitle.ts +22 -31
  203. package/src/engine/renderers/subVolume.ts +23 -20
  204. package/src/engine/renderers/timeAxis.ts +9 -9
  205. package/src/engine/renderers/webgl/candleSurface.ts +80 -60
  206. package/src/engine/renderers/yAxis.ts +6 -5
  207. package/src/engine/subPaneManager.ts +28 -1
  208. package/src/index.ts +1 -0
  209. package/src/plugin/types.ts +5 -1
  210. package/src/semantic/controller.ts +1 -1
  211. package/src/semantic/index.ts +1 -1
  212. package/src/tokens/__tests__/__snapshots__/baseline.test.ts.snap +393 -0
  213. package/src/tokens/__tests__/baseline.test.ts +183 -0
  214. package/src/tokens/__tests__/themeToCssVars.test.ts +175 -0
  215. package/src/tokens/__tests__/tokens.test.ts +215 -0
  216. package/src/tokens/colorPresetSettings.ts +128 -0
  217. package/src/tokens/index.ts +65 -0
  218. package/src/tokens/mergeTheme.ts +48 -0
  219. package/src/tokens/theme-china.ts +132 -0
  220. package/src/tokens/theme-dark.ts +244 -0
  221. package/src/tokens/theme-light.ts +250 -0
  222. package/src/tokens/themeToCssVars.ts +138 -0
  223. package/src/tokens/types.ts +394 -0
  224. package/src/utils/kLineDraw/axis.ts +31 -30
  225. package/src/version.ts +1 -1
  226. package/dist/engine/chart-store.d.ts +0 -75
  227. package/dist/engine/chart-store.d.ts.map +0 -1
  228. package/dist/engine/chart-store.js +0 -88
  229. package/dist/engine/chart-store.js.map +0 -1
  230. package/dist/engine/theme/colors.d.ts +0 -223
  231. package/dist/engine/theme/colors.d.ts.map +0 -1
  232. package/dist/engine/theme/colors.js +0 -375
  233. package/dist/engine/theme/colors.js.map +0 -1
  234. package/src/engine/chart-store.ts +0 -121
  235. package/src/engine/theme/colors.ts +0 -642
@@ -0,0 +1,132 @@
1
+ /**
2
+ * Asia-market (Chinese) colour convention helper.
3
+ *
4
+ * Asian markets traditionally use **red for "up"** (bull) and **green
5
+ * for "down"** (bear) — the reverse of the Western convention.
6
+ *
7
+ * {@link withAsiaMarketColors} takes any {@link Theme} and returns a new
8
+ * Theme with all bull/bear colour pairs swapped, so the caller only needs
9
+ * a single boolean (`isAsiaMarket`) to switch conventions at runtime.
10
+ *
11
+ * {@link resolveThemeColors} is a convenience for renderers that currently
12
+ * hard-code `theme === 'dark' ? darkTheme.colors : lightTheme.colors`.
13
+ *
14
+ * Usage:
15
+ * ```ts
16
+ * import { resolveThemeColors } from '../../tokens'
17
+ *
18
+ * const colors = resolveThemeColors(context.theme, context.isAsiaMarket)
19
+ * ```
20
+ */
21
+
22
+ import type { ColorTokens, Theme } from './types'
23
+ import { lightTheme } from './theme-light'
24
+ import { darkTheme } from './theme-dark'
25
+ import { applyColorPresetOverrides, type ColorPresetSettings } from './colorPresetSettings'
26
+
27
+ /**
28
+ * Swap all bull/bear colour pairs in a Theme so that "up" (bull) uses
29
+ * the formerly "down" (bear) colour and vice versa.
30
+ *
31
+ * @param theme — the base Theme (Western convention)
32
+ * @returns a **new** Theme object; the original is not mutated.
33
+ */
34
+ export function withAsiaMarketColors(theme: Theme): Theme {
35
+ return {
36
+ ...theme,
37
+ colors: {
38
+ ...theme.colors,
39
+
40
+ // ── Candle / OHLC ──
41
+ candleUpBody: theme.colors.candleDownBody,
42
+ candleDownBody: theme.colors.candleUpBody,
43
+ candleUpBorder: theme.colors.candleDownBorder,
44
+ candleDownBorder: theme.colors.candleUpBorder,
45
+ candleUpWick: theme.colors.candleDownWick,
46
+ candleDownWick: theme.colors.candleUpWick,
47
+
48
+ // ── Volume bars ──
49
+ volumeUp: theme.colors.volumeDown,
50
+ volumeDown: theme.colors.volumeUp,
51
+
52
+ // ── Footprint (ask = buy = bull, bid = sell = bear) ──
53
+ footprintAsk: theme.colors.footprintBid,
54
+ footprintBid: theme.colors.footprintAsk,
55
+
56
+ // ── Nested: price accents ──
57
+ price: {
58
+ ...theme.colors.price,
59
+ upLight: theme.colors.price.downLight,
60
+ downLight: theme.colors.price.upLight,
61
+ upTick: theme.colors.price.downTick,
62
+ downTick: theme.colors.price.upTick,
63
+ },
64
+
65
+ // ── Nested: MACD histogram bars ──
66
+ macd: {
67
+ ...theme.colors.macd,
68
+ barUp: theme.colors.macd.barDown,
69
+ barDown: theme.colors.macd.barUp,
70
+ barUpLight: theme.colors.macd.barDownLight,
71
+ barDownLight: theme.colors.macd.barUpLight,
72
+ },
73
+
74
+ // ── Nested: SMC structure (HH/HL = bull, LH/LL = bear) ──
75
+ structure: {
76
+ ...theme.colors.structure,
77
+ hh: theme.colors.structure.ll,
78
+ ll: theme.colors.structure.hh,
79
+ hl: theme.colors.structure.lh,
80
+ lh: theme.colors.structure.hl,
81
+ },
82
+
83
+ // ── Nested: Zones / FVG / Order Block ──
84
+ zones: {
85
+ ...theme.colors.zones,
86
+ fvgBullFill: theme.colors.zones.fvgBearFill,
87
+ fvgBearFill: theme.colors.zones.fvgBullFill,
88
+ fvgBullBorder: theme.colors.zones.fvgBearBorder,
89
+ fvgBearBorder: theme.colors.zones.fvgBullBorder,
90
+ obBullFill: theme.colors.zones.obBearFill,
91
+ obBearFill: theme.colors.zones.obBullFill,
92
+ },
93
+
94
+ // ── Nested: CCI overbought (bull) / oversold (bear) ──
95
+ cci: {
96
+ ...theme.colors.cci,
97
+ overbought: theme.colors.cci.oversold,
98
+ oversold: theme.colors.cci.overbought,
99
+ },
100
+
101
+ // ── Nested: WMSR overbought / oversold ──
102
+ wmsr: {
103
+ ...theme.colors.wmsr,
104
+ overbought: theme.colors.wmsr.oversold,
105
+ oversold: theme.colors.wmsr.overbought,
106
+ },
107
+ },
108
+ }
109
+ }
110
+
111
+ /**
112
+ * Resolve a theme name + optional Asia-market flag into concrete
113
+ * {@link ColorTokens}.
114
+ *
115
+ * Renderers replace this pattern:
116
+ * ```ts
117
+ * const colors = theme === 'dark' ? darkTheme.colors : lightTheme.colors
118
+ * ```
119
+ * with:
120
+ * ```ts
121
+ * const colors = resolveThemeColors(theme, isAsiaMarket)
122
+ * ```
123
+ */
124
+ export function resolveThemeColors(
125
+ themeName: 'light' | 'dark',
126
+ isAsiaMarket?: boolean,
127
+ colorPresetSettings?: ColorPresetSettings,
128
+ ): ColorTokens {
129
+ const base = themeName === 'dark' ? darkTheme : lightTheme
130
+ const active = isAsiaMarket ? withAsiaMarketColors(base) : base
131
+ return applyColorPresetOverrides(active.colors, themeName, colorPresetSettings)
132
+ }
@@ -0,0 +1,244 @@
1
+ /**
2
+ * Dark theme — paired with {@link lightTheme}.
3
+ *
4
+ * Color choices:
5
+ *
6
+ * - Background = #0E1116 (deep but not pure black — pure black creates
7
+ * halation around bright lines on OLED).
8
+ * - Bull = brighter green (#22D69B) — needed on dark background for
9
+ * 7.5:1 contrast (passes WCAG AAA for non-text).
10
+ * - Bear = brighter red (#FF6464) — 6.2:1 contrast.
11
+ * - Grid is barely visible (1.2:1 over background) so it never competes
12
+ * with the data.
13
+ * - Indicator palette is the same Okabe-Ito set but with the few hues
14
+ * that need a brightness bump on dark background pre-tuned.
15
+ *
16
+ * Same shape as light — only values change. The parity test in
17
+ * `__tests__/themes.test.ts` enforces this.
18
+ */
19
+
20
+ import type { Theme } from './types'
21
+
22
+ export const darkTheme: Theme = {
23
+ name: 'dark',
24
+ colors: {
25
+ background: '#111827',
26
+ foreground: '#E8EAED',
27
+ chartBackground: '#111827',
28
+
29
+ candleUpBody: '#22D69B',
30
+ candleUpBorder: '#22D69B',
31
+ candleUpWick: '#22D69B',
32
+ candleDownBody: '#FF6464',
33
+ candleDownBorder: '#FF6464',
34
+ candleDownWick: '#FF6464',
35
+ candleDojiBorder: '#8A8F98',
36
+
37
+ volumeUp: '#22D69B66',
38
+ volumeDown: '#FF646466',
39
+
40
+ axisText: '#9AA0A6',
41
+ axisLine: '#2A2F36',
42
+ axisTick: '#2A2F36',
43
+
44
+ gridMajor: '#1B1F26',
45
+ gridMinor: '#161A20',
46
+
47
+ crosshairLine: '#5F6368',
48
+ crosshairLabelBg: '#E8EAED',
49
+ crosshairLabelText: '#0E1116',
50
+
51
+ selectionFill: '#4A9EFF33',
52
+ selectionStroke: '#4A9EFF',
53
+
54
+ tooltipBg: '#1B1F26EE',
55
+ tooltipText: '#E8EAED',
56
+ tooltipBorder: '#2A2F36',
57
+
58
+ heatmapColdest: '#0E1116',
59
+ heatmapHottest: '#80B7FF',
60
+ volumeProfileFill: '#6B727A66',
61
+ volumeProfilePoc: '#FFA94D',
62
+ volumeProfileValueArea: '#4A9EFF33',
63
+ footprintAsk: '#22D69B80',
64
+ footprintBid: '#FF646480',
65
+ footprintImbalance: '#FFA94D',
66
+
67
+ alertActive: '#4A9EFF',
68
+ alertTriggered: '#FFA94D',
69
+ alertMuted: '#6B727A',
70
+
71
+ avwapLine: '#A78BFA',
72
+ avwapBand: '#A78BFA33',
73
+ mtfOverlay: '#38BDF8',
74
+
75
+ palette: {
76
+ // Same hue ordering as light theme; values tuned for dark BG.
77
+ i1: '#4A9EFF', // blue (brightened)
78
+ i2: '#FFB95A', // amber
79
+ i3: '#22D69B', // teal-green
80
+ i4: '#E879BA', // pink
81
+ i5: '#FF8848', // burnt orange
82
+ i6: '#7DD3FC', // sky
83
+ i7: '#FCE96A', // yellow
84
+ i8: '#A78BFA', // purple
85
+ i9: '#60A5FA', // blue
86
+ i10: '#9AA0A6', // neutral gray
87
+ indicatorAtr: '#F59E0B',
88
+ },
89
+
90
+ // ── Legacy indicator colours (from engine/theme/colors) ──
91
+ text: {
92
+ primary: 'hsl(210, 10%, 85%)',
93
+ secondary: 'hsl(210, 8%, 75%)',
94
+ tertiary: 'hsl(210, 6%, 60%)',
95
+ weak: 'hsl(210, 5%, 45%)',
96
+ white: 'rgba(255, 255, 255, 0.95)',
97
+ },
98
+ price: {
99
+ upLight: 'rgba(255, 80, 100, 0.85)',
100
+ upTick: 'hsl(0, 70%, 60%)',
101
+ downLight: 'rgba(60, 200, 160, 0.85)',
102
+ downTick: 'hsl(150, 50%, 65%)',
103
+ lastPrice: 'rgba(230, 100, 115, 0.95)',
104
+ },
105
+ tagBg: {
106
+ white: 'rgb(40, 40, 55)',
107
+ lightGray: 'rgba(50, 50, 65, 0.92)',
108
+ pureWhite: '#282837',
109
+ transparent: 'transparent',
110
+ active: '#1890ff',
111
+ activeHover: '#40a9ff',
112
+ hover: '#3a3a4a',
113
+ },
114
+ border: {
115
+ dark: 'rgba(255, 255, 255, 0.15)',
116
+ medium: 'rgba(255, 255, 255, 0.12)',
117
+ light: 'rgba(255, 255, 255, 0.08)',
118
+ separator: 'rgba(255, 255, 255, 0.10)',
119
+ button: '#505060',
120
+ chart: '#3A4048',
121
+ },
122
+ ma: {
123
+ ma5: 'rgba(255, 200, 50, 1)',
124
+ ma10: 'rgba(200, 150, 30, 1)',
125
+ ma20: 'rgba(90, 140, 255, 1)',
126
+ ma30: 'rgba(90, 190, 95, 1)',
127
+ ma60: 'rgba(170, 60, 195, 1)',
128
+ },
129
+ boll: {
130
+ upper: 'rgba(200, 60, 60, 1)',
131
+ middle: 'rgba(90, 140, 255, 1)',
132
+ lower: 'rgba(50, 170, 60, 1)',
133
+ bandFill: 'rgba(120, 170, 255, 0.15)',
134
+ },
135
+ macd: {
136
+ dif: 'rgba(90, 140, 255, 1)',
137
+ dea: 'rgba(255, 170, 50, 1)',
138
+ barUp: '#ff6b6b',
139
+ barUpLight: '#ffb3b3',
140
+ barDown: '#4ecdc4',
141
+ barDownLight: '#a8e6e1',
142
+ },
143
+ rsi: {
144
+ rsi1: 'rgba(90, 140, 255, 1)',
145
+ rsi2: 'rgba(255, 170, 50, 1)',
146
+ rsi3: 'rgba(180, 70, 205, 1)',
147
+ },
148
+ cci: {
149
+ cci: 'rgba(90, 140, 255, 1)',
150
+ overbought: 'rgba(255, 80, 100, 0.6)',
151
+ oversold: 'rgba(60, 200, 160, 0.6)',
152
+ },
153
+ kdj: {
154
+ k: 'rgba(90, 140, 255, 1)',
155
+ d: 'rgba(255, 170, 50, 1)',
156
+ j: 'rgba(180, 70, 205, 1)',
157
+ },
158
+ mom: {
159
+ mom: 'rgba(90, 140, 255, 1)',
160
+ zero: 'rgba(255, 255, 255, 0.2)',
161
+ },
162
+ wmsr: {
163
+ wmsr: 'rgba(90, 140, 255, 1)',
164
+ overbought: 'rgba(255, 80, 100, 0.6)',
165
+ oversold: 'rgba(60, 200, 160, 0.6)',
166
+ },
167
+ kst: {
168
+ kst: 'rgba(90, 140, 255, 1)',
169
+ signal: 'rgba(255, 170, 50, 1)',
170
+ },
171
+ expma: {
172
+ fast: 'rgba(255, 170, 50, 1)',
173
+ slow: 'rgba(90, 140, 255, 1)',
174
+ },
175
+ ene: {
176
+ upper: 'rgba(255, 80, 100, 1)',
177
+ middle: 'rgba(90, 140, 255, 1)',
178
+ lower: 'rgba(60, 200, 160, 1)',
179
+ bandFill: 'rgba(90, 140, 255, 0.12)',
180
+ },
181
+ label: {
182
+ bg: 'rgba(30, 30, 40, 0.9)',
183
+ text: '#ffffff',
184
+ },
185
+ lastPriceLabel: {
186
+ bg: 'rgba(60, 50, 55, 0.98)',
187
+ },
188
+ volumePrice: {
189
+ riseWith: '#FF6666',
190
+ riseWithout: '#66FF99',
191
+ fallWith: '#FF6666',
192
+ fallWithout: '#66FF99',
193
+ },
194
+ structure: {
195
+ hh: '#4ade80',
196
+ hl: '#22c55e',
197
+ lh: '#f87171',
198
+ ll: '#ef4444',
199
+ choch: '#a78bfa',
200
+ bos: '#fbbf24',
201
+ },
202
+ zones: {
203
+ fvgBullFill: 'rgba(74, 222, 128, 0.20)',
204
+ fvgBearFill: 'rgba(248, 113, 113, 0.20)',
205
+ fvgBullBorder: 'rgba(74, 222, 128, 0.8)',
206
+ fvgBearBorder: 'rgba(248, 113, 113, 0.8)',
207
+ obBullFill: 'rgba(74, 222, 128, 0.35)',
208
+ obBearFill: 'rgba(248, 113, 113, 0.35)',
209
+ },
210
+ wmsrGrid: 'rgba(255, 255, 255, 0.1)',
211
+ },
212
+ spacing: {
213
+ none: '0',
214
+ xxs: '2px',
215
+ xs: '4px',
216
+ sm: '8px',
217
+ md: '12px',
218
+ lg: '16px',
219
+ xl: '24px',
220
+ xxl: '32px',
221
+ xxxl: '64px',
222
+ },
223
+ typography: {
224
+ fontFamily:
225
+ "-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif",
226
+ fontFamilyMono:
227
+ "ui-monospace, SFMono-Regular, Menlo, Consolas, 'Liberation Mono', monospace",
228
+ fontSizeSm: '10px',
229
+ fontSizeMd: '12px',
230
+ fontSizeLg: '14px',
231
+ fontWeightRegular: 400,
232
+ fontWeightMedium: 500,
233
+ fontWeightBold: 700,
234
+ lineHeightTight: 1.2,
235
+ lineHeightStandard: 1.4,
236
+ },
237
+ motion: {
238
+ durationInstant: '0ms',
239
+ durationFast: '120ms',
240
+ durationModerate: '200ms',
241
+ easingStandard: 'cubic-bezier(0.4, 0, 0.2, 1)',
242
+ easingDecelerate: 'cubic-bezier(0, 0, 0.2, 1)',
243
+ },
244
+ }
@@ -0,0 +1,250 @@
1
+ /**
2
+ * Light theme — concrete token values.
3
+ *
4
+ * Color choices:
5
+ *
6
+ * - Bull (up) = a dark saturated green (#0F8B5C). Picked to clear the
7
+ * WCAG AA non-text threshold (≥ 3:1) against #FAFAFA. The lighter
8
+ * industry-standard greens like #26A69A fail that bar by ~25 %.
9
+ * - Bear (down) = a dark saturated red (#C2363B). Same rationale —
10
+ * the common #EE4D4D fails AA at ~2.6:1.
11
+ * - Background = #FAFAFA (slightly off-white, kinder to eyes than pure
12
+ * #FFFFFF for long sessions).
13
+ * - Grid major / minor split: major lines for round-number price tiers,
14
+ * minor for between-tier rhythm. Both very low contrast (1.3:1, 1.1:1)
15
+ * so they don't dominate.
16
+ *
17
+ * Indicator palette: ten qualitatively distinct hues using the Okabe-Ito
18
+ * colorblind-safe set (extended to ten by adding three desaturated mids).
19
+ * Each WCAG AA against the background (>= 3:1 for non-text).
20
+ */
21
+
22
+ import type { Theme } from './types'
23
+
24
+ export const lightTheme: Theme = {
25
+ name: 'light',
26
+ colors: {
27
+ background: '#FAFAFA',
28
+ foreground: '#1F1F1F',
29
+ chartBackground: '#FFFFFF',
30
+
31
+ candleUpBody: '#0F8B5C',
32
+ candleUpBorder: '#0F8B5C',
33
+ candleUpWick: '#0F8B5C',
34
+ candleDownBody: '#C2363B',
35
+ candleDownBorder: '#C2363B',
36
+ candleDownWick: '#C2363B',
37
+ candleDojiBorder: '#6E6E6E',
38
+
39
+ volumeUp: '#0F8B5C66', // 40% alpha — paired with candleUp
40
+ volumeDown: '#C2363B66',
41
+
42
+ axisText: '#5A5A5A',
43
+ axisLine: '#D0D0D0',
44
+ axisTick: '#D0D0D0',
45
+
46
+ gridMajor: '#E5E5E5',
47
+ gridMinor: '#F0F0F0',
48
+
49
+ crosshairLine: '#8C8C8C',
50
+ crosshairLabelBg: '#1F1F1F',
51
+ crosshairLabelText: '#FAFAFA',
52
+
53
+ selectionFill: '#2D7FF933',
54
+ selectionStroke: '#2D7FF9',
55
+
56
+ tooltipBg: '#FFFFFFEE',
57
+ tooltipText: '#1F1F1F',
58
+ tooltipBorder: '#D0D0D0',
59
+
60
+ heatmapColdest: '#F0F4F8',
61
+ heatmapHottest: '#1F3A5F',
62
+ volumeProfileFill: '#9CA3AF66',
63
+ volumeProfilePoc: '#F97316',
64
+ volumeProfileValueArea: '#2D7FF933',
65
+ footprintAsk: '#0F8B5C80',
66
+ footprintBid: '#C2363B80',
67
+ footprintImbalance: '#F97316',
68
+
69
+ alertActive: '#2D7FF9',
70
+ // alertTriggered: orange #F97316 was 2.69:1 on white (fails AA
71
+ // non-text). Darkened to #C2410C → 4.13:1.
72
+ alertTriggered: '#C2410C',
73
+ alertMuted: '#9CA3AF',
74
+
75
+ avwapLine: '#7C3AED',
76
+ avwapBand: '#7C3AED33',
77
+ // mtfOverlay: sky #0EA5E9 was 2.66:1 on white. Darkened to
78
+ // #0369A1 → 4.59:1.
79
+ mtfOverlay: '#0369A1',
80
+
81
+ palette: {
82
+ // Okabe-Ito-derived qualitative scale, AA on #FAFAFA
83
+ i1: '#0072B2', // strong blue
84
+ i2: '#E69F00', // amber
85
+ i3: '#009E73', // teal-green
86
+ i4: '#CC79A7', // pink
87
+ i5: '#D55E00', // burnt orange
88
+ i6: '#56B4E9', // sky
89
+ i7: '#F0E442', // yellow (use sparingly — low contrast)
90
+ i8: '#7C3AED', // purple
91
+ i9: '#2D7FF9', // blue
92
+ i10: '#6E6E6E', // neutral gray
93
+ indicatorAtr: '#d97706',
94
+ },
95
+
96
+ // ── Legacy indicator colours (from engine/theme/colors) ──
97
+ text: {
98
+ primary: 'hsl(210, 9%, 31%)',
99
+ secondary: 'hsl(210, 9%, 35%)',
100
+ tertiary: 'hsl(210, 8%, 50%)',
101
+ weak: 'hsl(210, 7%, 65%)',
102
+ white: 'rgba(255, 255, 255, 0.92)',
103
+ },
104
+ price: {
105
+ upLight: 'rgba(214, 10, 34, 0.92)',
106
+ upTick: 'hsl(0, 60%, 50%)',
107
+ downLight: 'rgba(3, 123, 102, 0.92)',
108
+ downTick: 'hsl(150, 30%, 60%)',
109
+ lastPrice: 'rgba(196, 74, 86, 0.95)',
110
+ },
111
+ tagBg: {
112
+ white: 'rgb(255, 255, 255)',
113
+ lightGray: 'rgba(255, 255, 255, 0.92)',
114
+ pureWhite: '#ffffff',
115
+ transparent: 'transparent',
116
+ active: '#1890ff',
117
+ activeHover: '#40a9ff',
118
+ hover: '#f0f0f0',
119
+ },
120
+ border: {
121
+ dark: 'rgba(0, 0, 0, 0.12)',
122
+ medium: 'rgba(0, 0, 0, 0.10)',
123
+ light: 'rgba(0, 0, 0, 0.08)',
124
+ separator: 'rgba(0, 0, 0, 0.10)',
125
+ button: '#d0d0d0',
126
+ chart: '#e5e5e5',
127
+ },
128
+ ma: {
129
+ ma5: 'rgba(255, 193, 37, 1)',
130
+ ma10: 'rgba(190, 131, 12, 1)',
131
+ ma20: 'rgba(69, 112, 249, 1)',
132
+ ma30: 'rgba(76, 175, 80, 1)',
133
+ ma60: 'rgba(156, 39, 176, 1)',
134
+ },
135
+ boll: {
136
+ upper: 'rgba(178, 34, 34, 1)',
137
+ middle: 'rgba(69, 112, 249, 1)',
138
+ lower: 'rgba(34, 139, 34, 1)',
139
+ bandFill: 'rgba(100, 149, 237, 0.1)',
140
+ },
141
+ macd: {
142
+ dif: 'rgba(69, 112, 249, 1)',
143
+ dea: 'rgba(255, 152, 0, 1)',
144
+ barUp: '#ff5252',
145
+ barUpLight: '#fccbcd',
146
+ barDown: '#22ab94',
147
+ barDownLight: '#ace5dc',
148
+ },
149
+ rsi: {
150
+ rsi1: 'rgba(69, 112, 249, 1)',
151
+ rsi2: 'rgba(255, 152, 0, 1)',
152
+ rsi3: 'rgba(156, 39, 176, 1)',
153
+ },
154
+ cci: {
155
+ cci: 'rgba(69, 112, 249, 1)',
156
+ overbought: 'rgba(214, 10, 34, 0.5)',
157
+ oversold: 'rgba(3, 123, 102, 0.5)',
158
+ },
159
+ kdj: {
160
+ k: 'rgba(69, 112, 249, 1)',
161
+ d: 'rgba(255, 152, 0, 1)',
162
+ j: 'rgba(156, 39, 176, 1)',
163
+ },
164
+ mom: {
165
+ mom: 'rgba(69, 112, 249, 1)',
166
+ zero: 'rgba(0, 0, 0, 0.2)',
167
+ },
168
+ wmsr: {
169
+ wmsr: 'rgba(69, 112, 249, 1)',
170
+ overbought: 'rgba(214, 10, 34, 0.5)',
171
+ oversold: 'rgba(3, 123, 102, 0.5)',
172
+ },
173
+ kst: {
174
+ kst: 'rgba(69, 112, 249, 1)',
175
+ signal: 'rgba(255, 152, 0, 1)',
176
+ },
177
+ expma: {
178
+ fast: 'rgba(255, 152, 0, 1)',
179
+ slow: 'rgba(69, 112, 249, 1)',
180
+ },
181
+ ene: {
182
+ upper: 'rgba(214, 10, 34, 1)',
183
+ middle: 'rgba(69, 112, 249, 1)',
184
+ lower: 'rgba(3, 123, 102, 1)',
185
+ bandFill: 'rgba(69, 112, 249, 0.08)',
186
+ },
187
+ label: {
188
+ bg: 'rgba(0, 0, 0, 0.8)',
189
+ text: '#ffffff',
190
+ },
191
+ lastPriceLabel: {
192
+ bg: 'rgba(255, 247, 248, 0.98)',
193
+ },
194
+ volumePrice: {
195
+ riseWith: '#FF4444',
196
+ riseWithout: '#00C853',
197
+ fallWith: '#FF4444',
198
+ fallWithout: '#00C853',
199
+ },
200
+ structure: {
201
+ hh: '#16a34a',
202
+ hl: '#22c55e',
203
+ lh: '#dc2626',
204
+ ll: '#ef4444',
205
+ choch: '#8b5cf6',
206
+ bos: '#f59e0b',
207
+ },
208
+ zones: {
209
+ fvgBullFill: 'rgba(34, 197, 94, 0.15)',
210
+ fvgBearFill: 'rgba(239, 68, 68, 0.15)',
211
+ fvgBullBorder: 'rgba(34, 197, 94, 0.6)',
212
+ fvgBearBorder: 'rgba(239, 68, 68, 0.6)',
213
+ obBullFill: 'rgba(34, 197, 94, 0.25)',
214
+ obBearFill: 'rgba(239, 68, 68, 0.25)',
215
+ },
216
+ wmsrGrid: 'rgba(0, 0, 0, 0.1)',
217
+ },
218
+ spacing: {
219
+ none: '0',
220
+ xxs: '2px',
221
+ xs: '4px',
222
+ sm: '8px',
223
+ md: '12px',
224
+ lg: '16px',
225
+ xl: '24px',
226
+ xxl: '32px',
227
+ xxxl: '64px',
228
+ },
229
+ typography: {
230
+ fontFamily:
231
+ "-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif",
232
+ fontFamilyMono:
233
+ "ui-monospace, SFMono-Regular, Menlo, Consolas, 'Liberation Mono', monospace",
234
+ fontSizeSm: '10px',
235
+ fontSizeMd: '12px',
236
+ fontSizeLg: '14px',
237
+ fontWeightRegular: 400,
238
+ fontWeightMedium: 500,
239
+ fontWeightBold: 700,
240
+ lineHeightTight: 1.2,
241
+ lineHeightStandard: 1.4,
242
+ },
243
+ motion: {
244
+ durationInstant: '0ms',
245
+ durationFast: '120ms',
246
+ durationModerate: '200ms',
247
+ easingStandard: 'cubic-bezier(0.4, 0, 0.2, 1)',
248
+ easingDecelerate: 'cubic-bezier(0, 0, 0.2, 1)',
249
+ },
250
+ }