Themes

Pre-configured color palettes.

Keystone UI provides a collection of base color themes to kickstart your Hugo project.

These themes are based on the original Shadcn UI palettes but have been calibrated to meet WCAG 2.2 AAA contrast requirements between paired values (background vs foreground).

Accessibility Note

While these values serve as a robust foundation, any customizations you make should be re-tested against your desired accessibility level.

(Minimum recommended: WCAG 2.2 AA).

Themes use strictly the OKLCH color space to ensure consistent color changes, allowing lightness and contrast to be adjusted predictably rather than by trial and error.

Instalation

The Keystone Starter includes five pre-installed base palettes in the assets/base/ directory:

  1. Neutral (default)
  2. Gray
  3. Slate
  4. Stone
  5. Zinc

To switch themes, edit your assets/css/main.css file and change the import path:

/assets/css/main.css
1/* Theme Variables */
2- @import './base/_neutral.css';
3+ @import './base/_zinc.css';

To use a different theme from the _neutral.css created in the Get Started: Manual Installation section:

  1. Create a new file in assets/base/ (e.g. _zinc.css).
  2. Copy the CSS code from the list below.
  3. Update your assets/main.css import.
/assets/main.css
1/* Theme Variables */
2- @import './base/_neutral.css';
3+ @import './base/_zinc.css';

Gray: Near-neutral grayscale with minimal chroma.

Tailwind CSS /assets/base/_gray.css
 1:root {
 2  --radius: 0.625rem;
 3  --background: oklch(1 0 0);
 4  --foreground: oklch(0.13 0.028 261.692);
 5  --card: oklch(1 0 0);
 6  --card-foreground: oklch(0.13 0.028 261.692);
 7  --popover: oklch(1 0 0);
 8  --popover-foreground: oklch(0.13 0.028 261.692);
 9  --primary: oklch(0.21 0.034 264.665);
10  --primary-foreground: oklch(0.985 0.002 247.839);
11  --secondary: oklch(0.967 0.003 264.542);
12  --secondary-foreground: oklch(0.21 0.034 264.665);
13  --muted: oklch(0.967 0.003 264.542);
14  --muted-foreground: oklch(0.4397 0.0188 257.25);
15  --accent: oklch(0.967 0.003 264.542);
16  --accent-foreground: oklch(0.21 0.034 264.665);
17  --destructive: oklch(0.577 0.245 27.325);
18  --border: oklch(0.928 0.006 264.531);
19  --input: oklch(0.928 0.006 264.531);
20  --ring: oklch(0.707 0.022 261.325);
21  --chart-1: oklch(0.646 0.222 41.116);
22  --chart-2: oklch(0.6 0.118 184.704);
23  --chart-3: oklch(0.398 0.07 227.392);
24  --chart-4: oklch(0.828 0.189 84.429);
25  --chart-5: oklch(0.769 0.188 70.08);
26  --sidebar: oklch(0.985 0.002 247.839);
27  --sidebar-foreground: oklch(0.13 0.028 261.692);
28  --sidebar-primary: oklch(0.21 0.034 264.665);
29  --sidebar-primary-foreground: oklch(0.985 0.002 247.839);
30  --sidebar-accent: oklch(0.967 0.003 264.542);
31  --sidebar-accent-foreground: oklch(0.21 0.034 264.665);
32  --sidebar-border: oklch(0.928 0.006 264.531);
33  --sidebar-ring: oklch(0.707 0.022 261.325);
34}
35
36.dark {
37  --background: oklch(0.13 0.028 261.692);
38  --foreground: oklch(0.985 0.002 247.839);
39  --card: oklch(0.21 0.034 264.665);
40  --card-foreground: oklch(0.985 0.002 247.839);
41  --popover: oklch(0.21 0.034 264.665);
42  --popover-foreground: oklch(0.985 0.002 247.839);
43  --primary: oklch(0.928 0.006 264.531);
44  --primary-foreground: oklch(0.21 0.034 264.665);
45  --secondary: oklch(0.278 0.033 256.848);
46  --secondary-foreground: oklch(0.985 0.002 247.839);
47  --muted: oklch(0.278 0.033 256.848);
48  --muted-foreground: oklch(0.7717 0.017 262.74);
49  --accent: oklch(0.278 0.033 256.848);
50  --accent-foreground: oklch(0.985 0.002 247.839);
51  --destructive: oklch(0.704 0.191 22.216);
52  --border: oklch(1 0 0 / 10%);
53  --input: oklch(1 0 0 / 15%);
54  --ring: oklch(0.551 0.027 264.364);
55  --chart-1: oklch(0.488 0.243 264.376);
56  --chart-2: oklch(0.696 0.17 162.48);
57  --chart-3: oklch(0.769 0.188 70.08);
58  --chart-4: oklch(0.627 0.265 303.9);
59  --chart-5: oklch(0.645 0.246 16.439);
60  --sidebar: oklch(0.21 0.034 264.665);
61  --sidebar-foreground: oklch(0.985 0.002 247.839);
62  --sidebar-primary: oklch(0.488 0.243 264.376);
63  --sidebar-primary-foreground: oklch(0.985 0.002 247.839);
64  --sidebar-accent: oklch(0.278 0.033 256.848);
65  --sidebar-accent-foreground: oklch(0.985 0.002 247.839);
66  --sidebar-border: oklch(1 0 0 / 10%);
67  --sidebar-ring: oklch(0.551 0.027 264.364);
68}

Slate: Subtle blue undertone. Technical and professional.

Tailwind CSS /assets/base/_slate.css
 1:root {
 2  --radius: 0.625rem;
 3  --background: oklch(1 0 0);
 4  --foreground: oklch(0.129 0.042 264.695);
 5  --card: oklch(1 0 0);
 6  --card-foreground: oklch(0.129 0.042 264.695);
 7  --popover: oklch(1 0 0);
 8  --popover-foreground: oklch(0.129 0.042 264.695);
 9  --primary: oklch(0.208 0.042 265.755);
10  --primary-foreground: oklch(0.984 0.003 247.858);
11  --secondary: oklch(0.968 0.007 247.896);
12  --secondary-foreground: oklch(0.208 0.042 265.755);
13  --muted: oklch(0.968 0.007 247.896);
14  --muted-foreground: oklch(0.4414 0.0306 244.98);
15  --accent: oklch(0.968 0.007 247.896);
16  --accent-foreground: oklch(0.208 0.042 265.755);
17  --destructive: oklch(0.577 0.245 27.325);
18  --border: oklch(0.929 0.013 255.508);
19  --input: oklch(0.929 0.013 255.508);
20  --ring: oklch(0.704 0.04 256.788);
21  --chart-1: oklch(0.646 0.222 41.116);
22  --chart-2: oklch(0.6 0.118 184.704);
23  --chart-3: oklch(0.398 0.07 227.392);
24  --chart-4: oklch(0.828 0.189 84.429);
25  --chart-5: oklch(0.769 0.188 70.08);
26  --sidebar: oklch(0.984 0.003 247.858);
27  --sidebar-foreground: oklch(0.129 0.042 264.695);
28  --sidebar-primary: oklch(0.208 0.042 265.755);
29  --sidebar-primary-foreground: oklch(0.984 0.003 247.858);
30  --sidebar-accent: oklch(0.968 0.007 247.896);
31  --sidebar-accent-foreground: oklch(0.208 0.042 265.755);
32  --sidebar-border: oklch(0.929 0.013 255.508);
33  --sidebar-ring: oklch(0.704 0.04 256.788);
34}
35
36.dark {
37  --background: oklch(0.129 0.042 264.695);
38  --foreground: oklch(0.984 0.003 247.858);
39  --card: oklch(0.208 0.042 265.755);
40  --card-foreground: oklch(0.984 0.003 247.858);
41  --popover: oklch(0.208 0.042 265.755);
42  --popover-foreground: oklch(0.984 0.003 247.858);
43  --primary: oklch(0.929 0.013 255.508);
44  --primary-foreground: oklch(0.208 0.042 265.755);
45  --secondary: oklch(0.279 0.041 260.031);
46  --secondary-foreground: oklch(0.984 0.003 247.858);
47  --muted: oklch(0.279 0.041 260.031);
48  --muted-foreground: oklch(0.7683 0.0314 256.03);
49  --accent: oklch(0.279 0.041 260.031);
50  --accent-foreground: oklch(0.984 0.003 247.858);
51  --destructive: oklch(0.704 0.191 22.216);
52  --border: oklch(1 0 0 / 10%);
53  --input: oklch(1 0 0 / 15%);
54  --ring: oklch(0.551 0.027 264.364);
55  --chart-1: oklch(0.488 0.243 264.376);
56  --chart-2: oklch(0.696 0.17 162.48);
57  --chart-3: oklch(0.769 0.188 70.08);
58  --chart-4: oklch(0.627 0.265 303.9);
59  --chart-5: oklch(0.645 0.246 16.439);
60  --sidebar: oklch(0.208 0.042 265.755);
61  --sidebar-foreground: oklch(0.984 0.003 247.858);
62  --sidebar-primary: oklch(0.488 0.243 264.376);
63  --sidebar-primary-foreground: oklch(0.984 0.003 247.858);
64  --sidebar-accent: oklch(0.279 0.041 260.031);
65  --sidebar-accent-foreground: oklch(0.984 0.003 247.858);
66  --sidebar-border: oklch(1 0 0 / 10%);
67  --sidebar-ring: oklch(0.551 0.027 264.364);
68}

Stone: Warm, earthy feel. Ideal for blogs and portfolios.

Tailwind CSS /assets/base/_stone.css
 1:root {
 2  --radius: 0.625rem;
 3  --background: oklch(1 0 0);
 4  --foreground: oklch(0.147 0.004 49.25);
 5  --card: oklch(1 0 0);
 6  --card-foreground: oklch(0.147 0.004 49.25);
 7  --popover: oklch(1 0 0);
 8  --popover-foreground: oklch(0.147 0.004 49.25);
 9  --primary: oklch(0.216 0.006 56.043);
10  --primary-foreground: oklch(0.985 0.001 106.423);
11  --secondary: oklch(0.97 0.001 106.424);
12  --secondary-foreground: oklch(0.216 0.006 56.043);
13  --muted: oklch(0.97 0.001 106.424);
14  --muted-foreground: oklch(0.4408 0.0096 73.64);
15  --accent: oklch(0.97 0.001 106.424);
16  --accent-foreground: oklch(0.216 0.006 56.043);
17  --destructive: oklch(0.577 0.245 27.325);
18  --border: oklch(0.923 0.003 48.717);
19  --input: oklch(0.923 0.003 48.717);
20  --ring: oklch(0.709 0.01 56.259);
21  --chart-1: oklch(0.646 0.222 41.116);
22  --chart-2: oklch(0.6 0.118 184.704);
23  --chart-3: oklch(0.398 0.07 227.392);
24  --chart-4: oklch(0.828 0.189 84.429);
25  --chart-5: oklch(0.769 0.188 70.08);
26  --sidebar: oklch(0.985 0.001 106.423);
27  --sidebar-foreground: oklch(0.147 0.004 49.25);
28  --sidebar-primary: oklch(0.216 0.006 56.043);
29  --sidebar-primary-foreground: oklch(0.985 0.001 106.423);
30  --sidebar-accent: oklch(0.97 0.001 106.424);
31  --sidebar-accent-foreground: oklch(0.216 0.006 56.043);
32  --sidebar-border: oklch(0.923 0.003 48.717);
33  --sidebar-ring: oklch(0.709 0.01 56.259);
34}
35
36.dark {
37  --background: oklch(0.147 0.004 49.25);
38  --foreground: oklch(0.985 0.001 106.423);
39  --card: oklch(0.216 0.006 56.043);
40  --card-foreground: oklch(0.985 0.001 106.423);
41  --popover: oklch(0.216 0.006 56.043);
42  --popover-foreground: oklch(0.985 0.001 106.423);
43  --primary: oklch(0.923 0.003 48.717);
44  --primary-foreground: oklch(0.216 0.006 56.043);
45  --secondary: oklch(0.268 0.007 34.298);
46  --secondary-foreground: oklch(0.985 0.001 106.423);
47  --muted: oklch(0.268 0.007 34.298);
48  --muted-foreground: oklch(0.7645 0.0081 48.62);
49  --accent: oklch(0.268 0.007 34.298);
50  --accent-foreground: oklch(0.985 0.001 106.423);
51  --destructive: oklch(0.704 0.191 22.216);
52  --border: oklch(1 0 0 / 10%);
53  --input: oklch(1 0 0 / 15%);
54  --ring: oklch(0.553 0.013 58.071);
55  --chart-1: oklch(0.488 0.243 264.376);
56  --chart-2: oklch(0.696 0.17 162.48);
57  --chart-3: oklch(0.769 0.188 70.08);
58  --chart-4: oklch(0.627 0.265 303.9);
59  --chart-5: oklch(0.645 0.246 16.439);
60  --sidebar: oklch(0.216 0.006 56.043);
61  --sidebar-foreground: oklch(0.985 0.001 106.423);
62  --sidebar-primary: oklch(0.488 0.243 264.376);
63  --sidebar-primary-foreground: oklch(0.985 0.001 106.423);
64  --sidebar-accent: oklch(0.268 0.007 34.298);
65  --sidebar-accent-foreground: oklch(0.985 0.001 106.423);
66  --sidebar-border: oklch(1 0 0 / 10%);
67  --sidebar-ring: oklch(0.553 0.013 58.071);
68}

Zinc: Versatile, cool-toned gray. Ideal for modern SaaS applications.

Tailwind CSS /assets/base/_zinc.css
 1:root {
 2  --radius: 0.625rem;
 3  --background: oklch(1 0 0);
 4  --foreground: oklch(0.141 0.005 285.823);
 5  --card: oklch(1 0 0);
 6  --card-foreground: oklch(0.141 0.005 285.823);
 7  --popover: oklch(1 0 0);
 8  --popover-foreground: oklch(0.141 0.005 285.823);
 9  --primary: oklch(0.21 0.006 285.885);
10  --primary-foreground: oklch(0.985 0 0);
11  --secondary: oklch(0.967 0.001 286.375);
12  --secondary-foreground: oklch(0.21 0.006 285.885);
13  --muted: oklch(0.967 0.001 286.375);
14  --muted-foreground: oklch(0.4375 0.0114 285.92);
15  --accent: oklch(0.967 0.001 286.375);
16  --accent-foreground: oklch(0.21 0.006 285.885);
17  --destructive: oklch(0.577 0.245 27.325);
18  --border: oklch(0.92 0.004 286.32);
19  --input: oklch(0.92 0.004 286.32);
20  --ring: oklch(0.705 0.015 286.067);
21  --chart-1: oklch(0.646 0.222 41.116);
22  --chart-2: oklch(0.6 0.118 184.704);
23  --chart-3: oklch(0.398 0.07 227.392);
24  --chart-4: oklch(0.828 0.189 84.429);
25  --chart-5: oklch(0.769 0.188 70.08);
26  --sidebar: oklch(0.985 0 0);
27  --sidebar-foreground: oklch(0.141 0.005 285.823);
28  --sidebar-primary: oklch(0.21 0.006 285.885);
29  --sidebar-primary-foreground: oklch(0.985 0 0);
30  --sidebar-accent: oklch(0.967 0.001 286.375);
31  --sidebar-accent-foreground: oklch(0.21 0.006 285.885);
32  --sidebar-border: oklch(0.92 0.004 286.32);
33  --sidebar-ring: oklch(0.705 0.015 286.067);
34}
35
36.dark {
37  --background: oklch(0.141 0.005 285.823);
38  --foreground: oklch(0.985 0 0);
39  --card: oklch(0.21 0.006 285.885);
40  --card-foreground: oklch(0.985 0 0);
41  --popover: oklch(0.21 0.006 285.885);
42  --popover-foreground: oklch(0.985 0 0);
43  --primary: oklch(0.92 0.004 286.32);
44  --primary-foreground: oklch(0.21 0.006 285.885);
45  --secondary: oklch(0.274 0.006 286.033);
46  --secondary-foreground: oklch(0.985 0 0);
47  --muted: oklch(0.274 0.006 286.033);
48  --muted-foreground: oklch(0.7721 0.0098 286.17);
49  --accent: oklch(0.274 0.006 286.033);
50  --accent-foreground: oklch(0.985 0 0);
51  --destructive: oklch(0.704 0.191 22.216);
52  --border: oklch(1 0 0 / 10%);
53  --input: oklch(1 0 0 / 15%);
54  --ring: oklch(0.552 0.016 285.938);
55  --chart-1: oklch(0.488 0.243 264.376);
56  --chart-2: oklch(0.696 0.17 162.48);
57  --chart-3: oklch(0.769 0.188 70.08);
58  --chart-4: oklch(0.627 0.265 303.9);
59  --chart-5: oklch(0.645 0.246 16.439);
60  --sidebar: oklch(0.21 0.006 285.885);
61  --sidebar-foreground: oklch(0.985 0 0);
62  --sidebar-primary: oklch(0.488 0.243 264.376);
63  --sidebar-primary-foreground: oklch(0.985 0 0);
64  --sidebar-accent: oklch(0.274 0.006 286.033);
65  --sidebar-accent-foreground: oklch(0.985 0 0);
66  --sidebar-border: oklch(1 0 0 / 10%);
67  --sidebar-ring: oklch(0.552 0.016 285.938);
68}
1/assets/
2  ├── css/             <-- The styles
3  ├── js/              <-- The logic (CSP Safe)
4  └── icons/
5  
6/layouts/
7  ├── _partials/ui/    <-- The Bricks
8  └── _shortcodes/ui/  <-- The Bricks