@olwiba/cn 0.1.32 → 0.1.34

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.32",
3
+ "version": "0.1.34",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "sideEffects": false,
@@ -23,98 +23,61 @@
23
23
  --radius: 0.25rem;
24
24
 
25
25
  /*
26
- * Neutral tint off by default.
26
+ * Light neutrals: off-white, tinted toward the brand. Not configurable.
27
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.
28
+ * The shadcn defaults are `oklch(1 0 0)` for the page and chroma 0 on every
29
+ * neutral pure white, pure grey. Both are the same mistake in different
30
+ * directions, and neither is ever the answer anyone actually wanted:
34
31
  *
35
- * Setting these two lets a product tint its neutrals toward its brand hue
36
- * without restating every token:
32
+ * - Pure white emits more light than any other surface on screen, so long
33
+ * reading tires eyes faster than an off-white does, and a page of it
34
+ * reads as sterile rather than clean.
35
+ * - Pure grey neutrals give a brand accent nothing to sit against. Light
36
+ * mode stops looking like a lighter version of the palette and starts
37
+ * looking like the absence of one.
37
38
  *
38
- * :root:not(.dark) {
39
- * --neutral-tint-hue: 186;
40
- * --neutral-tint-chroma: 0.012;
41
- * }
39
+ * So neither is a setting. The page sits at #fafafa, the neutrals carry a
40
+ * trace of the brand hue, and a product gets that by doing nothing.
42
41
  *
43
- * `:root:not(.dark)`, not `:root` see the note above the dark block.
42
+ * The hue is read from `--primary` with relative colour syntax, so this
43
+ * needs no per-product configuration and cannot drift from the brand. The
44
+ * plain off-white values live here; the brand-derived ones are applied in an
45
+ * `@supports` block below, so a browser without relative colour syntax keeps
46
+ * a correct, untinted off-white rather than nothing at all.
44
47
  *
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.
48
+ * Chroma is scaled per surface rather than applied flat a tint that reads
49
+ * as deliberate on a border reads as a colour cast across a full page — and
50
+ * lightness is stepped so a card lifts off the page rather than matching it,
51
+ * which is what makes a translucent surface over it visible at all.
49
52
  *
50
- * Both tint knobs default to 0, and `oklch(L 0 H)` is achromatic whatever
51
- * the hue, so a consumer that sets neither gets no colour at all.
52
- *
53
- * `--neutral-lift` below is the exception: it has a non-zero default,
54
- * because pure white is worth refusing by default rather than opting out
55
- * of. That is the only value a consumer inherits without asking.
56
- */
57
- --neutral-tint-hue: 0;
58
- --neutral-tint-chroma: 0;
59
-
60
- /*
61
- * How far the page drops below pure white. Also 0 by default.
62
- *
63
- * Chroma alone is not enough. `oklch(1 0.004 186)` is still white — there is
64
- * almost no room for colour at maximum lightness — so a tint applied to a
65
- * pure-white background barely registers, and "light mode is too bright"
66
- * stays true. Lowering the page a little is what makes the tint visible and
67
- * the page comfortable.
68
- *
69
- * It also separates card from background, which are otherwise the identical
70
- * value: a card is distinguished from the page only by its border, and a
71
- * translucent surface over it (`bg-card/45`) shows nothing at all. The card
72
- * drops by a fifth of what the page does, so it lifts without becoming a
73
- * different colour.
74
- *
75
- * Foregrounds are untouched, and the largest move here is 1 → 0.985, so
76
- * contrast is effectively unchanged.
77
- *
78
- * The default is not 0. Pure white is the one value worth refusing outright:
79
- * it emits more light than any other surface on the screen, which is why
80
- * long reading sessions tire eyes faster on #ffffff than on an off-white,
81
- * and it flattens a page into something sterile. The convention in
82
- * editorial and product design is to sit just off it.
83
- *
84
- * 0.003 puts the page at #fefefe — one step per channel, deliberately
85
- * conservative. It removes the extreme without restyling any consumer's
86
- * product, and it is the floor rather than the recommendation: 0.015
87
- * (#fafafa) is where the glare actually goes, and is what nestrrr uses.
88
- *
89
- * `--neutral-lift: 0` still gets pure white back for anything that wants
90
- * it — a print stylesheet, a canvas, a screenshot surface.
53
+ * `--neutral-tint-chroma: 0` is the single escape hatch, for a product where
54
+ * a colour cast would fight its content a charting or data tool. It keeps
55
+ * the off-white and drops the hue.
91
56
  */
92
- --neutral-lift: 0.003;
93
-
94
- /* Per-surface share of --neutral-tint-chroma. */
57
+ --neutral-tint-chroma: 0.012;
95
58
  --neutral-tint-page: calc(var(--neutral-tint-chroma) * 0.33);
96
59
  --neutral-tint-raised: calc(var(--neutral-tint-chroma) * 0.25);
97
60
  --neutral-tint-muted: calc(var(--neutral-tint-chroma) * 0.67);
98
61
  --neutral-tint-line: calc(var(--neutral-tint-chroma) * 0.83);
99
62
 
100
- --background: oklch(calc(1 - var(--neutral-lift)) var(--neutral-tint-page) var(--neutral-tint-hue));
63
+ --background: oklch(0.985 0 0);
101
64
  --foreground: oklch(0.145 0 0);
102
- --card: oklch(calc(1 - var(--neutral-lift) * 0.2) var(--neutral-tint-raised) var(--neutral-tint-hue));
65
+ --card: oklch(0.997 0 0);
103
66
  --card-foreground: oklch(0.145 0 0);
104
- --popover: oklch(calc(1 - var(--neutral-lift) * 0.2) var(--neutral-tint-raised) var(--neutral-tint-hue));
67
+ --popover: oklch(0.997 0 0);
105
68
  --popover-foreground: oklch(0.145 0 0);
106
69
 
107
70
  --primary: oklch(0.596 0.145 163.225);
108
71
  --primary-foreground: oklch(0.985 0 0);
109
- --secondary: oklch(calc(0.97 - var(--neutral-lift) * 0.53) var(--neutral-tint-muted) var(--neutral-tint-hue));
72
+ --secondary: oklch(0.962 0 0);
110
73
  --secondary-foreground: oklch(0.205 0 0);
111
- --muted: oklch(calc(0.97 - var(--neutral-lift) * 0.53) var(--neutral-tint-muted) var(--neutral-tint-hue));
74
+ --muted: oklch(0.962 0 0);
112
75
  --muted-foreground: oklch(0.556 0 0);
113
- --accent: oklch(calc(0.97 - var(--neutral-lift)) var(--neutral-tint-chroma) var(--neutral-tint-hue));
76
+ --accent: oklch(0.955 0 0);
114
77
  --accent-foreground: oklch(0.205 0 0);
115
78
  --destructive: oklch(0.577 0.245 27.325);
116
- --border: oklch(calc(0.922 - var(--neutral-lift) * 0.67) var(--neutral-tint-line) var(--neutral-tint-hue));
117
- --input: oklch(calc(0.922 - var(--neutral-lift) * 0.67) var(--neutral-tint-line) var(--neutral-tint-hue));
79
+ --border: oklch(0.912 0 0);
80
+ --input: oklch(0.912 0 0);
118
81
  --ring: oklch(0.596 0.145 163.225);
119
82
 
120
83
  --chart-1: oklch(0.765 0.177 163.223);
@@ -123,13 +86,13 @@
123
86
  --chart-4: oklch(0.508 0.118 165.612);
124
87
  --chart-5: oklch(0.432 0.095 166.913);
125
88
 
126
- --sidebar: oklch(calc(0.985 - var(--neutral-lift) * 0.67) var(--neutral-tint-muted) var(--neutral-tint-hue));
89
+ --sidebar: oklch(0.975 0 0);
127
90
  --sidebar-foreground: oklch(0.145 0 0);
128
91
  --sidebar-primary: oklch(0.596 0.145 163.225);
129
92
  --sidebar-primary-foreground: oklch(0.985 0 0);
130
- --sidebar-accent: oklch(calc(0.97 - var(--neutral-lift)) var(--neutral-tint-chroma) var(--neutral-tint-hue));
93
+ --sidebar-accent: oklch(0.955 0 0);
131
94
  --sidebar-accent-foreground: oklch(0.205 0 0);
132
- --sidebar-border: oklch(calc(0.922 - var(--neutral-lift) * 0.67) var(--neutral-tint-line) var(--neutral-tint-hue));
95
+ --sidebar-border: oklch(0.912 0 0);
133
96
  --sidebar-ring: oklch(0.596 0.145 163.225);
134
97
  }
135
98
 
@@ -146,6 +109,36 @@
146
109
  * The neutral tint knobs above exist partly to avoid needing such an override
147
110
  * at all.
148
111
  */
112
+ /*
113
+ * The brand-derived half, gated on relative colour syntax being supported.
114
+ *
115
+ * `@supports` rather than two declarations in `:root`. A custom property
116
+ * accepts almost any token stream, so `--background: oklch(from ...)` is
117
+ * stored even by a browser that cannot parse it — the failure only appears
118
+ * when the value is *used*, and then it is invalid at computed-value time and
119
+ * the property falls back to its initial value, not to an earlier declaration.
120
+ * The result would be a transparent page rather than an untinted one.
121
+ *
122
+ * Gating on support means an older browser simply never sees these, and keeps
123
+ * the plain off-white neutrals above. Which are correct on their own — the
124
+ * tint is the refinement, not the requirement.
125
+ */
126
+ @supports (color: oklch(from white l c h)) {
127
+ :root {
128
+ --background: oklch(from var(--primary) 0.985 var(--neutral-tint-page) h);
129
+ --card: oklch(from var(--primary) 0.997 var(--neutral-tint-raised) h);
130
+ --popover: oklch(from var(--primary) 0.997 var(--neutral-tint-raised) h);
131
+ --secondary: oklch(from var(--primary) 0.962 var(--neutral-tint-muted) h);
132
+ --muted: oklch(from var(--primary) 0.962 var(--neutral-tint-muted) h);
133
+ --accent: oklch(from var(--primary) 0.955 var(--neutral-tint-chroma) h);
134
+ --border: oklch(from var(--primary) 0.912 var(--neutral-tint-line) h);
135
+ --input: oklch(from var(--primary) 0.912 var(--neutral-tint-line) h);
136
+ --sidebar: oklch(from var(--primary) 0.975 var(--neutral-tint-muted) h);
137
+ --sidebar-accent: oklch(from var(--primary) 0.955 var(--neutral-tint-chroma) h);
138
+ --sidebar-border: oklch(from var(--primary) 0.912 var(--neutral-tint-line) h);
139
+ }
140
+ }
141
+
149
142
  .dark {
150
143
  --background: oklch(0.145 0 0);
151
144
  --foreground: oklch(0.985 0 0);