1import { colors, fontWeights, NumberToken } from "../tokens";
2import { withOpacity } from "../utils/color";
3import Theme, { buildPlayer, Syntax } from "./theme";
4
5const backgroundColor = {
6 100: {
7 base: colors.neutral[75],
8 hovered: colors.neutral[100],
9 active: colors.neutral[150],
10 focused: colors.neutral[100],
11 },
12 300: {
13 base: colors.neutral[25],
14 hovered: colors.neutral[75],
15 active: colors.neutral[100],
16 focused: colors.neutral[75],
17 },
18 500: {
19 base: colors.neutral[0],
20 hovered: withOpacity(colors.neutral[900], 0.03),
21 active: withOpacity(colors.neutral[900], 0.06),
22 focused: colors.neutral[50],
23 },
24 on300: {
25 base: colors.neutral[50],
26 hovered: colors.neutral[100],
27 active: colors.neutral[150],
28 focused: colors.neutral[100],
29 },
30 on500: {
31 base: colors.neutral[50],
32 hovered: colors.neutral[25],
33 active: colors.neutral[0],
34 focused: colors.neutral[25],
35 },
36 ok: {
37 base: withOpacity(colors.green[600], 0.15),
38 hovered: withOpacity(colors.green[600], 0.20),
39 active: withOpacity(colors.green[600], 0.25),
40 focused: withOpacity(colors.green[600], 0.20),
41 },
42 error: {
43 base: withOpacity(colors.red[600], 0.15),
44 hovered: withOpacity(colors.red[600], 0.20),
45 active: withOpacity(colors.red[600], 0.25),
46 focused: withOpacity(colors.red[600], 0.20),
47 },
48 warning: {
49 base: withOpacity(colors.amber[400], 0.15),
50 hovered: withOpacity(colors.amber[400], 0.20),
51 active: withOpacity(colors.amber[400], 0.25),
52 focused: withOpacity(colors.amber[400], 0.20),
53 },
54 info: {
55 base: withOpacity(colors.blue[500], 0.15),
56 hovered: withOpacity(colors.blue[500], 0.20),
57 active: withOpacity(colors.blue[500], 0.25),
58 focused: withOpacity(colors.blue[500], 0.20),
59 },
60};
61
62const borderColor = {
63 primary: colors.neutral[150],
64 secondary: colors.neutral[150],
65 muted: colors.neutral[100],
66 focused: colors.indigo[500],
67 active: colors.neutral[250],
68 onMedia: withOpacity(colors.neutral[250], 0.3),
69 ok: withOpacity(colors.green[600], 0.15),
70 error: withOpacity(colors.red[500], 0.15),
71 warning: withOpacity(colors.amber[400], 0.15),
72 info: withOpacity(colors.blue[500], 0.15),
73};
74
75const textColor = {
76 primary: colors.neutral[750],
77 secondary: colors.neutral[650],
78 muted: colors.neutral[550],
79 placeholder: colors.neutral[450],
80 active: colors.neutral[900],
81 feature: colors.indigo[500],
82 ok: colors.green[500],
83 error: colors.red[500],
84 warning: colors.yellow[500],
85 info: colors.blue[500],
86};
87
88const iconColor = {
89 primary: colors.neutral[700],
90 secondary: colors.neutral[500],
91 muted: colors.neutral[350],
92 placeholder: colors.neutral[300],
93 active: colors.neutral[900],
94 feature: colors.indigo[500],
95 ok: colors.green[600],
96 error: colors.red[600],
97 warning: colors.yellow[400],
98 info: colors.blue[600],
99};
100
101const player = {
102 1: buildPlayer(colors.blue[500]),
103 2: buildPlayer(colors.emerald[400]),
104 3: buildPlayer(colors.fuschia[400]),
105 4: buildPlayer(colors.orange[400]),
106 5: buildPlayer(colors.purple[400]),
107 6: buildPlayer(colors.teal[400]),
108 7: buildPlayer(colors.pink[400]),
109 8: buildPlayer(colors.yellow[400]),
110};
111
112const editor = {
113 background: backgroundColor[500].base,
114 indent_guide: borderColor.muted,
115 indent_guide_active: borderColor.secondary,
116 line: {
117 active: withOpacity(colors.neutral[900], 0.06),
118 highlighted: withOpacity(colors.neutral[900], 0.12),
119 inserted: backgroundColor.ok.active,
120 deleted: backgroundColor.error.active,
121 modified: backgroundColor.info.active,
122 },
123 highlight: {
124 selection: player[1].selectionColor,
125 occurrence: withOpacity(colors.neutral[900], 0.06),
126 activeOccurrence: withOpacity(colors.neutral[900], 0.16),
127 matchingBracket: colors.neutral[0],
128 match: colors.yellow[100],
129 activeMatch: colors.yellow[200],
130 related: colors.neutral[0],
131 },
132 gutter: {
133 primary: colors.neutral[300],
134 active: textColor.active,
135 },
136};
137
138const syntax: Syntax = {
139 primary: {
140 color: colors.neutral[800],
141 weight: fontWeights.normal,
142 },
143 comment: {
144 color: colors.neutral[500],
145 weight: fontWeights.normal,
146 },
147 punctuation: {
148 color: colors.neutral[600],
149 weight: fontWeights.normal,
150 },
151 constant: {
152 color: colors.neutral[800],
153 weight: fontWeights.normal,
154 },
155 keyword: {
156 color: colors.indigo[700],
157 weight: fontWeights.normal,
158 },
159 function: {
160 color: colors.orange[600],
161 weight: fontWeights.normal,
162 },
163 type: {
164 color: colors.yellow[600],
165 weight: fontWeights.normal,
166 },
167 variant: {
168 color: colors.rose[700],
169 weight: fontWeights.normal,
170 },
171 property: {
172 color: colors.emerald[700],
173 weight: fontWeights.normal,
174 },
175 enum: {
176 color: colors.red[500],
177 weight: fontWeights.normal,
178 },
179 operator: {
180 color: colors.red[500],
181 weight: fontWeights.normal,
182 },
183 string: {
184 color: colors.red[500],
185 weight: fontWeights.normal,
186 },
187 number: {
188 color: colors.indigo[500],
189 weight: fontWeights.normal,
190 },
191 boolean: {
192 color: colors.red[500],
193 weight: fontWeights.normal,
194 },
195 predictive: {
196 color: textColor.placeholder,
197 weight: fontWeights.normal,
198 },
199 title: {
200 color: colors.sky[500],
201 weight: fontWeights.bold,
202 },
203 emphasis: {
204 color: textColor.feature,
205 weight: fontWeights.normal,
206 },
207 "emphasis.strong": {
208 color: textColor.feature,
209 weight: fontWeights.bold,
210 },
211 linkUri: {
212 color: colors.lime[500],
213 weight: fontWeights.normal,
214 underline: true
215 },
216 linkText: {
217 color: colors.red[500],
218 weight: fontWeights.normal,
219 italic: true
220 },
221};
222
223const shadowAlpha: NumberToken = {
224 value: 0.12,
225 type: "number",
226};
227
228const theme: Theme = {
229 name: "light",
230 backgroundColor,
231 borderColor,
232 textColor,
233 iconColor,
234 editor,
235 syntax,
236 player,
237 shadowAlpha,
238};
239
240export default theme;