@jpgilldev / steid

steid/styles.css
4.8 KBRaw
1/* Steid's theme.
2 Started from Topcoat's `neutral` theme and retuned; see plans/ui.md.
3
4 The theme is a small set of design tokens. Components refer to tokens only,
5 never to raw colors, so the whole product restyles by editing `:root` and
6 `.dark` below. A component that hardcodes a color is a bug — it will not
7 follow a palette change and it will not adapt to the color scheme.
8
9 --background the page background
10 --surface raised panels: cards, menus, flash messages
11 --foreground text and iconography on the background
12 --muted-foreground secondary text: captions, descriptions, placeholders
13 --primary the emphasis color: primary actions, selection, links
14 --primary-foreground text on a primary-filled surface
15 --success confirmations, and git additions
16 --success-foreground text on a success-filled surface
17 --warning caution, and git modifications
18 --warning-foreground text on a warning-filled surface
19 --destructive destructive actions, errors, and git deletions
20 --destructive-foreground text on a destructive-filled surface
21 --border hairline borders and dividers
22 --ring the focus ring
23 --shadow-xs a subtle shadow for controls: buttons, inputs
24 --shadow-sm a shadow for raised surfaces: cards, menus
25
26 Interactive states (hover, press) have no tokens of their own: components
27 derive them by applying the fill or foreground color at reduced opacity,
28 which adapts to both color schemes automatically.
29
30 Steid is dark-first — the layout sets `class="dark"` on <html>. Light mode
31 is supported and secondary. */
32
33@import "tailwindcss";
34
35/* Scan the project's Rust sources for the Tailwind classes they use. This
36 file is installed at the project root, so `./src` is the crate's source. */
37@source "./src/**/*.rs";
38
39/* Dark mode is opted into by putting the `dark` class on an ancestor,
40 typically <html>. */
41@custom-variant dark (&:is(.dark *));
42
43/* Expose the tokens as Tailwind utilities (`bg-background`, `text-primary`,
44 `border-border`, ...). The indirection through plain variables on `:root`
45 and `.dark` is what lets the values swap when the color scheme changes. */
46@theme inline {
47 --font-sans: "Geist", ui-sans-serif, system-ui, sans-serif;
48 /* Paths, commit hashes, branch names, and code. */
49 --font-mono: "IBM Plex Mono", ui-monospace, "SF Mono", monospace;
50 --color-background: var(--background);
51 --color-surface: var(--surface);
52 --color-foreground: var(--foreground);
53 --color-muted-foreground: var(--muted-foreground);
54 --color-primary: var(--primary);
55 --color-primary-foreground: var(--primary-foreground);
56 --color-success: var(--success);
57 --color-success-foreground: var(--success-foreground);
58 --color-warning: var(--warning);
59 --color-warning-foreground: var(--warning-foreground);
60 --color-destructive: var(--destructive);
61 --color-destructive-foreground: var(--destructive-foreground);
62 --color-border: var(--border);
63 --color-ring: var(--ring);
64 --shadow-xs: var(--shadow-xs);
65 --shadow-sm: var(--shadow-sm);
66}
67
68/* Light mode. Secondary, but it should not look like an afterthought. */
69:root {
70 --background: oklch(0.99 0.003 260);
71 --surface: oklch(1 0 0);
72 --foreground: oklch(0.24 0.012 260);
73 --muted-foreground: oklch(0.51 0.014 260);
74 --primary: oklch(0.5 0.18 250);
75 --primary-foreground: oklch(0.99 0.003 260);
76 --success: oklch(0.52 0.15 145);
77 --success-foreground: oklch(0.99 0.01 145);
78 --warning: oklch(0.62 0.14 85);
79 --warning-foreground: oklch(0.99 0.01 85);
80 --destructive: oklch(0.55 0.2 27);
81 --destructive-foreground: oklch(0.99 0.012 27);
82 --border: oklch(0.9 0.008 260);
83 --ring: oklch(0.5 0.18 250);
84 --shadow-xs: 0 1px 2px oklch(0.24 0.02 260 / 12%);
85 --shadow-sm:
86 0 1px 2px oklch(0.24 0.02 260 / 10%),
87 0 2px 8px -2px oklch(0.24 0.02 260 / 9%);
88}
89
90/* Dark mode. The primary surface for this product. */
91.dark {
92 --background: oklch(0.16 0.02 260);
93 --surface: oklch(0.2 0.02 260);
94 --foreground: oklch(0.9 0.01 260);
95 --muted-foreground: oklch(0.66 0.014 260);
96 --primary: oklch(0.65 0.15 250);
97 --primary-foreground: oklch(0.16 0.02 260);
98 --success: oklch(0.7 0.17 145);
99 --success-foreground: oklch(0.16 0.02 145);
100 --warning: oklch(0.8 0.15 85);
101 --warning-foreground: oklch(0.16 0.02 85);
102 --destructive: oklch(0.65 0.2 25);
103 --destructive-foreground: oklch(0.14 0.02 25);
104 --border: oklch(0.3 0.012 260);
105 --ring: oklch(0.65 0.15 250);
106 /* Light-mode shadows disappear on a dark background, so these are deeper. */
107 --shadow-xs: 0 1px 2px oklch(0 0 0 / 35%);
108 --shadow-sm: 0 1px 2px oklch(0 0 0 / 35%), 0 2px 8px -2px oklch(0 0 0 / 30%);
109}
110
111@layer base {
112 body {
113 @apply bg-background font-sans text-foreground;
114 }
115}