Skip to content

Commit 8994cc0

Browse files
committed
feat: update website dark theme
1 parent 340e92e commit 8994cc0

9 files changed

Lines changed: 148 additions & 74 deletions

File tree

examples/web/app/components/ButtonsSection.tsx

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ function DemoButton({
2828

2929
return (
3030
<button
31-
className="shrink-0 transition-transform active:translate-y-px"
31+
className="shrink-0 shadow-sm transition-[filter,transform] hover:brightness-110 focus-visible:outline-2 focus-visible:outline-offset-2 active:translate-y-px"
3232
style={{
3333
backgroundColor: background,
3434
color: content,
@@ -41,6 +41,7 @@ function DemoButton({
4141
fontWeight: font?.weight,
4242
letterSpacing: font?.letterSpacing,
4343
lineHeight: font?.lineHeight,
44+
outlineColor: mode.theme.accent,
4445
}}
4546
>
4647
{buttonLabel(spec.variant, spec.size)}
@@ -77,7 +78,7 @@ export function ButtonsSection({
7778
{variant}
7879
</h3>
7980
<div
80-
className="flex flex-col gap-4 rounded-2xl border px-5 py-5 md:flex-row md:items-center md:justify-between"
81+
className="flex flex-col gap-4 rounded-2xl border px-5 py-5 shadow-sm md:flex-row md:items-center md:justify-between"
8182
style={{
8283
backgroundColor: theme.surfaceAlt,
8384
borderColor: theme.border,

examples/web/app/components/ColorCard.tsx

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,12 @@ export function ColorCard({
2121
setCopied(true);
2222
setTimeout(() => setCopied(false), 1200);
2323
}}
24-
className="group flex w-full items-center gap-3 rounded-2xl border px-3 py-3 text-left transition-colors"
24+
className="group flex w-full items-center gap-3 rounded-2xl border px-3 py-3 text-left shadow-sm transition-[background-color,border-color,transform] hover:-translate-y-px focus-visible:outline-2 focus-visible:outline-offset-2"
2525
style={{
2626
backgroundColor: theme.surfaceAlt,
2727
borderColor: theme.border,
2828
color: theme.text,
29+
outlineColor: theme.accent,
2930
}}
3031
>
3132
<div
@@ -37,7 +38,10 @@ export function ColorCard({
3738
/>
3839
<div className="min-w-0 flex-1">
3940
<div className="truncate text-sm font-semibold">{name}</div>
40-
<div className="truncate font-mono text-xs" style={{ color: theme.muted }}>
41+
<div
42+
className="truncate font-mono text-xs"
43+
style={{ color: theme.muted }}
44+
>
4145
{value}
4246
</div>
4347
</div>

examples/web/app/components/ColorPalettes.tsx

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,19 +18,23 @@ export function ColorPalettes({
1818
return (
1919
<div className="space-y-6" style={{ color: theme.text }}>
2020
<div
21-
className="inline-flex flex-wrap rounded-full border p-1"
22-
style={{ borderColor: theme.border }}
21+
className="inline-flex flex-wrap rounded-full border p-1 shadow-sm"
22+
style={{
23+
backgroundColor: theme.surfaceAlt,
24+
borderColor: theme.border,
25+
}}
2326
>
2427
{palettes.map((palette) => {
2528
const isActive = palette.id === selectedPalette.id;
2629
return (
2730
<button
2831
key={palette.id}
29-
className="rounded-full px-3 py-1.5 text-sm font-medium transition-colors"
32+
className="rounded-full px-3 py-1.5 text-sm font-medium transition-[background-color,color,opacity] hover:opacity-75 focus-visible:outline-2 focus-visible:outline-offset-2"
3033
onClick={() => setSelectedPaletteId(palette.id)}
3134
style={{
3235
backgroundColor: isActive ? theme.text : "transparent",
3336
color: isActive ? theme.background : theme.text,
37+
outlineColor: theme.accent,
3438
}}
3539
>
3640
{palette.label}

examples/web/app/components/HeroSection.tsx

Lines changed: 27 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,12 @@ const GITHUB_REPO_URL = "https://github.com/worldcoin/nucleus";
66

77
function GitHubIcon() {
88
return (
9-
<svg viewBox="0 0 16 16" className="h-5 w-5" fill="currentColor" aria-hidden="true">
9+
<svg
10+
viewBox="0 0 16 16"
11+
className="h-5 w-5"
12+
fill="currentColor"
13+
aria-hidden="true"
14+
>
1015
<path d="M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82.64-.18 1.32-.27 2-.27s1.36.09 2 .27c1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15.46.55.38A8.01 8.01 0 0 0 16 8c0-4.42-3.58-8-8-8Z" />
1116
</svg>
1217
);
@@ -33,19 +38,23 @@ export function HeroSection({
3338
<h1 className="text-3xl font-semibold tracking-tight">Nucleus</h1>
3439

3540
<nav
36-
className="inline-flex flex-wrap rounded-full border p-1"
37-
style={{ borderColor: activeTheme.border }}
41+
className="inline-flex flex-wrap rounded-full border p-1 shadow-sm"
42+
style={{
43+
backgroundColor: activeTheme.surface,
44+
borderColor: activeTheme.border,
45+
}}
3846
>
3947
{demoSections.map((section) => {
4048
const isActive = section.id === selectedSectionId;
4149
return (
4250
<button
4351
key={section.id}
44-
className="rounded-full px-3 py-1.5 text-sm font-medium transition-colors"
52+
className="rounded-full px-3 py-1.5 text-sm font-medium transition-[background-color,color,opacity] hover:opacity-75 focus-visible:outline-2 focus-visible:outline-offset-2"
4553
onClick={() => onSelectSection(section.id)}
4654
style={{
4755
backgroundColor: isActive ? activeTheme.text : "transparent",
4856
color: isActive ? activeTheme.background : activeTheme.text,
57+
outlineColor: activeTheme.muted,
4958
}}
5059
>
5160
{section.label}
@@ -57,19 +66,23 @@ export function HeroSection({
5766

5867
<div className="flex items-center gap-3">
5968
<div
60-
className="inline-flex rounded-full border p-1"
61-
style={{ borderColor: activeTheme.border }}
69+
className="inline-flex rounded-full border p-1 shadow-sm"
70+
style={{
71+
backgroundColor: activeTheme.surface,
72+
borderColor: activeTheme.border,
73+
}}
6274
>
6375
{appThemes.map((theme) => {
6476
const isActive = theme.id === activeTheme.id;
6577
return (
6678
<button
6779
key={theme.id}
68-
className="rounded-full px-3 py-1.5 text-sm font-medium transition-colors"
80+
className="rounded-full px-3 py-1.5 text-sm font-medium transition-[background-color,color,opacity] hover:opacity-75 focus-visible:outline-2 focus-visible:outline-offset-2"
6981
onClick={() => onSelectTheme(theme.id)}
7082
style={{
7183
backgroundColor: isActive ? activeTheme.text : "transparent",
7284
color: isActive ? activeTheme.background : activeTheme.text,
85+
outlineColor: activeTheme.muted,
7386
}}
7487
>
7588
{theme.name}
@@ -83,8 +96,13 @@ export function HeroSection({
8396
target="_blank"
8497
rel="noopener noreferrer"
8598
aria-label="Nucleus on GitHub"
86-
className="inline-flex h-10 w-10 items-center justify-center rounded-full border transition-opacity hover:opacity-70"
87-
style={{ borderColor: activeTheme.border, color: activeTheme.text }}
99+
className="inline-flex h-10 w-10 items-center justify-center rounded-full border shadow-sm transition-[background-color,color,opacity] hover:opacity-70 focus-visible:outline-2 focus-visible:outline-offset-2"
100+
style={{
101+
backgroundColor: activeTheme.surface,
102+
borderColor: activeTheme.border,
103+
color: activeTheme.text,
104+
outlineColor: activeTheme.muted,
105+
}}
88106
>
89107
<GitHubIcon />
90108
</a>

examples/web/app/components/IconsSection.tsx

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -42,11 +42,12 @@ function IconCard({
4242
setCopied(true);
4343
setTimeout(() => setCopied(false), 1200);
4444
}}
45-
className="flex flex-col items-center gap-2 rounded-2xl border px-2 py-4 transition-colors"
45+
className="flex flex-col items-center gap-2 rounded-2xl border px-2 py-4 shadow-sm transition-[background-color,border-color,transform] hover:-translate-y-px focus-visible:outline-2 focus-visible:outline-offset-2"
4646
style={{
4747
backgroundColor: theme.surfaceAlt,
4848
borderColor: theme.border,
4949
color: theme.text,
50+
outlineColor: theme.accent,
5051
}}
5152
>
5253
<span
@@ -89,27 +90,32 @@ export function IconsSection({
8990
placeholder={`Search ${icons.length} icons…`}
9091
value={query}
9192
onChange={(event) => setQuery(event.target.value)}
92-
className="w-64 rounded-full border px-4 py-2 text-sm outline-none"
93+
className="w-64 rounded-full border px-4 py-2 text-sm shadow-sm outline-none focus-visible:outline-2 focus-visible:outline-offset-2"
9394
style={{
9495
backgroundColor: theme.surfaceAlt,
9596
borderColor: theme.border,
9697
color: theme.text,
98+
outlineColor: theme.accent,
9799
}}
98100
/>
99101
<div
100-
className="inline-flex rounded-full border p-1"
101-
style={{ borderColor: theme.border }}
102+
className="inline-flex rounded-full border p-1 shadow-sm"
103+
style={{
104+
backgroundColor: theme.surfaceAlt,
105+
borderColor: theme.border,
106+
}}
102107
>
103108
{VARIANTS.map((option) => {
104109
const isActive = option === variant;
105110
return (
106111
<button
107112
key={option}
108-
className="rounded-full px-3 py-1.5 text-sm font-medium capitalize transition-colors"
113+
className="rounded-full px-3 py-1.5 text-sm font-medium capitalize transition-[background-color,color,opacity] hover:opacity-75 focus-visible:outline-2 focus-visible:outline-offset-2"
109114
onClick={() => setVariant(option)}
110115
style={{
111116
backgroundColor: isActive ? theme.text : "transparent",
112117
color: isActive ? theme.background : theme.text,
118+
outlineColor: theme.accent,
113119
}}
114120
>
115121
{option}

examples/web/app/components/TypographySection.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ export function TypographySection({
1414
{styles.map((style) => (
1515
<div
1616
key={style.name}
17-
className="flex flex-col gap-3 rounded-2xl border px-5 py-4 md:flex-row md:items-center"
17+
className="flex flex-col gap-3 rounded-2xl border px-5 py-4 shadow-sm md:flex-row md:items-center"
1818
style={{
1919
backgroundColor: theme.surfaceAlt,
2020
borderColor: theme.border,

examples/web/app/globals.css

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
@import "tailwindcss";
22

33
:root {
4-
--background: #F9FAFB;
5-
--foreground: #17181A;
4+
--background: #f9fafb;
5+
--foreground: #17181a;
66
--muted: #747679;
7-
--border: #EAEBED;
8-
--surface: #FFFFFF;
7+
--border: #eaebed;
8+
--surface: #ffffff;
99
}
1010

1111
@theme inline {
@@ -33,3 +33,13 @@ body {
3333
color: var(--foreground);
3434
font-family: var(--font-sans);
3535
}
36+
37+
button:not(:disabled),
38+
a {
39+
cursor: pointer;
40+
}
41+
42+
input::placeholder {
43+
color: currentColor;
44+
opacity: 0.55;
45+
}

examples/web/app/page.tsx

Lines changed: 22 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -3,32 +3,26 @@
33
import { useEffect, useState } from "react";
44
import { HeroSection } from "./components/HeroSection";
55
import { TokenSectionCard } from "./components/TokenSectionCard";
6-
import type { AppTheme, DemoTheme } from "./models";
6+
import type { AppTheme } from "./models";
77
import { appThemes, demoSections, fontStyles, semanticModes } from "./tokens";
88

9-
function fallbackSectionTheme(theme: AppTheme): DemoTheme {
10-
return {
11-
background: theme.surface,
12-
surface: theme.surface,
13-
surfaceAlt: theme.surface,
14-
border: theme.border,
15-
text: theme.text,
16-
muted: theme.muted,
17-
accent: theme.text,
18-
accentContent: theme.background,
19-
};
20-
}
21-
229
const THEME_STORAGE_KEY = "nucleus-theme";
2310

2411
export default function Home() {
25-
const [selectedSectionId, setSelectedSectionId] = useState(demoSections[0].id);
26-
const [selectedThemeId, setSelectedThemeId] = useState<AppTheme["id"]>("light");
12+
const [selectedSectionId, setSelectedSectionId] = useState(
13+
demoSections[0].id,
14+
);
15+
const [selectedThemeId, setSelectedThemeId] =
16+
useState<AppTheme["id"]>("light");
2717

2818
useEffect(() => {
2919
const stored = window.localStorage.getItem(THEME_STORAGE_KEY);
3020
if (stored === "light" || stored === "dark") {
31-
setSelectedThemeId(stored);
21+
const restoreTheme = window.setTimeout(
22+
() => setSelectedThemeId(stored),
23+
0,
24+
);
25+
return () => window.clearTimeout(restoreTheme);
3226
}
3327
}, []);
3428

@@ -38,19 +32,24 @@ export default function Home() {
3832
};
3933

4034
const selectedSection =
41-
demoSections.find((section) => section.id === selectedSectionId) ?? demoSections[0];
35+
demoSections.find((section) => section.id === selectedSectionId) ??
36+
demoSections[0];
4237
const activeTheme =
4338
appThemes.find((theme) => theme.id === selectedThemeId) ?? appThemes[0];
4439
const activeMode =
45-
semanticModes.find((mode) => mode.id === activeTheme.id) ?? semanticModes[0];
46-
const chromeTheme = fallbackSectionTheme(activeTheme);
40+
semanticModes.find((mode) => mode.id === activeTheme.id) ??
41+
semanticModes[0];
4742

4843
return (
4944
<main
50-
className="min-h-screen"
45+
className="min-h-screen transition-colors duration-300"
5146
style={{
52-
backgroundColor: activeTheme.background,
47+
background:
48+
activeTheme.id === "dark"
49+
? `radial-gradient(ellipse 90% 52% at 50% -12%, ${activeTheme.surface} 0%, ${activeTheme.background} 68%)`
50+
: activeTheme.background,
5351
color: activeTheme.text,
52+
colorScheme: activeTheme.id,
5453
}}
5554
>
5655
<div className="mx-auto flex max-w-7xl flex-col gap-8 px-6 py-8 md:py-10">
@@ -65,7 +64,7 @@ export default function Home() {
6564

6665
<TokenSectionCard
6766
section={selectedSection}
68-
theme={chromeTheme}
67+
theme={activeMode.theme}
6968
mode={activeMode}
7069
fontStyles={fontStyles}
7170
/>

0 commit comments

Comments
 (0)