Skip to content

Commit 13e8770

Browse files
authored
Feat/themes (#205)
* feat(app) add themes page * feat(themes) add all retro themes * feat: add theme copy dialog and refactor theme management with TypeScript enums * style: update calendar sizing, code snippet layout and theme selector text colors * style: update theme selector UI and adjust accent color values across themes * style: adjust accent and muted color values in dark and light themes
1 parent c52bb64 commit 13e8770

File tree

12 files changed

+1069
-187
lines changed

12 files changed

+1069
-187
lines changed

app/docs/components/code-snippet.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,10 @@ export default function CodeSnippet({
2525
}
2626

2727
return (
28-
<div className="rounded-lg overflow-hidden border border-zinc-800 break-all">
29-
<div className="bg-[#121212] text-white flex justify-between px-2 pl-4 py-2">
28+
<div className="bg-[#121212] rounded-lg overflow-hidden border border-zinc-800 break-all max-h-[400px] overflow-y-scroll overflow-x-auto">
29+
<div className="text-white flex justify-between px-2 pl-4 py-2">
3030
<pre className="text-sm flex items-center">
31-
<code className="text-white whitespace-pre-wrap">{children}</code>
31+
<code className="text-white text-nowrap">{children}</code>
3232
</pre>
3333

3434
<Button variant="ghost" size="icon" onClick={handleCopy}>

app/globals.css

Lines changed: 344 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,3 +120,347 @@
120120
@apply bg-background text-foreground;
121121
}
122122
}
123+
124+
.theme-default {
125+
--radius: 0rem;
126+
--background: oklch(1 0 0);
127+
--foreground: oklch(0.141 0.005 285.823);
128+
--card: oklch(1 0 0);
129+
--card-foreground: oklch(0.141 0.005 285.823);
130+
--popover: oklch(1 0 0);
131+
--popover-foreground: oklch(0.141 0.005 285.823);
132+
--primary: oklch(0.795 0.184 86.047);
133+
--primary-foreground: oklch(0.421 0.095 57.708);
134+
--secondary: oklch(0.967 0.001 286.375);
135+
--secondary-foreground: oklch(0.21 0.006 285.885);
136+
--muted: oklch(0.967 0.001 286.375);
137+
--muted-foreground: oklch(0.552 0.016 285.938);
138+
--accent: oklch(0.967 0.001 286.375);
139+
--accent-foreground: oklch(0.21 0.006 285.885);
140+
--destructive: oklch(0.577 0.245 27.325);
141+
--border: oklch(0.92 0.004 286.32);
142+
--input: oklch(0.92 0.004 286.32);
143+
--ring: oklch(0.795 0.184 86.047);
144+
--chart-1: oklch(0.795 0.184 86.047);
145+
--chart-2: oklch(0.421 0.095 57.708);
146+
--chart-3: oklch(0.398 0.07 227.392);
147+
--chart-4: oklch(0.828 0.189 84.429);
148+
--chart-5: oklch(0.769 0.188 70.08);
149+
--sidebar: oklch(0.985 0 0);
150+
--sidebar-foreground: oklch(0.141 0.005 285.823);
151+
--sidebar-primary: oklch(0.795 0.184 86.047);
152+
--sidebar-primary-foreground: oklch(0.421 0.095 57.708);
153+
--sidebar-accent: oklch(0.967 0.001 286.375);
154+
--sidebar-accent-foreground: oklch(0.21 0.006 285.885);
155+
--sidebar-border: oklch(0.92 0.004 286.32);
156+
--sidebar-ring: oklch(0.795 0.184 86.047);
157+
158+
@variant dark {
159+
--background: oklch(0.141 0.005 285.823);
160+
--foreground: oklch(0.985 0 0);
161+
--card: oklch(0.21 0.006 285.885);
162+
--card-foreground: oklch(0.985 0 0);
163+
--popover: oklch(0.21 0.006 285.885);
164+
--popover-foreground: oklch(0.985 0 0);
165+
--primary: oklch(0.795 0.184 86.047);
166+
--primary-foreground: oklch(0.421 0.095 57.708);
167+
--secondary: oklch(0.274 0.006 286.033);
168+
--secondary-foreground: oklch(0.985 0 0);
169+
--muted: oklch(0.274 0.006 286.033);
170+
--muted-foreground: oklch(0.705 0.015 286.067);
171+
--accent: oklch(0.274 0.006 286.033);
172+
--accent-foreground: oklch(0.985 0 0);
173+
--destructive: oklch(0.704 0.191 22.216);
174+
--border: oklch(1 0 0 / 10%);
175+
--input: oklch(1 0 0 / 15%);
176+
--ring: oklch(0.554 0.135 66.442);
177+
--chart-1: oklch(0.795 0.184 86.047);
178+
--chart-2: oklch(0.421 0.095 57.708);
179+
--chart-3: oklch(0.769 0.188 70.08);
180+
--chart-4: oklch(0.627 0.265 303.9);
181+
--chart-5: oklch(0.645 0.246 16.439);
182+
--sidebar: oklch(0.21 0.006 285.885);
183+
--sidebar-foreground: oklch(0.985 0 0);
184+
--sidebar-primary: oklch(0.795 0.184 86.047);
185+
--sidebar-primary-foreground: oklch(0.421 0.095 57.708);
186+
--sidebar-accent: oklch(0.274 0.006 286.033);
187+
--sidebar-accent-foreground: oklch(0.985 0 0);
188+
--sidebar-border: oklch(1 0 0 / 10%);
189+
--sidebar-ring: oklch(0.554 0.135 66.442);
190+
}
191+
}
192+
193+
.theme-sega {
194+
--radius: 0rem;
195+
--primary: oklch(0.5 0.2 260);
196+
--primary-foreground: oklch(0.9 0.02 260);
197+
--background: oklch(0.85 0.1 220);
198+
--foreground: oklch(0.1 0.1 280);
199+
--card: oklch(0.85 0.1 220);
200+
--card-foreground: oklch(0.1 0.1 280);
201+
--popover: oklch(0.85 0.1 220);
202+
--popover-foreground: oklch(0.9 0.02 260);
203+
--secondary: oklch(0.5 0.2 260);
204+
--secondary-foreground: oklch(0.9 0.02 260);
205+
--muted: oklch(0.1 0.1 280);
206+
--muted-foreground: oklch(0.5 0.2 280);
207+
--accent: oklch(0.5 0.2 260);
208+
--accent-foreground: oklch(1 0 0);
209+
--destructive: oklch(0.6 0.2 20);
210+
--border: oklch(0.5 0.2 260);
211+
--input: oklch(0.5 0.2 260);
212+
--ring: oklch(0.5 0.2 260);
213+
--chart-1: oklch(0.5 0.2 260);
214+
--chart-2: oklch(0.3 0.2 260);
215+
--chart-3: oklch(0.7 0.1 250);
216+
--chart-4: oklch(0.6 0.15 250);
217+
--chart-5: oklch(0.4 0.15 250);
218+
--sidebar: oklch(0.2 0 0);
219+
--sidebar-foreground: oklch(0.1 0.1 280);
220+
--sidebar-primary: oklch(0.4 0.15 250);
221+
--sidebar-primary-foreground: oklch(0.1 0.1 280);
222+
--sidebar-accent: oklch(0.5 0.2 280);
223+
--sidebar-accent-foreground: oklch(1 0 0);
224+
--sidebar-border: oklch(0.3 0 0);
225+
--sidebar-ring: oklch(0.4 0.15 250);
226+
227+
@variant dark {
228+
--primary: oklch(0.5 0.2 260);
229+
--primary-foreground: oklch(0.9 0.02 260);
230+
--background: oklch(0.1 0.1 280);
231+
--foreground: oklch(0.9 0.02 260);
232+
--card: oklch(0.1 0.1 280);
233+
--card-foreground: oklch(0.9 0.02 260);
234+
--popover: oklch(0.1 0.1 280);
235+
--popover-foreground: oklch(0.9 0.02 260);
236+
--secondary: oklch(0.5 0.2 260);
237+
--secondary-foreground: oklch(0.9 0.02 260);
238+
--muted: oklch(0.5 0.2 260);
239+
--muted-foreground: oklch(0.85 0.1 220);
240+
--accent: oklch(0.5 0.2 260);
241+
--accent-foreground: oklch(1 0 0);
242+
--destructive: oklch(0.5 0.2 20);
243+
--border: oklch(0.5 0.2 260);
244+
--input: oklch(0.5 0.2 260);
245+
--ring: oklch(0.5 0.2 260);
246+
--chart-1: oklch(0.5 0.2 260);
247+
--chart-2: oklch(0.3 0.2 260);
248+
--chart-3: oklch(0.5 0.2 280);
249+
--chart-4: oklch(0.4 0.2 250);
250+
--chart-5: oklch(0.4 0.15 250);
251+
--sidebar: oklch(0.15 0 0);
252+
--sidebar-foreground: oklch(0.9 0.02 260);
253+
--sidebar-primary: oklch(0.4 0.15 250);
254+
--sidebar-primary-foreground: oklch(0.9 0.02 260);
255+
--sidebar-accent: oklch(0.5 0.2 280);
256+
--sidebar-accent-foreground: oklch(1 0 0);
257+
--sidebar-border: oklch(0.5 0.2 260);
258+
--sidebar-ring: oklch(0.4 0.15 250);
259+
}
260+
}
261+
262+
.theme-nintendo {
263+
--radius: 0rem;
264+
--primary: oklch(0.5 0.2 280);
265+
--primary-foreground: oklch(0 0 0);
266+
--background: oklch(1 0 0);
267+
--foreground: oklch(0 0 0);
268+
--card: oklch(1 0 0);
269+
--card-foreground: oklch(0 0 0);
270+
--popover: oklch(1 0 0);
271+
--popover-foreground: oklch(0 0 0);
272+
--secondary: oklch(0.7 0 0);
273+
--secondary-foreground: oklch(0 0 0);
274+
--muted: oklch(0.7 0 0);
275+
--muted-foreground: oklch(0.4 0 0);
276+
--accent: oklch(0.7 0.1 260);
277+
--accent-foreground: oklch(1 0 0);
278+
--destructive: oklch(0.5 0.2 10);
279+
--border: oklch(0.5 0.2 280);
280+
--input: oklch(0.5 0.2 280);
281+
--ring: oklch(0.5 0.2 280);
282+
--chart-1: oklch(0.7 0 0);
283+
--chart-2: oklch(0.5 0.2 280);
284+
--chart-3: oklch(0.7 0 0);
285+
--chart-4: oklch(0.4 0 0);
286+
--chart-5: oklch(0.5 0.2 280);
287+
--sidebar: oklch(0.9 0 0);
288+
--sidebar-foreground: oklch(0 0 0);
289+
--sidebar-primary: oklch(0.5 0.2 280);
290+
--sidebar-primary-foreground: oklch(0 0 0);
291+
--sidebar-accent: oklch(0.7 0.1 260);
292+
--sidebar-accent-foreground: oklch(1 0 0);
293+
--sidebar-border: oklch(0.7 0 0);
294+
--sidebar-ring: oklch(0.5 0.2 280);
295+
296+
@variant dark {
297+
--primary: oklch(0.5 0.2 280);
298+
--primary-foreground: oklch(0.9 0.05 280);
299+
--background: oklch(0 0 0);
300+
--foreground: oklch(1 0 0);
301+
--card: oklch(0.5 0.2 280);
302+
--popover: oklch(0.5 0.2 280);
303+
--popover-foreground: oklch(1 0 0);
304+
--secondary: oklch(0.4 0 0);
305+
--secondary-foreground: oklch(1 0 0);
306+
--muted: oklch(0.4 0 0);
307+
--muted-foreground: oklch(0.7 0 0);
308+
--accent: oklch(0.4 0.2 280);
309+
--accent-foreground: oklch(1 0 0);
310+
--destructive: oklch(0.4 0.2 10);
311+
--border: oklch(1 0 0);
312+
--input: oklch(0.5 0.2 280);
313+
--ring: oklch(0.7 0.15 250);
314+
--chart-1: oklch(0 0 0);
315+
--chart-2: oklch(0.2 0 0);
316+
--chart-3: oklch(0.4 0 0);
317+
--chart-4: oklch(0.4 0.2 10);
318+
--chart-5: oklch(0.5 0.2 280);
319+
--sidebar: oklch(0.4 0 0);
320+
--sidebar-foreground: oklch(0.9 0.05 280);
321+
--sidebar-primary: oklch(0.5 0.2 280);
322+
--sidebar-primary-foreground: oklch(0.9 0.05 280);
323+
--sidebar-accent: oklch(0.7 0.1 260);
324+
--sidebar-accent-foreground: oklch(1 0 0);
325+
--sidebar-border: oklch(0.4 0 0);
326+
--sidebar-ring: oklch(0.5 0.2 280);
327+
}
328+
}
329+
330+
.theme-gameboy {
331+
--radius: 0rem;
332+
--primary: oklch(0.7 0.2 120);
333+
--primary-foreground: oklch(0.2 0.1 140);
334+
--background: oklch(0.8 0.2 140);
335+
--foreground: oklch(0.2 0.1 140);
336+
--card: oklch(0.8 0.2 140);
337+
--card-foreground: oklch(0.2 0.1 140);
338+
--popover: oklch(0.8 0.2 140);
339+
--popover-foreground: oklch(0.2 0.1 140);
340+
--secondary: oklch(0.7 0.2 120);
341+
--secondary-foreground: oklch(0.2 0.1 140);
342+
--muted: oklch(0.7 0.2 120);
343+
--muted-foreground: oklch(0.2 0.1 140);
344+
--accent: oklch(0.3 0.2 140);
345+
--accent-foreground: oklch(0.8 0.2 120);
346+
--destructive: oklch(0.5 0.3 30);
347+
--border: oklch(0.4 0.2 140);
348+
--input: oklch(0.4 0.2 140);
349+
--ring: oklch(0.8 0.2 120);
350+
--chart-1: oklch(0.4 0.2 140);
351+
--chart-2: oklch(0.3 0.2 140);
352+
--chart-3: oklch(0.4 0.2 140);
353+
--chart-4: oklch(0.4 0.2 140);
354+
--chart-5: oklch(0.4 0.2 140);
355+
--sidebar: oklch(0.8 0.2 140);
356+
--sidebar-foreground: oklch(0.2 0.1 140);
357+
--sidebar-primary: oklch(0.8 0.2 120);
358+
--sidebar-primary-foreground: oklch(0.2 0.1 140);
359+
--sidebar-accent: oklch(0.7 0.2 120);
360+
--sidebar-accent-foreground: oklch(0.2 0.1 140);
361+
--sidebar-border: oklch(0.4 0.2 140);
362+
--sidebar-ring: oklch(0.8 0.2 120);
363+
364+
@variant dark {
365+
--primary: oklch(0.7 0.2 120);
366+
--primary-foreground: oklch(0.2 0.1 140);
367+
--background: oklch(0.2 0.1 140);
368+
--foreground: oklch(0.8 0.2 120);
369+
--card: oklch(0.2 0.1 140);
370+
--card-foreground: oklch(0.8 0.2 120);
371+
--popover: oklch(0.2 0.1 140);
372+
--popover-foreground: oklch(0.8 0.2 120);
373+
--secondary: oklch(0.3 0.1 140);
374+
--secondary-foreground: oklch(0.8 0.2 120);
375+
--muted: oklch(0.3 0.1 140);
376+
--muted-foreground: oklch(0.7 0.2 120);
377+
--accent: oklch(0.4 0.2 140);
378+
--accent-foreground: oklch(0.8 0.2 120);
379+
--destructive: oklch(0.5 0.3 30);
380+
--border: oklch(0.4 0.2 140);
381+
--input: oklch(0.4 0.2 140);
382+
--ring: oklch(0.8 0.2 120);
383+
--chart-1: oklch(0.4 0.2 140);
384+
--chart-2: oklch(0.3 0.2 140);
385+
--chart-3: oklch(0.4 0.2 140);
386+
--chart-4: oklch(0.4 0.2 140);
387+
--chart-5: oklch(0.4 0.2 140);
388+
--sidebar: oklch(0.2 0.1 140);
389+
--sidebar-foreground: oklch(0.8 0.2 120);
390+
--sidebar-primary: oklch(0.4 0.2 140);
391+
--sidebar-primary-foreground: oklch(0.8 0.2 120);
392+
--sidebar-accent: oklch(0.3 0.1 140);
393+
--sidebar-accent-foreground: oklch(0.8 0.2 120);
394+
--sidebar-border: oklch(0.4 0.2 140);
395+
--sidebar-ring: oklch(0.8 0.2 120);
396+
}
397+
}
398+
399+
.theme-atari {
400+
--radius: 0rem;
401+
--primary: oklch(0.5 0.2 60);
402+
--primary-foreground: oklch(0 0 0);
403+
--background: oklch(0.7 0 0);
404+
--foreground: oklch(0 0 0);
405+
--card: oklch(1 0 0);
406+
--card-foreground: oklch(0 0 0);
407+
--popover: oklch(1 0 0);
408+
--popover-foreground: oklch(0 0 0);
409+
--secondary: oklch(0.7 0 0);
410+
--secondary-foreground: oklch(0 0 0);
411+
--muted: oklch(0.7 0 0);
412+
--muted-foreground: oklch(0 0 0);
413+
--accent: oklch(0.5 0.2 60);
414+
--accent-foreground: oklch(1 0 0);
415+
--destructive: oklch(0.5 0.3 20);
416+
--border: oklch(0.5 0.2 60);
417+
--input: oklch(0.7 0 0);
418+
--ring: oklch(0.7 0 0);
419+
--chart-1: oklch(0.7 0 0);
420+
--chart-2: oklch(0.5 0.2 60);
421+
--chart-3: oklch(0.9 0 0);
422+
--chart-4: oklch(0.7 0 0);
423+
--chart-5: oklch(0.5 0.3 280);
424+
--sidebar: oklch(0.9 0 0);
425+
--sidebar-foreground: oklch(0 0 0);
426+
--sidebar-primary: oklch(0.5 0.3 280);
427+
--sidebar-primary-foreground: oklch(0 0 0);
428+
--sidebar-accent: oklch(0.6 0.3 30);
429+
--sidebar-accent-foreground: oklch(1 0 0);
430+
--sidebar-border: oklch(0.7 0 0);
431+
--sidebar-ring: oklch(0.5 0.3 280);
432+
433+
@variant dark {
434+
--primary: oklch(0.4 0.2 60);
435+
--primary-foreground: oklch(0.9 0 0);
436+
--background: oklch(0.2 0 0);
437+
--foreground: oklch(0.9 0 0);
438+
--card: oklch(0.4 0 0);
439+
--card-foreground: oklch(0.9 0 0);
440+
--popover: oklch(0.4 0 0);
441+
--popover-foreground: oklch(0.9 0 0);
442+
--secondary: oklch(0.4 0 0);
443+
--secondary-foreground: oklch(0.9 0 0);
444+
--muted: oklch(0.4 0 0);
445+
--muted-foreground: oklch(0.7 0 0);
446+
--accent: oklch(0.4 0.2 60);
447+
--accent-foreground: oklch(1 0 0);
448+
--destructive: oklch(0.4 0.3 20);
449+
--border: oklch(0.4 0 0);
450+
--input: oklch(0.4 0 0);
451+
--ring: oklch(0 0 0);
452+
--chart-1: oklch(0 0 0);
453+
--chart-2: oklch(0.4 0.2 60);
454+
--chart-3: oklch(0.7 0 0);
455+
--chart-4: oklch(0.4 0 0);
456+
--chart-5: oklch(0.5 0.3 280);
457+
--sidebar: oklch(0.4 0 0);
458+
--sidebar-foreground: oklch(0.9 0 0);
459+
--sidebar-primary: oklch(0.5 0.3 280);
460+
--sidebar-primary-foreground: oklch(0.9 0 0);
461+
--sidebar-accent: oklch(0.5 0.3 20);
462+
--sidebar-accent-foreground: oklch(1 0 0);
463+
--sidebar-border: oklch(0.4 0 0);
464+
--sidebar-ring: oklch(0.5 0.3 280);
465+
}
466+
}

app/layout.tsx

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import { Analytics } from "@vercel/analytics/react"
77

88
import { sharedMetaData } from "@/lib/metadata"
99
import { Toaster } from "@/components/ui/sonner"
10+
import { ActiveThemeProvider } from "@/components/active-theme"
1011
import { ScreenSize } from "@/components/screen-size"
1112
import SiteFooter from "@/components/site-footer"
1213
import { SiteHeader } from "@/components/site-header"
@@ -42,14 +43,16 @@ export default function RootLayout({
4243
enableSystem
4344
disableTransitionOnChange
4445
>
45-
<SiteHeader />
46-
<div className="flex-1 border-l border-r border-dashed max-w-[1400px] mx-auto w-full">
47-
{children}
48-
</div>
49-
<SiteFooter />
50-
<Toaster />
51-
<Analytics />
52-
{process.env.APP_ENV === "development" && <ScreenSize />}
46+
<ActiveThemeProvider>
47+
<SiteHeader />
48+
<div className="flex-1 border-l border-r border-dashed max-w-[1400px] mx-auto w-full">
49+
{children}
50+
</div>
51+
<SiteFooter />
52+
<Toaster />
53+
<Analytics />
54+
{process.env.APP_ENV === "development" && <ScreenSize />}
55+
</ActiveThemeProvider>
5356
</ThemeProvider>
5457
</body>
5558
</html>

0 commit comments

Comments
 (0)