+1
-1
apps/main-app/public/components/ui/checkbox.tsx
+1
-1
apps/main-app/public/components/ui/checkbox.tsx
···
12
12
<CheckboxPrimitive.Root
13
13
data-slot="checkbox"
14
14
className={cn(
15
-
"peer border-input dark:bg-input/30 data-[state=checked]:bg-primary data-[state=checked]:text-primary-foreground dark:data-[state=checked]:bg-primary data-[state=checked]:border-primary focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive size-4 shrink-0 rounded-[4px] border shadow-xs transition-shadow outline-none focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50",
15
+
"peer border-border bg-background dark:bg-input/30 data-[state=checked]:bg-primary data-[state=checked]:text-primary-foreground dark:data-[state=checked]:bg-primary data-[state=checked]:border-primary focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive size-4 shrink-0 rounded-[4px] border shadow-xs transition-shadow outline-none focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50",
16
16
className
17
17
)}
18
18
{...props}
+74
-66
apps/main-app/public/index.tsx
+74
-66
apps/main-app/public/index.tsx
···
88
88
89
89
const handleKeyDown = (e: React.KeyboardEvent<HTMLInputElement>) => {
90
90
const navigationKeys = ['ArrowDown', 'ArrowUp', 'PageDown', 'PageUp', 'Enter', 'Escape']
91
-
91
+
92
92
// Mark that we should preserve the index for navigation keys
93
93
if (navigationKeys.includes(e.key)) {
94
94
preserveIndexRef.current = true
···
142
142
setIndex(-1)
143
143
setIsOpen(false)
144
144
onSelect?.(handle)
145
-
145
+
146
146
// Auto-submit the form if enabled
147
147
if (autoSubmit && inputRef.current) {
148
148
const form = inputRef.current.closest('form')
···
236
236
height: 'calc(1.5rem + 12px)',
237
237
borderRadius: '4px',
238
238
cursor: 'pointer',
239
-
backgroundColor: i === index ? 'hsl(var(--accent) / 0.5)' : 'transparent',
239
+
backgroundColor: i === index ? 'color-mix(in oklch, var(--accent) 50%, transparent)' : 'transparent',
240
240
transition: 'background-color 0.1s'
241
241
}}
242
242
onMouseEnter={() => setIndex(i)}
···
246
246
width: '1.5rem',
247
247
height: '1.5rem',
248
248
borderRadius: '50%',
249
-
backgroundColor: 'hsl(var(--muted))',
249
+
backgroundColor: 'var(--muted)',
250
250
overflow: 'hidden',
251
251
flexShrink: 0
252
252
}}
···
255
255
<img
256
256
src={actor.avatar}
257
257
alt=""
258
+
loading="lazy"
258
259
style={{
259
260
display: 'block',
260
261
width: '100%',
···
359
360
360
361
return (
361
362
<>
362
-
<div className="min-h-screen">
363
+
<div className="w-full min-h-screen flex flex-col">
363
364
{/* Header */}
364
-
<header className="border-b border-border/40 bg-background/80 backdrop-blur-sm sticky top-0 z-50">
365
-
<div className="container mx-auto px-4 py-4 flex items-center justify-between">
365
+
<header className="w-full border-b border-border/40 bg-background/80 backdrop-blur-sm sticky top-0 z-50">
366
+
<div className="max-w-6xl w-full mx-auto px-4 h-16 flex items-center justify-between">
366
367
<div className="flex items-center gap-2">
367
368
<img src="/transparent-full-size-ico.png" alt="wisp.place" className="w-8 h-8" />
368
-
<span className="text-xl font-semibold text-foreground">
369
+
<span className="text-lg font-semibold text-foreground">
369
370
wisp.place
370
371
</span>
371
372
</div>
372
-
<div className="flex items-center gap-3">
373
+
<div className="flex items-center gap-4">
374
+
<a
375
+
href="https://docs.wisp.place"
376
+
target="_blank"
377
+
rel="noopener noreferrer"
378
+
className="text-sm text-muted-foreground hover:text-foreground transition-colors"
379
+
>
380
+
Read the Docs
381
+
</a>
373
382
<Button
374
-
variant="ghost"
383
+
variant="outline"
375
384
size="sm"
385
+
className="btn-hover-lift"
376
386
onClick={() => setShowForm(true)}
377
387
>
378
388
Sign In
379
389
</Button>
380
-
<Button
381
-
size="sm"
382
-
className="bg-accent text-accent-foreground hover:bg-accent/90"
383
-
asChild
384
-
>
385
-
<a href="https://docs.wisp.place" target="_blank" rel="noopener noreferrer">
386
-
Read the Docs
387
-
</a>
388
-
</Button>
389
390
</div>
390
391
</div>
391
392
</header>
392
393
393
394
{/* Hero Section */}
394
-
<section className="container mx-auto px-4 py-20 md:py-32">
395
+
<section className="container mx-auto px-4 py-24 md:py-36">
395
396
<div className="max-w-4xl mx-auto text-center">
396
-
<div className="inline-flex items-center gap-2 px-4 py-2 rounded-full bg-accent/10 border border-accent/20 mb-8">
397
-
<span className="w-2 h-2 bg-accent rounded-full animate-pulse"></span>
398
-
<span className="text-sm text-foreground">
399
-
Built on AT Protocol
400
-
</span>
401
-
</div>
402
-
403
-
<h1 className="text-5xl md:text-7xl font-bold text-balance mb-6 leading-tight">
404
-
Your Website.Your Control. Lightning Fast.
397
+
{/* Main Headline */}
398
+
<h1 className="animate-fade-in-up animate-delay-100 text-5xl md:text-7xl font-bold mb-2 leading-tight tracking-tight">
399
+
Deploy Anywhere.
400
+
</h1>
401
+
<h1 className="animate-fade-in-up animate-delay-200 text-5xl md:text-7xl font-bold mb-8 leading-tight tracking-tight text-gradient-animate">
402
+
For Free. Forever.
405
403
</h1>
406
404
407
-
<p className="text-xl md:text-2xl text-muted-foreground text-balance mb-10 leading-relaxed max-w-3xl mx-auto">
408
-
Host static sites in your AT Protocol account. You
409
-
keep ownership and control. We just serve them fast
410
-
through our CDN.
405
+
{/* Subheadline */}
406
+
<p className="animate-fade-in-up animate-delay-300 text-lg md:text-xl text-muted-foreground mb-12 leading-relaxed max-w-2xl mx-auto">
407
+
The easiest way to deploy and orchestrate static sites.
408
+
Push updates instantly. Host on our infrastructure or yours.
409
+
All powered by AT Protocol.
411
410
</p>
412
411
413
-
<div className="max-w-md mx-auto relative">
412
+
{/* CTA Buttons */}
413
+
<div className="animate-fade-in-up animate-delay-400 max-w-lg mx-auto relative">
414
414
<div
415
-
className={`transition-all duration-500 ease-in-out ${
416
-
showForm
417
-
? 'opacity-0 -translate-y-5 pointer-events-none'
418
-
: 'opacity-100 translate-y-0'
419
-
}`}
415
+
className={`transition-all duration-500 ease-in-out ${showForm
416
+
? 'opacity-0 -translate-y-5 pointer-events-none absolute inset-0'
417
+
: 'opacity-100 translate-y-0'
418
+
}`}
420
419
>
421
-
<Button
422
-
size="lg"
423
-
className="bg-primary text-primary-foreground hover:bg-primary/90 text-lg px-8 py-6 w-full"
424
-
onClick={() => setShowForm(true)}
425
-
>
426
-
Log in with AT Proto
427
-
<ArrowRight className="ml-2 w-5 h-5" />
428
-
</Button>
420
+
<div className="flex flex-col sm:flex-row gap-3 justify-center">
421
+
<Button
422
+
size="lg"
423
+
className="bg-foreground text-background hover:bg-foreground/90 text-base px-6 py-5 btn-hover-lift"
424
+
onClick={() => setShowForm(true)}
425
+
>
426
+
<span className="mr-2 font-bold">@</span>
427
+
Deploy with AT
428
+
</Button>
429
+
<Button
430
+
variant="outline"
431
+
size="lg"
432
+
className="text-base px-6 py-5 btn-hover-lift"
433
+
asChild
434
+
>
435
+
<a href="https://docs.wisp.place/cli/" target="_blank" rel="noopener noreferrer">
436
+
<span className="font-mono mr-2 text-muted-foreground">>_</span>
437
+
Install wisp-cli
438
+
</a>
439
+
</Button>
440
+
</div>
429
441
</div>
430
442
431
443
<div
432
-
className={`transition-all duration-500 ease-in-out absolute inset-0 ${
433
-
showForm
434
-
? 'opacity-100 translate-y-0'
435
-
: 'opacity-0 translate-y-5 pointer-events-none'
436
-
}`}
444
+
className={`transition-all duration-500 ease-in-out ${showForm
445
+
? 'opacity-100 translate-y-0'
446
+
: 'opacity-0 translate-y-5 pointer-events-none absolute inset-0'
447
+
}`}
437
448
>
438
449
<form
439
450
onSubmit={async (e) => {
···
494
505
</ActorTypeahead>
495
506
<button
496
507
type="submit"
497
-
className="w-full bg-accent hover:bg-accent/90 text-accent-foreground font-semibold py-4 px-6 text-lg rounded-lg inline-flex items-center justify-center transition-colors"
508
+
className="w-full bg-foreground text-background hover:bg-foreground/90 font-semibold py-4 px-6 text-lg rounded-lg inline-flex items-center justify-center transition-colors btn-hover-lift"
498
509
>
499
510
Continue
500
511
<ArrowRight className="ml-2 w-5 h-5" />
···
518
529
</div>
519
530
<div>
520
531
<h3 className="text-xl font-semibold mb-2">
521
-
Upload your static site
532
+
Drop in your files
522
533
</h3>
523
534
<p className="text-muted-foreground">
524
-
Your HTML, CSS, and JavaScript files are
525
-
stored in your AT Protocol account as
526
-
gzipped blobs and a manifest record.
535
+
Upload your site through our dashboard or push with the CLI.
536
+
Everything gets stored directly in your AT Protocol account.
527
537
</p>
528
538
</div>
529
539
</div>
···
533
543
</div>
534
544
<div>
535
545
<h3 className="text-xl font-semibold mb-2">
536
-
We serve it globally
546
+
We handle the rest
537
547
</h3>
538
548
<p className="text-muted-foreground">
539
-
Wisp.place reads your site from your
540
-
account and delivers it through our CDN
541
-
for fast loading anywhere.
549
+
Your site goes live instantly on our global CDN.
550
+
Custom domains, HTTPS, caching—all automatic.
542
551
</p>
543
552
</div>
544
553
</div>
···
548
557
</div>
549
558
<div>
550
559
<h3 className="text-xl font-semibold mb-2">
551
-
You stay in control
560
+
Push updates instantly
552
561
</h3>
553
562
<p className="text-muted-foreground">
554
-
Update or remove your site anytime
555
-
through your AT Protocol account. No
556
-
lock-in, no middleman ownership.
563
+
Ship changes in seconds. Update through the dashboard,
564
+
run wisp-cli deploy, or wire up your CI/CD pipeline.
557
565
</p>
558
566
</div>
559
567
</div>
···
686
694
</section>
687
695
688
696
{/* Footer */}
689
-
<footer className="border-t border-border/40 bg-muted/20">
697
+
<footer className="border-t border-border/40 bg-muted/20 mt-auto">
690
698
<div className="container mx-auto px-4 py-8">
691
699
<div className="text-center text-sm text-muted-foreground">
692
700
<p>
+212
-39
apps/main-app/public/styles/global.css
+212
-39
apps/main-app/public/styles/global.css
···
6
6
:root {
7
7
color-scheme: light;
8
8
9
-
/* Warm beige background inspired by Sunset design #E9DDD8 */
10
-
--background: oklch(0.90 0.012 35);
11
-
/* Very dark brown text for strong contrast #2A2420 */
12
-
--foreground: oklch(0.18 0.01 30);
9
+
/* Warm beige background inspired by Sunset design */
10
+
--background: oklch(0.92 0.012 35);
11
+
/* Very dark brown text for strong contrast */
12
+
--foreground: oklch(0.15 0.015 30);
13
13
14
-
/* Slightly lighter card background */
15
-
--card: oklch(0.93 0.01 35);
16
-
--card-foreground: oklch(0.18 0.01 30);
14
+
/* Slightly lighter card background for elevation */
15
+
--card: oklch(0.95 0.008 35);
16
+
--card-foreground: oklch(0.15 0.015 30);
17
17
18
-
--popover: oklch(0.93 0.01 35);
19
-
--popover-foreground: oklch(0.18 0.01 30);
18
+
--popover: oklch(0.96 0.006 35);
19
+
--popover-foreground: oklch(0.15 0.015 30);
20
20
21
-
/* Dark brown primary inspired by #645343 */
22
-
--primary: oklch(0.35 0.02 35);
23
-
--primary-foreground: oklch(0.95 0.01 35);
21
+
/* Dark brown primary - darker for better contrast */
22
+
--primary: oklch(0.30 0.025 35);
23
+
--primary-foreground: oklch(0.96 0.008 35);
24
24
25
-
/* Bright pink accent for links #FFAAD2 */
26
-
--accent: oklch(0.78 0.15 345);
27
-
--accent-foreground: oklch(0.18 0.01 30);
25
+
/* Deeper pink accent for better visibility */
26
+
--accent: oklch(0.65 0.18 345);
27
+
--accent-foreground: oklch(0.15 0.015 30);
28
28
29
-
/* Medium taupe secondary inspired by #867D76 */
30
-
--secondary: oklch(0.52 0.015 30);
31
-
--secondary-foreground: oklch(0.95 0.01 35);
29
+
/* Darker taupe secondary for better contrast */
30
+
--secondary: oklch(0.85 0.012 30);
31
+
--secondary-foreground: oklch(0.25 0.02 30);
32
32
33
-
/* Light warm muted background */
33
+
/* Muted areas with better distinction */
34
34
--muted: oklch(0.88 0.01 35);
35
-
--muted-foreground: oklch(0.42 0.015 30);
35
+
--muted-foreground: oklch(0.35 0.02 30);
36
36
37
-
--border: oklch(0.75 0.015 30);
38
-
--input: oklch(0.92 0.01 35);
39
-
--ring: oklch(0.72 0.08 15);
37
+
/* Significantly darker border for visibility */
38
+
--border: oklch(0.65 0.02 30);
39
+
/* Input backgrounds lighter than cards */
40
+
--input: oklch(0.97 0.005 35);
41
+
--ring: oklch(0.55 0.12 345);
40
42
41
-
--destructive: oklch(0.577 0.245 27.325);
42
-
--destructive-foreground: oklch(0.985 0 0);
43
+
--destructive: oklch(0.50 0.20 25);
44
+
--destructive-foreground: oklch(0.98 0 0);
43
45
44
-
--chart-1: oklch(0.78 0.15 345);
46
+
--chart-1: oklch(0.65 0.18 345);
45
47
--chart-2: oklch(0.32 0.04 285);
46
-
--chart-3: oklch(0.56 0.08 220);
47
-
--chart-4: oklch(0.85 0.02 130);
48
-
--chart-5: oklch(0.93 0.03 85);
48
+
--chart-3: oklch(0.50 0.10 220);
49
+
--chart-4: oklch(0.70 0.08 130);
50
+
--chart-5: oklch(0.75 0.06 85);
49
51
50
52
--radius: 0.75rem;
51
-
--sidebar: oklch(0.985 0 0);
52
-
--sidebar-foreground: oklch(0.145 0 0);
53
-
--sidebar-primary: oklch(0.205 0 0);
54
-
--sidebar-primary-foreground: oklch(0.985 0 0);
55
-
--sidebar-accent: oklch(0.97 0 0);
56
-
--sidebar-accent-foreground: oklch(0.205 0 0);
57
-
--sidebar-border: oklch(0.922 0 0);
58
-
--sidebar-ring: oklch(0.708 0 0);
53
+
--sidebar: oklch(0.94 0.008 35);
54
+
--sidebar-foreground: oklch(0.15 0.015 30);
55
+
--sidebar-primary: oklch(0.30 0.025 35);
56
+
--sidebar-primary-foreground: oklch(0.96 0.008 35);
57
+
--sidebar-accent: oklch(0.90 0.01 35);
58
+
--sidebar-accent-foreground: oklch(0.20 0.02 30);
59
+
--sidebar-border: oklch(0.65 0.02 30);
60
+
--sidebar-ring: oklch(0.55 0.12 345);
59
61
}
60
62
61
63
.dark {
···
160
162
* {
161
163
@apply border-border outline-ring/50;
162
164
}
165
+
166
+
html {
167
+
scrollbar-gutter: stable;
168
+
}
169
+
163
170
body {
164
171
@apply bg-background text-foreground;
165
172
}
166
173
}
167
174
168
175
@keyframes arrow-bounce {
169
-
0%, 100% {
176
+
177
+
0%,
178
+
100% {
170
179
transform: translateX(0);
171
180
}
181
+
172
182
50% {
173
183
transform: translateX(4px);
174
184
}
···
189
199
border-radius: 0.5rem;
190
200
padding: 1rem;
191
201
overflow-x: auto;
192
-
border: 1px solid hsl(var(--border));
202
+
border: 1px solid var(--border);
193
203
}
194
204
195
205
.shiki-wrapper pre {
196
206
margin: 0 !important;
197
207
padding: 0 !important;
198
208
}
209
+
210
+
/* ========== Landing Page Animations ========== */
211
+
212
+
/* Animated gradient for headline text */
213
+
@keyframes gradient-shift {
214
+
215
+
0%,
216
+
100% {
217
+
background-position: 0% 50%;
218
+
}
219
+
220
+
50% {
221
+
background-position: 100% 50%;
222
+
}
223
+
}
224
+
225
+
.text-gradient-animate {
226
+
background: linear-gradient(90deg,
227
+
oklch(0.55 0.22 350),
228
+
oklch(0.60 0.24 10),
229
+
oklch(0.55 0.22 350));
230
+
background-size: 200% auto;
231
+
-webkit-background-clip: text;
232
+
background-clip: text;
233
+
-webkit-text-fill-color: transparent;
234
+
animation: gradient-shift 4s ease-in-out infinite;
235
+
}
236
+
237
+
.dark .text-gradient-animate {
238
+
background: linear-gradient(90deg,
239
+
oklch(0.75 0.12 295),
240
+
oklch(0.85 0.10 5),
241
+
oklch(0.75 0.12 295));
242
+
background-size: 200% auto;
243
+
-webkit-background-clip: text;
244
+
background-clip: text;
245
+
-webkit-text-fill-color: transparent;
246
+
}
247
+
248
+
/* Floating/breathing animation for hero elements */
249
+
@keyframes float {
250
+
251
+
0%,
252
+
100% {
253
+
transform: translateY(0);
254
+
}
255
+
256
+
50% {
257
+
transform: translateY(-8px);
258
+
}
259
+
}
260
+
261
+
.animate-float {
262
+
animation: float 3s ease-in-out infinite;
263
+
}
264
+
265
+
.animate-float-delayed {
266
+
animation: float 3s ease-in-out infinite;
267
+
animation-delay: 0.5s;
268
+
}
269
+
270
+
/* Staggered fade-in animation */
271
+
@keyframes fade-in-up {
272
+
from {
273
+
opacity: 0;
274
+
transform: translateY(20px);
275
+
}
276
+
277
+
to {
278
+
opacity: 1;
279
+
transform: translateY(0);
280
+
}
281
+
}
282
+
283
+
.animate-fade-in-up {
284
+
animation: fade-in-up 0.6s ease-out forwards;
285
+
opacity: 0;
286
+
}
287
+
288
+
.animate-delay-100 {
289
+
animation-delay: 0.1s;
290
+
}
291
+
292
+
.animate-delay-200 {
293
+
animation-delay: 0.2s;
294
+
}
295
+
296
+
.animate-delay-300 {
297
+
animation-delay: 0.3s;
298
+
}
299
+
300
+
.animate-delay-400 {
301
+
animation-delay: 0.4s;
302
+
}
303
+
304
+
.animate-delay-500 {
305
+
animation-delay: 0.5s;
306
+
}
307
+
308
+
.animate-delay-600 {
309
+
animation-delay: 0.6s;
310
+
}
311
+
312
+
/* Terminal cursor blink */
313
+
@keyframes cursor-blink {
314
+
315
+
0%,
316
+
50% {
317
+
opacity: 1;
318
+
}
319
+
320
+
51%,
321
+
100% {
322
+
opacity: 0;
323
+
}
324
+
}
325
+
326
+
.animate-cursor-blink {
327
+
animation: cursor-blink 1s step-end infinite;
328
+
}
329
+
330
+
/* Button hover scale effect */
331
+
.btn-hover-lift {
332
+
transition: all 0.2s ease-out;
333
+
}
334
+
335
+
.btn-hover-lift:hover {
336
+
transform: translateY(-2px);
337
+
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
338
+
}
339
+
340
+
.btn-hover-lift:active {
341
+
transform: translateY(0);
342
+
}
343
+
344
+
/* Subtle pulse for feature dots */
345
+
@keyframes dot-pulse {
346
+
347
+
0%,
348
+
100% {
349
+
transform: scale(1);
350
+
opacity: 1;
351
+
}
352
+
353
+
50% {
354
+
transform: scale(1.2);
355
+
opacity: 0.8;
356
+
}
357
+
}
358
+
359
+
.animate-dot-pulse {
360
+
animation: dot-pulse 2s ease-in-out infinite;
361
+
}
362
+
363
+
.animate-dot-pulse-delayed-1 {
364
+
animation: dot-pulse 2s ease-in-out infinite;
365
+
animation-delay: 0.3s;
366
+
}
367
+
368
+
.animate-dot-pulse-delayed-2 {
369
+
animation: dot-pulse 2s ease-in-out infinite;
370
+
animation-delay: 0.6s;
371
+
}
+15
-15
docs/src/styles/custom.css
+15
-15
docs/src/styles/custom.css
···
5
5
/* Increase base font size by 10% */
6
6
font-size: 110%;
7
7
8
-
/* Light theme - Warm beige background from app */
9
-
--sl-color-bg: oklch(0.90 0.012 35);
10
-
--sl-color-bg-sidebar: oklch(0.93 0.01 35);
11
-
--sl-color-bg-nav: oklch(0.93 0.01 35);
12
-
--sl-color-text: oklch(0.18 0.01 30);
13
-
--sl-color-text-accent: oklch(0.78 0.15 345);
14
-
--sl-color-accent: oklch(0.78 0.15 345);
15
-
--sl-color-accent-low: oklch(0.95 0.03 345);
16
-
--sl-color-border: oklch(0.75 0.015 30);
17
-
--sl-color-gray-1: oklch(0.52 0.015 30);
18
-
--sl-color-gray-2: oklch(0.42 0.015 30);
19
-
--sl-color-gray-3: oklch(0.33 0.015 30);
20
-
--sl-color-gray-4: oklch(0.25 0.015 30);
21
-
--sl-color-gray-5: oklch(0.75 0.015 30);
8
+
/* Light theme - Warm beige with improved contrast */
9
+
--sl-color-bg: oklch(0.92 0.012 35);
10
+
--sl-color-bg-sidebar: oklch(0.95 0.008 35);
11
+
--sl-color-bg-nav: oklch(0.95 0.008 35);
12
+
--sl-color-text: oklch(0.15 0.015 30);
13
+
--sl-color-text-accent: oklch(0.65 0.18 345);
14
+
--sl-color-accent: oklch(0.65 0.18 345);
15
+
--sl-color-accent-low: oklch(0.92 0.05 345);
16
+
--sl-color-border: oklch(0.65 0.02 30);
17
+
--sl-color-gray-1: oklch(0.45 0.02 30);
18
+
--sl-color-gray-2: oklch(0.35 0.02 30);
19
+
--sl-color-gray-3: oklch(0.28 0.02 30);
20
+
--sl-color-gray-4: oklch(0.20 0.015 30);
21
+
--sl-color-gray-5: oklch(0.65 0.02 30);
22
22
--sl-color-bg-accent: oklch(0.88 0.01 35);
23
23
}
24
24
···
70
70
/* Sidebar active/hover state text contrast fix */
71
71
.sidebar a[aria-current="page"],
72
72
.sidebar a[aria-current="page"] span {
73
-
color: oklch(0.23 0.015 285) !important;
73
+
color: oklch(0.15 0.015 30) !important;
74
74
}
75
75
76
76
[data-theme="dark"] .sidebar a[aria-current="page"],