@openmarketsai/order-sheet 0.1.0

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 (65) hide show
  1. package/LICENSE +201 -0
  2. package/NOTICE +5 -0
  3. package/README.md +183 -0
  4. package/dist/auth.d.ts +24 -0
  5. package/dist/auth.js +36 -0
  6. package/dist/auth.js.map +1 -0
  7. package/dist/client.d.ts +158 -0
  8. package/dist/client.js +253 -0
  9. package/dist/client.js.map +1 -0
  10. package/dist/errors.d.ts +34 -0
  11. package/dist/errors.js +34 -0
  12. package/dist/errors.js.map +1 -0
  13. package/dist/generated/contract.d.ts +28 -0
  14. package/dist/generated/contract.js +176 -0
  15. package/dist/generated/contract.js.map +1 -0
  16. package/dist/http.d.ts +19 -0
  17. package/dist/http.js +58 -0
  18. package/dist/http.js.map +1 -0
  19. package/dist/index.cjs +1742 -0
  20. package/dist/index.d.ts +41 -0
  21. package/dist/index.js +31 -0
  22. package/dist/index.js.map +1 -0
  23. package/dist/math.d.ts +22 -0
  24. package/dist/math.js +55 -0
  25. package/dist/math.js.map +1 -0
  26. package/dist/messages.d.ts +21 -0
  27. package/dist/messages.js +97 -0
  28. package/dist/messages.js.map +1 -0
  29. package/dist/odds.d.ts +12 -0
  30. package/dist/odds.js +33 -0
  31. package/dist/odds.js.map +1 -0
  32. package/dist/quote.d.ts +20 -0
  33. package/dist/quote.js +117 -0
  34. package/dist/quote.js.map +1 -0
  35. package/dist/react.cjs +2137 -0
  36. package/dist/react.d.ts +157 -0
  37. package/dist/react.js +297 -0
  38. package/dist/react.js.map +1 -0
  39. package/dist/sheet.d.ts +77 -0
  40. package/dist/sheet.js +648 -0
  41. package/dist/sheet.js.map +1 -0
  42. package/dist/stream.d.ts +71 -0
  43. package/dist/stream.js +160 -0
  44. package/dist/stream.js.map +1 -0
  45. package/dist/types.d.ts +287 -0
  46. package/dist/types.js +2 -0
  47. package/dist/types.js.map +1 -0
  48. package/dist/ui/styles.css +284 -0
  49. package/dist/ui/theme.d.ts +108 -0
  50. package/dist/ui/theme.js +180 -0
  51. package/dist/ui/theme.js.map +1 -0
  52. package/dist/ui.cjs +2606 -0
  53. package/dist/ui.d.ts +124 -0
  54. package/dist/ui.js +154 -0
  55. package/dist/ui.js.map +1 -0
  56. package/dist/validate.d.ts +20 -0
  57. package/dist/validate.js +126 -0
  58. package/dist/validate.js.map +1 -0
  59. package/dist/venues.d.ts +19 -0
  60. package/dist/venues.js +103 -0
  61. package/dist/venues.js.map +1 -0
  62. package/dist/wire.d.ts +382 -0
  63. package/dist/wire.js +2 -0
  64. package/dist/wire.js.map +1 -0
  65. package/package.json +78 -0
@@ -0,0 +1,284 @@
1
+ /* @openmarketsai/order-sheet/ui — the styled sheet.
2
+ *
3
+ * Contract with the host page:
4
+ * - every rule is scoped under .oms-root; no :root, html, body, or * rules
5
+ * - every variable is --oms-*, every class is oms-*
6
+ * - everything lives in @layer oms, so a host's own layers order above it and
7
+ * an unlayered host rule always wins
8
+ * - the default tokens are the OpenMarkets brand; system colour scheme by
9
+ * default, dark under prefers-color-scheme (guarded so data-oms-theme="light"
10
+ * wins) and again under data-oms-theme="dark"; the two dark blocks are
11
+ * byte-identical on purpose
12
+ * - the layout answers to the sheet's OWN width (container queries), not the viewport
13
+ * - no @font-face: the token names a stack with system fallbacks
14
+ */
15
+ @layer oms {
16
+ .oms-root {
17
+ color-scheme: light;
18
+ --oms-bg: #fafafc;
19
+ --oms-surface: #ffffff;
20
+ --oms-fg: #09090b;
21
+ --oms-muted: #52525b;
22
+ --oms-border: #e4e4e7;
23
+ --oms-accent: #4f46e5;
24
+ --oms-accent-soft: #e0e7ff;
25
+ --oms-live: #047857;
26
+ --oms-live-soft: #d1fae5;
27
+ --oms-soon: #155e75;
28
+ --oms-soon-soft: #cffafe;
29
+ --oms-warn: #b45309;
30
+ --oms-warn-soft: #fef3c7;
31
+ --oms-danger: #be123c;
32
+ --oms-danger-soft: #ffe4e6;
33
+ --oms-font: 'Inter', -apple-system, BlinkMacSystemFont, system-ui, sans-serif;
34
+ --oms-font-mono: 'JetBrains Mono', ui-monospace, 'SF Mono', Menlo, monospace;
35
+ --oms-radius: 4px;
36
+ --oms-density: 1;
37
+
38
+ /* derived */
39
+ --oms-radius-chip: calc(var(--oms-radius) * 0.75);
40
+ --oms-space: calc(8px * var(--oms-density));
41
+ --oms-text: calc(14px * var(--oms-density));
42
+ --oms-text-sm: calc(12px * var(--oms-density));
43
+ --oms-text-lg: calc(18px * var(--oms-density));
44
+ --oms-line: 1.45;
45
+
46
+ container-type: inline-size;
47
+ container-name: oms;
48
+ color: var(--oms-fg);
49
+ font-family: var(--oms-font);
50
+ font-size: var(--oms-text);
51
+ line-height: var(--oms-line);
52
+ -webkit-font-smoothing: antialiased;
53
+ }
54
+
55
+ @media (prefers-color-scheme: dark) {
56
+ .oms-root:not([data-oms-theme='light']) {
57
+ color-scheme: dark;
58
+ --oms-bg: #09090b;
59
+ --oms-surface: #18181b;
60
+ --oms-fg: #f4f4f5;
61
+ --oms-muted: #a1a1aa;
62
+ --oms-border: #2a2a30;
63
+ --oms-accent: #818cf8;
64
+ --oms-accent-soft: #1e1b4b;
65
+ --oms-live: #34d399;
66
+ --oms-live-soft: #052e21;
67
+ --oms-soon: #22d3ee;
68
+ --oms-soon-soft: #083344;
69
+ --oms-warn: #fbbf24;
70
+ --oms-warn-soft: #3a2a0a;
71
+ --oms-danger: #fb7185;
72
+ --oms-danger-soft: #4c0519;
73
+ }
74
+ }
75
+
76
+ .oms-root[data-oms-theme='dark'] {
77
+ color-scheme: dark;
78
+ --oms-bg: #09090b;
79
+ --oms-surface: #18181b;
80
+ --oms-fg: #f4f4f5;
81
+ --oms-muted: #a1a1aa;
82
+ --oms-border: #2a2a30;
83
+ --oms-accent: #818cf8;
84
+ --oms-accent-soft: #1e1b4b;
85
+ --oms-live: #34d399;
86
+ --oms-live-soft: #052e21;
87
+ --oms-soon: #22d3ee;
88
+ --oms-soon-soft: #083344;
89
+ --oms-warn: #fbbf24;
90
+ --oms-warn-soft: #3a2a0a;
91
+ --oms-danger: #fb7185;
92
+ --oms-danger-soft: #4c0519;
93
+ }
94
+
95
+ /* ── the card ── */
96
+ .oms-sheet {
97
+ background: var(--oms-surface);
98
+ border: 1px solid var(--oms-border);
99
+ border-radius: var(--oms-radius);
100
+ padding: calc(var(--oms-space) * 2);
101
+ display: grid;
102
+ gap: calc(var(--oms-space) * 1.5);
103
+ box-sizing: border-box;
104
+ max-width: 100%;
105
+ }
106
+ .oms-sheet *,
107
+ .oms-sheet *::before,
108
+ .oms-sheet *::after { box-sizing: border-box; }
109
+ .oms-sheet button,
110
+ .oms-sheet input { font: inherit; color: inherit; }
111
+
112
+ .oms-sheet :is(button, input, [role='radio']):focus-visible {
113
+ outline: 2px solid var(--oms-accent);
114
+ outline-offset: 2px;
115
+ }
116
+
117
+ .oms-header { display: grid; gap: calc(var(--oms-space) * 0.25); }
118
+ .oms-title { font-size: var(--oms-text-lg); font-weight: 700; letter-spacing: -0.01em; margin: 0; }
119
+ .oms-subtitle { color: var(--oms-muted); font-size: var(--oms-text-sm); margin: 0; }
120
+
121
+ .oms-label {
122
+ display: block;
123
+ color: var(--oms-muted);
124
+ font-family: var(--oms-font-mono);
125
+ font-size: calc(var(--oms-text-sm) * 0.92);
126
+ letter-spacing: 0.06em;
127
+ text-transform: uppercase;
128
+ margin-bottom: calc(var(--oms-space) * 0.5);
129
+ }
130
+
131
+ /* ── venues ── */
132
+ .oms-venues { display: grid; gap: calc(var(--oms-space) * 0.5); margin: 0; padding: 0; }
133
+ .oms-venue {
134
+ display: grid;
135
+ grid-template-columns: auto 1fr auto;
136
+ align-items: center;
137
+ gap: var(--oms-space);
138
+ padding: var(--oms-space) calc(var(--oms-space) * 1.25);
139
+ border: 1px solid var(--oms-border);
140
+ border-radius: var(--oms-radius);
141
+ background: var(--oms-surface);
142
+ cursor: pointer;
143
+ text-align: left;
144
+ width: 100%;
145
+ }
146
+ .oms-venue[aria-checked='true'] { border-color: var(--oms-accent); background: var(--oms-accent-soft); }
147
+ .oms-venue[data-state='blocked'] { cursor: not-allowed; }
148
+ .oms-venue[data-state='blocked'] .oms-venue-name,
149
+ .oms-venue[data-state='blocked'] .oms-venue-price { opacity: 0.55; }
150
+ .oms-venue-logo { width: calc(20px * var(--oms-density)); height: calc(20px * var(--oms-density)); border-radius: 50%; object-fit: cover; background: var(--oms-border); }
151
+ .oms-venue-logo:empty, .oms-venue-logo--placeholder { display: inline-block; }
152
+ .oms-venue-main { display: grid; gap: 2px; min-width: 0; }
153
+ .oms-venue-name { font-weight: 600; display: flex; align-items: center; gap: calc(var(--oms-space) * 0.5); flex-wrap: wrap; }
154
+ .oms-venue-reason { color: var(--oms-muted); font-size: var(--oms-text-sm); }
155
+ .oms-venue[data-state='blocked'] .oms-venue-reason { color: var(--oms-danger); }
156
+ .oms-venue-price { font-family: var(--oms-font-mono); font-variant-numeric: tabular-nums; font-size: var(--oms-text-lg); font-weight: 600; }
157
+ .oms-venue-meta { color: var(--oms-muted); font-size: var(--oms-text-sm); font-family: var(--oms-font-mono); font-variant-numeric: tabular-nums; text-align: right; }
158
+
159
+ /* ── chips ── */
160
+ .oms-chip {
161
+ display: inline-block;
162
+ padding: 1px calc(var(--oms-space) * 0.75);
163
+ border-radius: var(--oms-radius-chip);
164
+ font-family: var(--oms-font-mono);
165
+ font-size: calc(var(--oms-text-sm) * 0.9);
166
+ font-weight: 600;
167
+ letter-spacing: 0.04em;
168
+ text-transform: uppercase;
169
+ line-height: 1.6;
170
+ }
171
+ .oms-chip--best { background: var(--oms-live-soft); color: var(--oms-live); }
172
+ .oms-chip--connected { background: var(--oms-live-soft); color: var(--oms-live); }
173
+ .oms-chip--off { background: var(--oms-warn-soft); color: var(--oms-warn); }
174
+ .oms-chip--test { background: var(--oms-warn-soft); color: var(--oms-warn); }
175
+ .oms-chip--soon { background: var(--oms-soon-soft); color: var(--oms-soon); }
176
+ .oms-chip--danger { background: var(--oms-danger-soft); color: var(--oms-danger); }
177
+
178
+ /* ── segmented controls ── */
179
+ .oms-segmented { display: inline-grid; grid-auto-flow: column; grid-auto-columns: 1fr; border: 1px solid var(--oms-border); border-radius: var(--oms-radius); overflow: hidden; width: 100%; }
180
+ .oms-segment {
181
+ padding: calc(var(--oms-space) * 0.75) var(--oms-space);
182
+ background: var(--oms-surface);
183
+ border: 0;
184
+ border-right: 1px solid var(--oms-border);
185
+ cursor: pointer;
186
+ font-weight: 500;
187
+ }
188
+ .oms-segment:last-child { border-right: 0; }
189
+ .oms-segment[aria-pressed='true'] { background: var(--oms-accent); color: var(--oms-bg); }
190
+ .oms-segment[data-mode='real'][aria-pressed='true'] { background: var(--oms-danger); }
191
+ .oms-segment:not([data-available]) { color: var(--oms-muted); }
192
+ .oms-segment:disabled { cursor: not-allowed; opacity: 0.6; }
193
+
194
+ /* ── fields ── */
195
+ .oms-fields { display: grid; grid-template-columns: 1fr 1fr; gap: var(--oms-space); }
196
+ .oms-field { display: grid; gap: calc(var(--oms-space) * 0.5); min-width: 0; }
197
+ .oms-input-row { display: flex; align-items: stretch; border: 1px solid var(--oms-border); border-radius: var(--oms-radius); background: var(--oms-surface); overflow: hidden; }
198
+ .oms-input-row:focus-within { border-color: var(--oms-accent); }
199
+ .oms-input {
200
+ flex: 1 1 auto;
201
+ min-width: 0;
202
+ padding: calc(var(--oms-space) * 0.75) var(--oms-space);
203
+ border: 0;
204
+ background: transparent;
205
+ font-family: var(--oms-font-mono);
206
+ font-variant-numeric: tabular-nums;
207
+ font-size: var(--oms-text-lg);
208
+ }
209
+ .oms-input:focus-visible { outline: none; }
210
+ .oms-input[aria-invalid='true'] { color: var(--oms-danger); }
211
+ .oms-input-unit { display: flex; }
212
+ .oms-input-unit .oms-segment { border-right: 0; border-left: 1px solid var(--oms-border); font-family: var(--oms-font-mono); font-size: var(--oms-text-sm); }
213
+ .oms-input-hint { color: var(--oms-muted); font-size: var(--oms-text-sm); font-family: var(--oms-font-mono); }
214
+ .oms-link { background: none; border: 0; padding: 0; color: var(--oms-accent); cursor: pointer; text-decoration: underline; font-size: var(--oms-text-sm); }
215
+
216
+ /* ── quote ── */
217
+ .oms-quote { display: grid; gap: calc(var(--oms-space) * 0.5); padding: var(--oms-space) calc(var(--oms-space) * 1.25); border: 1px solid var(--oms-border); border-radius: var(--oms-radius); background: var(--oms-bg); }
218
+ .oms-quote[data-freshness='stale'] { border-style: dashed; }
219
+ .oms-quote-row { display: flex; justify-content: space-between; gap: var(--oms-space); margin: 0; }
220
+ .oms-quote-row dt { color: var(--oms-muted); }
221
+ .oms-quote-row dd { margin: 0; font-family: var(--oms-font-mono); font-variant-numeric: tabular-nums; }
222
+ .oms-quote-row--total dd, .oms-quote-row--total dt { font-weight: 700; }
223
+ .oms-quote-row--profit dd { color: var(--oms-live); }
224
+ .oms-quote-note { color: var(--oms-muted); font-size: var(--oms-text-sm); margin: 0; }
225
+
226
+ /* ── issues ── */
227
+ .oms-issues { display: grid; gap: calc(var(--oms-space) * 0.5); }
228
+ .oms-issues:empty { display: none; }
229
+ .oms-issue {
230
+ display: flex;
231
+ align-items: flex-start;
232
+ gap: calc(var(--oms-space) * 0.75);
233
+ padding: calc(var(--oms-space) * 0.75) var(--oms-space);
234
+ border-radius: var(--oms-radius);
235
+ font-size: var(--oms-text-sm);
236
+ }
237
+ .oms-issue[data-severity='block'] { background: var(--oms-danger-soft); color: var(--oms-danger); }
238
+ .oms-issue[data-severity='warn'] { background: var(--oms-warn-soft); color: var(--oms-warn); }
239
+ .oms-issue[data-severity='info'] { background: var(--oms-soon-soft); color: var(--oms-soon); }
240
+ .oms-issue-fix { margin-left: auto; white-space: nowrap; background: none; border: 1px solid currentColor; border-radius: var(--oms-radius-chip); color: inherit; padding: 0 calc(var(--oms-space) * 0.75); cursor: pointer; font-size: inherit; }
241
+
242
+ .oms-hint { display: flex; align-items: center; gap: var(--oms-space); color: var(--oms-muted); font-size: var(--oms-text-sm); }
243
+
244
+ /* ── submit ── */
245
+ .oms-submit {
246
+ width: 100%;
247
+ padding: calc(var(--oms-space) * 1.25) var(--oms-space);
248
+ border: 0;
249
+ border-radius: var(--oms-radius);
250
+ background: var(--oms-accent);
251
+ color: var(--oms-bg);
252
+ font-weight: 700;
253
+ font-size: var(--oms-text);
254
+ cursor: pointer;
255
+ }
256
+ .oms-submit[data-mode='real'] { background: var(--oms-danger); }
257
+ .oms-submit[data-phase='confirming'] { outline: 2px solid var(--oms-danger); outline-offset: 2px; }
258
+ .oms-submit:disabled { opacity: 0.5; cursor: not-allowed; }
259
+ .oms-submit-row { display: grid; gap: calc(var(--oms-space) * 0.5); }
260
+ .oms-submit-secondary { background: none; border: 0; color: var(--oms-muted); cursor: pointer; text-decoration: underline; font-size: var(--oms-text-sm); justify-self: center; }
261
+
262
+ /* ── outcome ── */
263
+ .oms-outcome { display: grid; gap: calc(var(--oms-space) * 0.5); padding: var(--oms-space) calc(var(--oms-space) * 1.25); border-radius: var(--oms-radius); border: 1px solid var(--oms-border); }
264
+ .oms-outcome[data-summary='filled'], .oms-outcome[data-phase='filled'], .oms-outcome[data-phase='settled'] { border-color: var(--oms-live); background: var(--oms-live-soft); color: var(--oms-live); }
265
+ .oms-outcome[data-phase='resting'], .oms-outcome[data-phase='pending'], .oms-outcome[data-phase='partial'] { border-color: var(--oms-soon); background: var(--oms-soon-soft); color: var(--oms-soon); }
266
+ .oms-outcome[data-phase='failed'], .oms-outcome[data-phase='cancelled'] { border-color: var(--oms-danger); background: var(--oms-danger-soft); color: var(--oms-danger); }
267
+ .oms-outcome-title { font-weight: 700; margin: 0; }
268
+ .oms-outcome-detail { margin: 0; font-size: var(--oms-text-sm); }
269
+ .oms-outcome-ids { font-family: var(--oms-font-mono); font-size: var(--oms-text-sm); opacity: 0.8; word-break: break-all; }
270
+ .oms-outcome-actions { display: flex; gap: var(--oms-space); flex-wrap: wrap; }
271
+ .oms-button { padding: calc(var(--oms-space) * 0.6) var(--oms-space); border: 1px solid currentColor; border-radius: var(--oms-radius); background: transparent; color: inherit; cursor: pointer; font-weight: 600; font-size: var(--oms-text-sm); }
272
+
273
+ .oms-footer { color: var(--oms-muted); font-size: var(--oms-text-sm); display: flex; justify-content: space-between; gap: var(--oms-space); flex-wrap: wrap; }
274
+ .oms-skeleton { color: var(--oms-muted); }
275
+ .oms-sr-only { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
276
+
277
+ /* ── narrow sheets: stack the fields, tighten the venue rows ── */
278
+ @container oms (max-width: 420px) {
279
+ .oms-fields { grid-template-columns: 1fr; }
280
+ .oms-venue { grid-template-columns: 1fr auto; }
281
+ .oms-venue-logo { display: none; }
282
+ .oms-venue-price { font-size: var(--oms-text); }
283
+ }
284
+ }
@@ -0,0 +1,108 @@
1
+ /**
2
+ * The theme contract for @openmarketsai/order-sheet/ui.
3
+ *
4
+ * A Theme is a small set of tokens per scheme (light / dark) plus type, radius
5
+ * and density. `createTheme` deep-merges partial overrides over a preset and
6
+ * derives the `*Soft` tints when only the strong colour is given. `themeToCss`
7
+ * turns a theme into `--oms-*` custom properties scoped to one class:
8
+ *
9
+ * light values on `.oms-theme-x`
10
+ * dark values under `@media (prefers-color-scheme: dark)` guarded by
11
+ * `:not([data-oms-theme="light"])`, and again under `[data-oms-theme="dark"]`
12
+ *
13
+ * so system is the default and the host can force either on any ancestor —
14
+ * exactly like the OpenMarkets console. Nothing here is global: no `:root`, no
15
+ * `body`, no resets.
16
+ */
17
+ export interface ThemeTokens {
18
+ /** Page / sheet background. Also the text colour ON an accent or danger fill. */
19
+ bg: string;
20
+ /** Card and inputs. */
21
+ surface: string;
22
+ fg: string;
23
+ muted: string;
24
+ border: string;
25
+ /** Practice CTA, selected venue, focus. */
26
+ accent: string;
27
+ accentSoft: string;
28
+ /** Filled, connected. */
29
+ live: string;
30
+ liveSoft: string;
31
+ /** Resting / pending. */
32
+ soon: string;
33
+ soonSoft: string;
34
+ /** Warnings, test mode. */
35
+ warn: string;
36
+ warnSoft: string;
37
+ /** Real-money CTA, blocks, failed. */
38
+ danger: string;
39
+ dangerSoft: string;
40
+ }
41
+ export type ThemeScheme = 'light' | 'dark' | 'system';
42
+ export interface Theme {
43
+ scheme: ThemeScheme;
44
+ font: string;
45
+ fontMono: string;
46
+ /** One radius for panels; chips are `calc(radius * 0.75)`. */
47
+ radius: string;
48
+ /** Scales paddings and line-heights: 0.85 compact, 1 default, 1.15 touch. */
49
+ density: number;
50
+ light: ThemeTokens;
51
+ dark: ThemeTokens;
52
+ }
53
+ type PerScheme<T> = T | {
54
+ light: T;
55
+ dark: T;
56
+ };
57
+ /** Partial overrides. A token given as one string applies to both schemes; `{ light, dark }` sets each. */
58
+ export interface ThemeInput {
59
+ scheme?: ThemeScheme;
60
+ font?: string;
61
+ fontMono?: string;
62
+ radius?: string;
63
+ density?: number;
64
+ bg?: PerScheme<string>;
65
+ surface?: PerScheme<string>;
66
+ fg?: PerScheme<string>;
67
+ muted?: PerScheme<string>;
68
+ border?: PerScheme<string>;
69
+ accent?: PerScheme<string>;
70
+ accentSoft?: PerScheme<string>;
71
+ live?: PerScheme<string>;
72
+ liveSoft?: PerScheme<string>;
73
+ soon?: PerScheme<string>;
74
+ soonSoft?: PerScheme<string>;
75
+ warn?: PerScheme<string>;
76
+ warnSoft?: PerScheme<string>;
77
+ danger?: PerScheme<string>;
78
+ dangerSoft?: PerScheme<string>;
79
+ /** Whole-scheme overrides win over the shorthands above. */
80
+ light?: Partial<ThemeTokens>;
81
+ dark?: Partial<ThemeTokens>;
82
+ }
83
+ /** The OpenMarkets brand — the console's tokens (apps/app/app/globals.css): zinc neutrals, indigo accent. */
84
+ export declare const openmarkets: Theme;
85
+ /** A second design on the same contract: cool slate, teal accent, rounder, a touch denser. */
86
+ export declare const slate: Theme;
87
+ export declare const presets: {
88
+ readonly openmarkets: Theme;
89
+ readonly slate: Theme;
90
+ };
91
+ export declare function createTheme(input?: ThemeInput, base?: Theme): Theme;
92
+ /** Mix a strong colour towards the background: 85% bg in light (a pale tint), 70% bg in dark (a deep tint). */
93
+ export declare function deriveSoft(strong: string, bg: string, scheme: 'light' | 'dark'): string;
94
+ /**
95
+ * A theme value goes into an injected <style> verbatim, so it must not be able
96
+ * to close the declaration, the rule or the element: drop `; { } < >` and
97
+ * comment openers. Developer input, but a value copied from a design tool
98
+ * should never break out of its custom property.
99
+ */
100
+ export declare function cssValue(v: string | number): string;
101
+ /**
102
+ * CSS for one theme, scoped to `selector` (a class on the sheet's root). The two
103
+ * dark blocks are byte-identical on purpose — keep them that way.
104
+ */
105
+ export declare function themeToCss(theme: Theme, selector: string): string;
106
+ /** A short stable id for a theme, so the same theme injects one style block. */
107
+ export declare function themeId(theme: Theme): string;
108
+ export {};
@@ -0,0 +1,180 @@
1
+ /**
2
+ * The theme contract for @openmarketsai/order-sheet/ui.
3
+ *
4
+ * A Theme is a small set of tokens per scheme (light / dark) plus type, radius
5
+ * and density. `createTheme` deep-merges partial overrides over a preset and
6
+ * derives the `*Soft` tints when only the strong colour is given. `themeToCss`
7
+ * turns a theme into `--oms-*` custom properties scoped to one class:
8
+ *
9
+ * light values on `.oms-theme-x`
10
+ * dark values under `@media (prefers-color-scheme: dark)` guarded by
11
+ * `:not([data-oms-theme="light"])`, and again under `[data-oms-theme="dark"]`
12
+ *
13
+ * so system is the default and the host can force either on any ancestor —
14
+ * exactly like the OpenMarkets console. Nothing here is global: no `:root`, no
15
+ * `body`, no resets.
16
+ */
17
+ // ─── Presets ───────────────────────────────────────────────────────────────────
18
+ /** The OpenMarkets brand — the console's tokens (apps/app/app/globals.css): zinc neutrals, indigo accent. */
19
+ export const openmarkets = {
20
+ scheme: 'system',
21
+ font: "'Inter', -apple-system, BlinkMacSystemFont, system-ui, sans-serif",
22
+ fontMono: "'JetBrains Mono', ui-monospace, 'SF Mono', Menlo, monospace",
23
+ radius: '4px',
24
+ density: 1,
25
+ light: {
26
+ bg: '#fafafc', surface: '#ffffff', fg: '#09090b', muted: '#52525b', border: '#e4e4e7',
27
+ accent: '#4f46e5', accentSoft: '#e0e7ff',
28
+ live: '#047857', liveSoft: '#d1fae5',
29
+ soon: '#155e75', soonSoft: '#cffafe',
30
+ warn: '#b45309', warnSoft: '#fef3c7',
31
+ danger: '#be123c', dangerSoft: '#ffe4e6',
32
+ },
33
+ dark: {
34
+ bg: '#09090b', surface: '#18181b', fg: '#f4f4f5', muted: '#a1a1aa', border: '#2a2a30',
35
+ accent: '#818cf8', accentSoft: '#1e1b4b',
36
+ live: '#34d399', liveSoft: '#052e21',
37
+ soon: '#22d3ee', soonSoft: '#083344',
38
+ warn: '#fbbf24', warnSoft: '#3a2a0a',
39
+ danger: '#fb7185', dangerSoft: '#4c0519',
40
+ },
41
+ };
42
+ /** A second design on the same contract: cool slate, teal accent, rounder, a touch denser. */
43
+ export const slate = {
44
+ scheme: 'system',
45
+ font: "system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif",
46
+ fontMono: "ui-monospace, 'SF Mono', Menlo, monospace",
47
+ radius: '10px',
48
+ density: 0.95,
49
+ light: {
50
+ bg: '#f6f8fa', surface: '#ffffff', fg: '#0f172a', muted: '#475569', border: '#d9e1ea',
51
+ accent: '#0f766e', accentSoft: '#ccfbf1',
52
+ live: '#15803d', liveSoft: '#dcfce7',
53
+ soon: '#1d4ed8', soonSoft: '#dbeafe',
54
+ warn: '#a16207', warnSoft: '#fef9c3',
55
+ danger: '#b91c1c', dangerSoft: '#fee2e2',
56
+ },
57
+ dark: {
58
+ bg: '#0b1220', surface: '#111a2b', fg: '#e2e8f0', muted: '#94a3b8', border: '#22304a',
59
+ accent: '#2dd4bf', accentSoft: '#042f2e',
60
+ live: '#4ade80', liveSoft: '#052e16',
61
+ soon: '#60a5fa', soonSoft: '#172554',
62
+ warn: '#facc15', warnSoft: '#422006',
63
+ danger: '#f87171', dangerSoft: '#450a0a',
64
+ },
65
+ };
66
+ export const presets = { openmarkets, slate };
67
+ // ─── createTheme ───────────────────────────────────────────────────────────────
68
+ const STRONG = ['accent', 'live', 'soon', 'warn', 'danger'];
69
+ const SOFT_OF = { accent: 'accentSoft', live: 'liveSoft', soon: 'soonSoft', warn: 'warnSoft', danger: 'dangerSoft' };
70
+ function pick(v, scheme) {
71
+ if (v == null)
72
+ return undefined;
73
+ if (typeof v === 'object' && v !== null && 'light' in v && 'dark' in v)
74
+ return v[scheme];
75
+ return v;
76
+ }
77
+ export function createTheme(input = {}, base = openmarkets) {
78
+ const build = (scheme) => {
79
+ const out = { ...base[scheme] };
80
+ const keys = Object.keys(out);
81
+ for (const k of keys) {
82
+ const v = pick(input[k], scheme);
83
+ if (v)
84
+ out[k] = v;
85
+ }
86
+ // A strong colour given without its tint: derive the tint from the scheme's background.
87
+ for (const k of STRONG) {
88
+ const soft = SOFT_OF[k];
89
+ const strongGiven = pick(input[k], scheme) || input[scheme]?.[k];
90
+ const softGiven = pick(input[soft], scheme) || input[scheme]?.[soft];
91
+ if (strongGiven && !softGiven)
92
+ out[soft] = deriveSoft(out[k], out.bg, scheme);
93
+ }
94
+ Object.assign(out, input[scheme] ?? {});
95
+ return out;
96
+ };
97
+ return {
98
+ scheme: input.scheme ?? base.scheme,
99
+ font: input.font ?? base.font,
100
+ fontMono: input.fontMono ?? base.fontMono,
101
+ radius: input.radius ?? base.radius,
102
+ density: input.density ?? base.density,
103
+ light: build('light'),
104
+ dark: build('dark'),
105
+ };
106
+ }
107
+ /** Mix a strong colour towards the background: 85% bg in light (a pale tint), 70% bg in dark (a deep tint). */
108
+ export function deriveSoft(strong, bg, scheme) {
109
+ const a = hexToRgb(strong);
110
+ const b = hexToRgb(bg);
111
+ if (!a || !b)
112
+ return strong;
113
+ const t = scheme === 'light' ? 0.85 : 0.7;
114
+ const mix = (x, y) => Math.round(x * (1 - t) + y * t);
115
+ return rgbToHex(mix(a[0], b[0]), mix(a[1], b[1]), mix(a[2], b[2]));
116
+ }
117
+ function hexToRgb(hex) {
118
+ const m = /^#?([0-9a-f]{3}|[0-9a-f]{6})$/i.exec(hex.trim());
119
+ if (!m)
120
+ return null;
121
+ let h = m[1];
122
+ if (h.length === 3)
123
+ h = h.split('').map((c) => c + c).join('');
124
+ return [parseInt(h.slice(0, 2), 16), parseInt(h.slice(2, 4), 16), parseInt(h.slice(4, 6), 16)];
125
+ }
126
+ function rgbToHex(r, g, b) {
127
+ return `#${[r, g, b].map((n) => Math.max(0, Math.min(255, n)).toString(16).padStart(2, '0')).join('')}`;
128
+ }
129
+ // ─── CSS emission ──────────────────────────────────────────────────────────────
130
+ const VAR_OF = {
131
+ bg: '--oms-bg', surface: '--oms-surface', fg: '--oms-fg', muted: '--oms-muted', border: '--oms-border',
132
+ accent: '--oms-accent', accentSoft: '--oms-accent-soft', live: '--oms-live', liveSoft: '--oms-live-soft',
133
+ soon: '--oms-soon', soonSoft: '--oms-soon-soft', warn: '--oms-warn', warnSoft: '--oms-warn-soft',
134
+ danger: '--oms-danger', dangerSoft: '--oms-danger-soft',
135
+ };
136
+ /**
137
+ * A theme value goes into an injected <style> verbatim, so it must not be able
138
+ * to close the declaration, the rule or the element: drop `; { } < >` and
139
+ * comment openers. Developer input, but a value copied from a design tool
140
+ * should never break out of its custom property.
141
+ */
142
+ export function cssValue(v) {
143
+ return String(v).replace(/[;{}<>]|\/\*|\*\//g, '').trim();
144
+ }
145
+ function declarations(tokens, scheme) {
146
+ const lines = [`color-scheme: ${scheme};`];
147
+ for (const k of Object.keys(VAR_OF))
148
+ lines.push(`${VAR_OF[k]}: ${cssValue(tokens[k])};`);
149
+ return lines.join(' ');
150
+ }
151
+ /**
152
+ * CSS for one theme, scoped to `selector` (a class on the sheet's root). The two
153
+ * dark blocks are byte-identical on purpose — keep them that way.
154
+ */
155
+ export function themeToCss(theme, selector) {
156
+ const base = [
157
+ `--oms-font: ${cssValue(theme.font)};`,
158
+ `--oms-font-mono: ${cssValue(theme.fontMono)};`,
159
+ `--oms-radius: ${cssValue(theme.radius)};`,
160
+ `--oms-density: ${cssValue(theme.density)};`,
161
+ declarations(theme.light, 'light'),
162
+ ].join(' ');
163
+ const dark = declarations(theme.dark, 'dark');
164
+ return [
165
+ `${selector} { ${base} }`,
166
+ `@media (prefers-color-scheme: dark) { ${selector}:not([data-oms-theme="light"]) { ${dark} } }`,
167
+ `${selector}[data-oms-theme="dark"] { ${dark} }`,
168
+ ].join('\n');
169
+ }
170
+ /** A short stable id for a theme, so the same theme injects one style block. */
171
+ export function themeId(theme) {
172
+ const s = JSON.stringify(theme);
173
+ let h = 2166136261;
174
+ for (let i = 0; i < s.length; i++) {
175
+ h ^= s.charCodeAt(i);
176
+ h = Math.imul(h, 16777619);
177
+ }
178
+ return (h >>> 0).toString(36);
179
+ }
180
+ //# sourceMappingURL=theme.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"theme.js","sourceRoot":"","sources":["../../src/ui/theme.ts"],"names":[],"mappings":"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"}