+55
-55
src/app.css
+55
-55
src/app.css
···
8
'Segoe UI Symbol', 'Noto Color Emoji';
9
10
/* Ink - Text colors (adjusted for WCAG AA compliance) */
11
-
--color-ink-50: light-dark(oklch(97.31% 0.015 123.04), oklch(17.39% 0.023 124.58));
12
-
--color-ink-100: light-dark(oklch(93% 0.032 124.47), oklch(24.9% 0.042 126.8));
13
-
--color-ink-200: light-dark(oklch(85% 0.061 123.88), oklch(38.03% 0.07 126.15));
14
-
--color-ink-300: light-dark(oklch(75% 0.093 124.99), oklch(50.28% 0.098 126.82));
15
-
--color-ink-400: light-dark(oklch(65% 0.123 125.63), oklch(61.88% 0.124 126.72));
16
-
--color-ink-500: light-dark(oklch(55% 0.149 127.03), oklch(72.9% 0.149 127.03));
17
-
--color-ink-600: light-dark(oklch(45% 0.124 126.72), oklch(78.19% 0.123 125.63));
18
-
--color-ink-700: light-dark(oklch(35% 0.098 126.82), oklch(83.5% 0.093 124.99));
19
-
--color-ink-800: light-dark(oklch(25% 0.07 126.15), oklch(88.94% 0.061 123.88));
20
-
--color-ink-900: light-dark(oklch(18% 0.042 126.8), oklch(94.52% 0.032 124.47));
21
-
--color-ink-950: light-dark(oklch(12% 0.023 124.58), oklch(97.31% 0.015 123.04));
22
23
/* Canvas - Background colors (adjusted for better contrast) */
24
-
--color-canvas-50: light-dark(oklch(98.5% 0.01 123.97), oklch(17.69% 0.027 125.57));
25
-
--color-canvas-100: light-dark(oklch(96.5% 0.02 123.69), oklch(25.56% 0.047 126.44));
26
-
--color-canvas-200: light-dark(oklch(92% 0.045 125.14), oklch(39.36% 0.083 127.85));
27
-
--color-canvas-300: light-dark(oklch(86% 0.075 125.55), oklch(51.84% 0.112 127.68));
28
-
--color-canvas-400: light-dark(oklch(80% 0.105 126.87), oklch(63.78% 0.141 128.14));
29
-
--color-canvas-500: light-dark(oklch(75.25% 0.135 128.13), oklch(75.25% 0.169 128.13));
30
-
--color-canvas-600: light-dark(oklch(63.78% 0.141 128.14), oklch(80% 0.105 126.87));
31
-
--color-canvas-700: light-dark(oklch(51.84% 0.112 127.68), oklch(86% 0.075 125.55));
32
-
--color-canvas-800: light-dark(oklch(39.36% 0.083 127.85), oklch(92% 0.045 125.14));
33
-
--color-canvas-900: light-dark(oklch(25.56% 0.047 126.44), oklch(96.5% 0.02 123.69));
34
-
--color-canvas-950: light-dark(oklch(17.69% 0.027 125.57), oklch(98.5% 0.01 123.97));
35
36
/* Sage - Primary colors (adjusted for WCAG AA compliance) */
37
-
--color-primary-50: light-dark(oklch(97.73% 0.02 121.83), oklch(18.09% 0.031 123.74));
38
-
--color-primary-100: light-dark(oklch(94% 0.042 123.12), oklch(26.23% 0.053 126.29));
39
-
--color-primary-200: light-dark(oklch(88% 0.082 123.68), oklch(40.39% 0.088 126.72));
40
-
--color-primary-300: light-dark(oklch(78% 0.122 124.71), oklch(53.63% 0.122 127.17));
41
-
--color-primary-400: light-dark(oklch(68% 0.155 125.79), oklch(65.86% 0.152 127.23));
42
-
--color-primary-500: light-dark(oklch(58% 0.182 127.42), oklch(77.77% 0.182 127.42));
43
-
--color-primary-600: light-dark(oklch(48% 0.152 127.23), oklch(81.83% 0.155 125.79));
44
-
--color-primary-700: light-dark(oklch(38% 0.122 127.17), oklch(86.28% 0.122 124.71));
45
-
--color-primary-800: light-dark(oklch(28% 0.088 126.72), oklch(90.67% 0.082 123.68));
46
-
--color-primary-900: light-dark(oklch(20% 0.053 126.29), oklch(95.38% 0.042 123.12));
47
-
--color-primary-950: light-dark(oklch(14% 0.031 123.74), oklch(97.73% 0.02 121.83));
48
49
/* Mint - Secondary colors (adjusted for WCAG AA compliance) */
50
-
--color-secondary-50: light-dark(oklch(97.87% 0.024 121.9), oklch(18.72% 0.037 126.2));
51
-
--color-secondary-100: light-dark(oklch(94.5% 0.048 123.9), oklch(26.82% 0.058 127.38));
52
-
--color-secondary-200: light-dark(oklch(89% 0.097 124.41), oklch(42.08% 0.101 128.02));
53
-
--color-secondary-300: light-dark(oklch(80% 0.141 125.62), oklch(55.72% 0.137 128.49));
54
-
--color-secondary-400: light-dark(oklch(70% 0.178 127.04), oklch(68.58% 0.171 128.75));
55
-
--color-secondary-500: light-dark(oklch(60% 0.205 129.04), oklch(81.09% 0.205 129.04));
56
-
--color-secondary-600: light-dark(oklch(50% 0.171 128.75), oklch(84.3% 0.178 127.04));
57
-
--color-secondary-700: light-dark(oklch(40% 0.137 128.49), oklch(87.99% 0.141 125.62));
58
-
--color-secondary-800: light-dark(oklch(30% 0.101 128.02), oklch(91.89% 0.097 124.41));
59
-
--color-secondary-900: light-dark(oklch(22% 0.058 127.38), oklch(95.73% 0.048 123.9));
60
-
--color-secondary-950: light-dark(oklch(15% 0.037 126.2), oklch(97.87% 0.024 121.9));
61
62
/* Jade - Accent colors (adjusted for WCAG AA compliance) */
63
-
--color-accent-50: light-dark(oklch(98.05% 0.027 122.65), oklch(19.03% 0.041 126.73));
64
-
--color-accent-100: light-dark(oklch(95% 0.056 123.8), oklch(27.78% 0.066 127.71));
65
-
--color-accent-200: light-dark(oklch(90% 0.11 124.83), oklch(43.51% 0.11 128.91));
66
-
--color-accent-300: light-dark(oklch(82% 0.159 126.06), oklch(57.9% 0.149 129.35));
67
-
--color-accent-400: light-dark(oklch(72% 0.198 127.63), oklch(71.44% 0.186 129.59));
68
-
--color-accent-500: light-dark(oklch(62% 0.221 129.75), oklch(84.36% 0.221 129.75));
69
-
--color-accent-600: light-dark(oklch(52% 0.186 129.59), oklch(86.93% 0.198 127.63));
70
-
--color-accent-700: light-dark(oklch(42% 0.149 129.35), oklch(89.79% 0.159 126.06));
71
-
--color-accent-800: light-dark(oklch(32% 0.11 128.91), oklch(92.93% 0.11 124.83));
72
-
--color-accent-900: light-dark(oklch(23% 0.066 127.71), oklch(96.35% 0.056 123.8));
73
-
--color-accent-950: light-dark(oklch(16% 0.041 126.73), oklch(98.05% 0.027 122.65));
74
}
75
76
@layer base {
···
8
'Segoe UI Symbol', 'Noto Color Emoji';
9
10
/* Ink - Text colors (adjusted for WCAG AA compliance) */
11
+
--color-ink-50: light-dark(oklch(17.39% 0.023 124.58), oklch(97.31% 0.015 123.04));
12
+
--color-ink-100: light-dark(oklch(24.9% 0.042 126.8), oklch(93% 0.032 124.47));
13
+
--color-ink-200: light-dark(oklch(38.03% 0.07 126.15), oklch(85% 0.061 123.88));
14
+
--color-ink-300: light-dark(oklch(50.28% 0.098 126.82), oklch(75% 0.093 124.99));
15
+
--color-ink-400: light-dark(oklch(61.88% 0.124 126.72), oklch(65% 0.123 125.63));
16
+
--color-ink-500: light-dark(oklch(72.9% 0.149 127.03), oklch(55% 0.149 127.03));
17
+
--color-ink-600: light-dark(oklch(78.19% 0.123 125.63), oklch(45% 0.124 126.72));
18
+
--color-ink-700: light-dark(oklch(83.5% 0.093 124.99), oklch(35% 0.098 126.82));
19
+
--color-ink-800: light-dark(oklch(88.94% 0.061 123.88), oklch(25% 0.07 126.15));
20
+
--color-ink-900: light-dark(oklch(94.52% 0.032 124.47), oklch(18% 0.042 126.8));
21
+
--color-ink-950: light-dark(oklch(97.31% 0.015 123.04), oklch(12% 0.023 124.58));
22
23
/* Canvas - Background colors (adjusted for better contrast) */
24
+
--color-canvas-50: light-dark(oklch(17.69% 0.027 125.57), oklch(98.5% 0.01 123.97));
25
+
--color-canvas-100: light-dark(oklch(25.56% 0.047 126.44), oklch(96.5% 0.02 123.69));
26
+
--color-canvas-200: light-dark(oklch(39.36% 0.083 127.85), oklch(92% 0.045 125.14));
27
+
--color-canvas-300: light-dark(oklch(51.84% 0.112 127.68), oklch(86% 0.075 125.55));
28
+
--color-canvas-400: light-dark(oklch(63.78% 0.141 128.14), oklch(80% 0.105 126.87));
29
+
--color-canvas-500: light-dark(oklch(75.25% 0.169 128.13), oklch(75.25% 0.135 128.13));
30
+
--color-canvas-600: light-dark(oklch(80% 0.105 126.87), oklch(63.78% 0.141 128.14));
31
+
--color-canvas-700: light-dark(oklch(86% 0.075 125.55), oklch(51.84% 0.112 127.68));
32
+
--color-canvas-800: light-dark(oklch(92% 0.045 125.14), oklch(39.36% 0.083 127.85));
33
+
--color-canvas-900: light-dark(oklch(96.5% 0.02 123.69), oklch(25.56% 0.047 126.44));
34
+
--color-canvas-950: light-dark(oklch(98.5% 0.01 123.97), oklch(17.69% 0.027 125.57));
35
36
/* Sage - Primary colors (adjusted for WCAG AA compliance) */
37
+
--color-primary-50: light-dark(oklch(18.09% 0.031 123.74), oklch(97.73% 0.02 121.83));
38
+
--color-primary-100: light-dark(oklch(26.23% 0.053 126.29), oklch(94% 0.042 123.12));
39
+
--color-primary-200: light-dark(oklch(40.39% 0.088 126.72), oklch(88% 0.082 123.68));
40
+
--color-primary-300: light-dark(oklch(53.63% 0.122 127.17), oklch(78% 0.122 124.71));
41
+
--color-primary-400: light-dark(oklch(65.86% 0.152 127.23), oklch(68% 0.155 125.79));
42
+
--color-primary-500: light-dark(oklch(77.77% 0.182 127.42), oklch(58% 0.182 127.42));
43
+
--color-primary-600: light-dark(oklch(81.83% 0.155 125.79), oklch(48% 0.152 127.23));
44
+
--color-primary-700: light-dark(oklch(86.28% 0.122 124.71), oklch(38% 0.122 127.17));
45
+
--color-primary-800: light-dark(oklch(90.67% 0.082 123.68), oklch(28% 0.088 126.72));
46
+
--color-primary-900: light-dark(oklch(95.38% 0.042 123.12), oklch(20% 0.053 126.29));
47
+
--color-primary-950: light-dark(oklch(97.73% 0.02 121.83), oklch(14% 0.031 123.74));
48
49
/* Mint - Secondary colors (adjusted for WCAG AA compliance) */
50
+
--color-secondary-50: light-dark(oklch(18.72% 0.037 126.2), oklch(97.87% 0.024 121.9));
51
+
--color-secondary-100: light-dark(oklch(26.82% 0.058 127.38), oklch(94.5% 0.048 123.9));
52
+
--color-secondary-200: light-dark(oklch(42.08% 0.101 128.02), oklch(89% 0.097 124.41));
53
+
--color-secondary-300: light-dark(oklch(55.72% 0.137 128.49), oklch(80% 0.141 125.62));
54
+
--color-secondary-400: light-dark(oklch(68.58% 0.171 128.75), oklch(70% 0.178 127.04));
55
+
--color-secondary-500: light-dark(oklch(81.09% 0.205 129.04), oklch(60% 0.205 129.04));
56
+
--color-secondary-600: light-dark(oklch(84.3% 0.178 127.04), oklch(50% 0.171 128.75));
57
+
--color-secondary-700: light-dark(oklch(87.99% 0.141 125.62), oklch(40% 0.137 128.49));
58
+
--color-secondary-800: light-dark(oklch(91.89% 0.097 124.41), oklch(30% 0.101 128.02));
59
+
--color-secondary-900: light-dark(oklch(95.73% 0.048 123.9), oklch(22% 0.058 127.38));
60
+
--color-secondary-950: light-dark(oklch(97.87% 0.024 121.9), oklch(15% 0.037 126.2));
61
62
/* Jade - Accent colors (adjusted for WCAG AA compliance) */
63
+
--color-accent-50: light-dark(oklch(19.03% 0.041 126.73), oklch(98.05% 0.027 122.65));
64
+
--color-accent-100: light-dark(oklch(27.78% 0.066 127.71), oklch(95% 0.056 123.8));
65
+
--color-accent-200: light-dark(oklch(43.51% 0.11 128.91), oklch(90% 0.11 124.83));
66
+
--color-accent-300: light-dark(oklch(57.9% 0.149 129.35), oklch(82% 0.159 126.06));
67
+
--color-accent-400: light-dark(oklch(71.44% 0.186 129.59), oklch(72% 0.198 127.63));
68
+
--color-accent-500: light-dark(oklch(84.36% 0.221 129.75), oklch(62% 0.221 129.75));
69
+
--color-accent-600: light-dark(oklch(86.93% 0.198 127.63), oklch(52% 0.186 129.59));
70
+
--color-accent-700: light-dark(oklch(89.79% 0.159 126.06), oklch(42% 0.149 129.35));
71
+
--color-accent-800: light-dark(oklch(92.93% 0.11 124.83), oklch(32% 0.11 128.91));
72
+
--color-accent-900: light-dark(oklch(96.35% 0.056 123.8), oklch(23% 0.066 127.71));
73
+
--color-accent-950: light-dark(oklch(98.05% 0.027 122.65), oklch(16% 0.041 126.73));
74
}
75
76
@layer base {
+12
-12
src/lib/components/layout/ThemeToggle.svelte
+12
-12
src/lib/components/layout/ThemeToggle.svelte
···
10
const stored = localStorage.getItem('theme');
11
const prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
12
13
-
isDark = stored === 'dark' || (!stored && prefersDark);
14
updateTheme();
15
mounted = true;
16
···
33
const htmlElement = document.documentElement;
34
35
if (isDark) {
36
-
htmlElement.classList.add('dark');
37
-
htmlElement.style.colorScheme = 'dark';
38
-
} else {
39
htmlElement.classList.remove('dark');
40
htmlElement.style.colorScheme = 'light';
41
}
42
}
43
44
function toggleTheme() {
45
isDark = !isDark;
46
-
localStorage.setItem('theme', isDark ? 'dark' : 'light');
47
updateTheme();
48
}
49
</script>
···
51
<button
52
onclick={toggleTheme}
53
class="relative flex h-10 w-10 items-center justify-center rounded-lg bg-canvas-200 text-ink-900 transition-all hover:bg-canvas-300 dark:bg-canvas-800 dark:text-ink-50 dark:hover:bg-canvas-700"
54
-
aria-label={isDark ? 'Switch to light mode' : 'Switch to dark mode'}
55
type="button"
56
>
57
{#if mounted}
58
<div class="relative h-5 w-5">
59
-
<Sun
60
class="absolute inset-0 h-5 w-5 transition-all duration-300 {isDark
61
-
? 'scale-0 rotate-90 opacity-0'
62
-
: 'scale-100 rotate-0 opacity-100'}"
63
aria-hidden="true"
64
/>
65
-
<Moon
66
class="absolute inset-0 h-5 w-5 transition-all duration-300 {isDark
67
-
? 'scale-100 rotate-0 opacity-100'
68
-
: 'scale-0 -rotate-90 opacity-0'}"
69
aria-hidden="true"
70
/>
71
</div>
···
10
const stored = localStorage.getItem('theme');
11
const prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
12
13
+
isDark = stored === 'light' || (!stored && !prefersDark);
14
updateTheme();
15
mounted = true;
16
···
33
const htmlElement = document.documentElement;
34
35
if (isDark) {
36
htmlElement.classList.remove('dark');
37
htmlElement.style.colorScheme = 'light';
38
+
} else {
39
+
htmlElement.classList.add('dark');
40
+
htmlElement.style.colorScheme = 'dark';
41
}
42
}
43
44
function toggleTheme() {
45
isDark = !isDark;
46
+
localStorage.setItem('theme', isDark ? 'light' : 'dark');
47
updateTheme();
48
}
49
</script>
···
51
<button
52
onclick={toggleTheme}
53
class="relative flex h-10 w-10 items-center justify-center rounded-lg bg-canvas-200 text-ink-900 transition-all hover:bg-canvas-300 dark:bg-canvas-800 dark:text-ink-50 dark:hover:bg-canvas-700"
54
+
aria-label={isDark ? 'Switch to dark mode' : 'Switch to light mode'}
55
type="button"
56
>
57
{#if mounted}
58
<div class="relative h-5 w-5">
59
+
<Moon
60
class="absolute inset-0 h-5 w-5 transition-all duration-300 {isDark
61
+
? 'scale-100 rotate-0 opacity-100'
62
+
: 'scale-0 rotate-90 opacity-0'}"
63
aria-hidden="true"
64
/>
65
+
<Sun
66
class="absolute inset-0 h-5 w-5 transition-all duration-300 {isDark
67
+
? 'scale-0 -rotate-90 opacity-0'
68
+
: 'scale-100 rotate-0 opacity-100'}"
69
aria-hidden="true"
70
/>
71
</div>