@olwiba/cn 0.1.29 → 0.1.31

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@olwiba/cn",
3
- "version": "0.1.29",
3
+ "version": "0.1.31",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "sideEffects": false,
@@ -22,24 +22,82 @@
22
22
  :root {
23
23
  --radius: 0.25rem;
24
24
 
25
- --background: oklch(1 0 0);
25
+ /*
26
+ * Neutral tint — off by default.
27
+ *
28
+ * The light neutrals below are pure achromatic: `oklch(1 0 0)` for the
29
+ * background, chroma 0 on every one of them. That is a deliberate shadcn
30
+ * default and it is fine for a neutral product, but it makes a branded one
31
+ * read as clinical: an accent dropped onto pure white has nothing to sit
32
+ * against, and light mode looks less like "light" than like the absence of
33
+ * colour.
34
+ *
35
+ * Setting these two lets a product tint its neutrals toward its brand hue
36
+ * without restating every token:
37
+ *
38
+ * :root:not(.dark) {
39
+ * --neutral-tint-hue: 186;
40
+ * --neutral-tint-chroma: 0.012;
41
+ * }
42
+ *
43
+ * `:root:not(.dark)`, not `:root` — see the note above the dark block.
44
+ *
45
+ * Chroma is scaled per surface rather than applied flat. A tint that reads
46
+ * as deliberate on a border reads as a colour cast across a full-page
47
+ * background, so the largest surfaces get a fraction of it and the smallest
48
+ * get all of it.
49
+ *
50
+ * Both default to 0, and `oklch(L 0 H)` is achromatic whatever the hue, so
51
+ * a consumer that sets neither renders exactly the colours it did before.
52
+ * The declarations change; the computed values do not.
53
+ */
54
+ --neutral-tint-hue: 0;
55
+ --neutral-tint-chroma: 0;
56
+
57
+ /*
58
+ * How far the page drops below pure white. Also 0 by default.
59
+ *
60
+ * Chroma alone is not enough. `oklch(1 0.004 186)` is still white — there is
61
+ * almost no room for colour at maximum lightness — so a tint applied to a
62
+ * pure-white background barely registers, and "light mode is too bright"
63
+ * stays true. Lowering the page a little is what makes the tint visible and
64
+ * the page comfortable.
65
+ *
66
+ * It also separates card from background, which are otherwise the identical
67
+ * value: a card is distinguished from the page only by its border, and a
68
+ * translucent surface over it (`bg-card/45`) shows nothing at all. The card
69
+ * drops by a fifth of what the page does, so it lifts without becoming a
70
+ * different colour.
71
+ *
72
+ * Foregrounds are untouched, and the largest move here is 1 → 0.985, so
73
+ * contrast is effectively unchanged.
74
+ */
75
+ --neutral-lift: 0;
76
+
77
+ /* Per-surface share of --neutral-tint-chroma. */
78
+ --neutral-tint-page: calc(var(--neutral-tint-chroma) * 0.33);
79
+ --neutral-tint-raised: calc(var(--neutral-tint-chroma) * 0.25);
80
+ --neutral-tint-muted: calc(var(--neutral-tint-chroma) * 0.67);
81
+ --neutral-tint-line: calc(var(--neutral-tint-chroma) * 0.83);
82
+
83
+ --background: oklch(calc(1 - var(--neutral-lift)) var(--neutral-tint-page) var(--neutral-tint-hue));
26
84
  --foreground: oklch(0.145 0 0);
27
- --card: oklch(1 0 0);
85
+ --card: oklch(calc(1 - var(--neutral-lift) * 0.2) var(--neutral-tint-raised) var(--neutral-tint-hue));
28
86
  --card-foreground: oklch(0.145 0 0);
29
- --popover: oklch(1 0 0);
87
+ --popover: oklch(calc(1 - var(--neutral-lift) * 0.2) var(--neutral-tint-raised) var(--neutral-tint-hue));
30
88
  --popover-foreground: oklch(0.145 0 0);
31
89
 
32
90
  --primary: oklch(0.596 0.145 163.225);
33
91
  --primary-foreground: oklch(0.985 0 0);
34
- --secondary: oklch(0.97 0 0);
92
+ --secondary: oklch(calc(0.97 - var(--neutral-lift) * 0.53) var(--neutral-tint-muted) var(--neutral-tint-hue));
35
93
  --secondary-foreground: oklch(0.205 0 0);
36
- --muted: oklch(0.97 0 0);
94
+ --muted: oklch(calc(0.97 - var(--neutral-lift) * 0.53) var(--neutral-tint-muted) var(--neutral-tint-hue));
37
95
  --muted-foreground: oklch(0.556 0 0);
38
- --accent: oklch(0.97 0 0);
96
+ --accent: oklch(calc(0.97 - var(--neutral-lift)) var(--neutral-tint-chroma) var(--neutral-tint-hue));
39
97
  --accent-foreground: oklch(0.205 0 0);
40
98
  --destructive: oklch(0.577 0.245 27.325);
41
- --border: oklch(0.922 0 0);
42
- --input: oklch(0.922 0 0);
99
+ --border: oklch(calc(0.922 - var(--neutral-lift) * 0.67) var(--neutral-tint-line) var(--neutral-tint-hue));
100
+ --input: oklch(calc(0.922 - var(--neutral-lift) * 0.67) var(--neutral-tint-line) var(--neutral-tint-hue));
43
101
  --ring: oklch(0.596 0.145 163.225);
44
102
 
45
103
  --chart-1: oklch(0.765 0.177 163.223);
@@ -48,16 +106,29 @@
48
106
  --chart-4: oklch(0.508 0.118 165.612);
49
107
  --chart-5: oklch(0.432 0.095 166.913);
50
108
 
51
- --sidebar: oklch(0.985 0 0);
109
+ --sidebar: oklch(calc(0.985 - var(--neutral-lift) * 0.67) var(--neutral-tint-muted) var(--neutral-tint-hue));
52
110
  --sidebar-foreground: oklch(0.145 0 0);
53
111
  --sidebar-primary: oklch(0.596 0.145 163.225);
54
112
  --sidebar-primary-foreground: oklch(0.985 0 0);
55
- --sidebar-accent: oklch(0.97 0 0);
113
+ --sidebar-accent: oklch(calc(0.97 - var(--neutral-lift)) var(--neutral-tint-chroma) var(--neutral-tint-hue));
56
114
  --sidebar-accent-foreground: oklch(0.205 0 0);
57
- --sidebar-border: oklch(0.922 0 0);
115
+ --sidebar-border: oklch(calc(0.922 - var(--neutral-lift) * 0.67) var(--neutral-tint-line) var(--neutral-tint-hue));
58
116
  --sidebar-ring: oklch(0.596 0.145 163.225);
59
117
  }
60
118
 
119
+ /*
120
+ * Overriding any of these from a consumer stylesheet needs `:root:not(.dark)`,
121
+ * not `:root`.
122
+ *
123
+ * `.dark` is a class and `:root` is a pseudo-class — the same specificity. A
124
+ * consumer's stylesheet is imported after this preset, so a plain `:root`
125
+ * block wins on source order and repaints *dark* mode with the light values.
126
+ * It looks like the override was ignored in light mode and applied in dark,
127
+ * which sends you looking in the wrong place entirely.
128
+ *
129
+ * The neutral tint knobs above exist partly to avoid needing such an override
130
+ * at all.
131
+ */
61
132
  .dark {
62
133
  --background: oklch(0.145 0 0);
63
134
  --foreground: oklch(0.985 0 0);