@webmate-studio/builder 0.2.140 → 0.2.142

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": "@webmate-studio/builder",
3
- "version": "0.2.140",
3
+ "version": "0.2.142",
4
4
  "type": "module",
5
5
  "description": "Webmate Studio Component Builder",
6
6
  "keywords": [
@@ -45,8 +45,12 @@ export function generateColorScale(baseHex, curve) {
45
45
  // Neutral-Erkennung: Basis mit sehr niedriger Chroma (reines Grau)
46
46
  const isPureNeutral = base.c < 0.008;
47
47
 
48
+ // Neutral-Erkennung für Rampe: getönte Grautöne (c < 0.05) brauchen
49
+ // dunkle Steps für Textfarbe und Step 1 = Weiß
50
+ const isLowChroma = base.c < 0.05;
51
+
48
52
  // Lightness-Rampe adaptiv an Base-Lightness
49
- const L = buildLightnessRamp(base.l);
53
+ const L = buildLightnessRamp(base.l, isLowChroma);
50
54
 
51
55
  // Wurde die Base-Lightness geclampt? (extrem helle/dunkle Farben)
52
56
  const baseClamped = Math.abs(L[8] - base.l) > 0.01;
@@ -70,14 +74,22 @@ export function generateColorScale(baseHex, curve) {
70
74
  c = base.c;
71
75
  } else {
72
76
  c = computeChroma(L[i], L[8], base.c, stdDev, chromaScale);
77
+
78
+ // Neutraltöne: Helle Stufen extra dämpfen, damit Steps 2-5
79
+ // nicht zu farbig wirken. Nahe der Base bleibt volle Chroma.
80
+ if (isLowChroma && L[i] > L[8]) {
81
+ const distFromBase = (L[i] - L[8]) / (0.985 - L[8]); // 0 bei Base, 1 bei Step 1
82
+ const damping = 1.0 - 0.55 * distFromBase * distFromBase;
83
+ c *= damping;
84
+ }
73
85
  }
74
86
 
75
87
  const mapped = gamutMapOklch(L[i], c, base.h);
76
88
  scale[step] = oklchToHex(mapped.l, mapped.c, mapped.h);
77
89
  }
78
90
 
79
- // Reines Neutral Step 1 = reines Weiß
80
- if (isPureNeutral) {
91
+ // Neutraltöne: Step 1 = reines Weiß (Seitenhintergrund)
92
+ if (isLowChroma) {
81
93
  scale[1] = '#ffffff';
82
94
  }
83
95
 
@@ -222,9 +234,8 @@ function hslToHex(h, s, l) {
222
234
  * - Die Rampe wird auf den verfügbaren Bereich komprimiert
223
235
  * - Monotonie ist durch die Konstruktion garantiert
224
236
  */
225
- function buildLightnessRamp(baseL) {
237
+ function buildLightnessRamp(baseL, isLowChroma = false) {
226
238
  const topL = 0.985; // Step 1: fast Weiß
227
- const bottomL = 0.25; // Step 12: dunkelster Wert
228
239
 
229
240
  // Base clampen: min. 0.30 damit 3 dunkle Stufen Platz haben,
230
241
  // max. 0.80 damit 8 helle Stufen genug Abstand in sRGB haben
@@ -237,15 +248,30 @@ function buildLightnessRamp(baseL) {
237
248
  const range = topL - step8Target;
238
249
 
239
250
  // Feste Verteilungs-Gewichte: Steps 1-2 bleiben nahe Weiß,
240
- // dann beschleunigter Abstieg zur Base. Inspiriert von Radix' Lightness-Verteilung.
241
- const weights = [0.0, 0.04, 0.10, 0.20, 0.34, 0.50, 0.70, 0.92];
251
+ // dann gleichmäßiger Abstieg zur Base. Sprünge zwischen benachbarten Weights
252
+ // sollen möglichst gleichmäßig ansteigen (kein harter Sprung bei Step 7).
253
+ const weights = [0.0, 0.04, 0.10, 0.20, 0.34, 0.50, 0.67, 0.86];
242
254
  const lightSteps = weights.map(w => topL - w * range);
243
255
 
244
- // Steps 10-12: nach unten von Base weg
245
- const darkRange = safeBaseL - bottomL;
246
- const step10L = safeBaseL - darkRange * 0.12;
247
- const step11L = safeBaseL - darkRange * 0.55;
248
- const step12L = bottomL;
256
+ let step10L, step11L, step12L;
257
+
258
+ if (isLowChroma) {
259
+ // Neutraltöne: Step 12 muss sehr dunkel sein (Hauptschriftfarbe),
260
+ // Step 11 = Low-Contrast Text, gleichmäßigere Verteilung nach unten
261
+ const bottomL = 0.25;
262
+ const darkRange = safeBaseL - bottomL;
263
+ step10L = safeBaseL - darkRange * 0.20;
264
+ step11L = safeBaseL - darkRange * 0.55;
265
+ step12L = bottomL;
266
+ } else {
267
+ // Chromatische Farben: Steps 11-12 näher beieinander,
268
+ // der Farbton bleibt wichtiger als maximale Dunkelheit
269
+ const bottomL = 0.25;
270
+ const darkRange = safeBaseL - bottomL;
271
+ step10L = safeBaseL - darkRange * 0.12;
272
+ step11L = safeBaseL - darkRange * 0.30;
273
+ step12L = safeBaseL - darkRange * 0.42;
274
+ }
249
275
 
250
276
  const ramp = [
251
277
  ...lightSteps, // Steps 1-8