@webmate-studio/builder 0.2.137 → 0.2.139

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.137",
3
+ "version": "0.2.139",
4
4
  "type": "module",
5
5
  "description": "Webmate Studio Component Builder",
6
6
  "keywords": [
@@ -16,10 +16,10 @@
16
16
  * chromaScale = globaler Sättigungsmultiplikator
17
17
  */
18
18
  export const COLOR_SCALE_PRESETS = {
19
- vivid: { label: 'Leuchtend', stdDev: 28, chromaScale: 1.0 },
20
- natural: { label: 'Natürlich', stdDev: 20, chromaScale: 0.85 },
21
- soft: { label: 'Pastellig', stdDev: 13, chromaScale: 0.7 },
22
- muted: { label: 'Gedämpft', stdDev: 18, chromaScale: 0.5 },
19
+ vivid: { label: 'Leuchtend', stdDev: 40, chromaScale: 1.15 },
20
+ natural: { label: 'Natürlich', stdDev: 30, chromaScale: 1.0 },
21
+ soft: { label: 'Pastellig', stdDev: 16, chromaScale: 0.75 },
22
+ muted: { label: 'Gedämpft', stdDev: 22, chromaScale: 0.55 },
23
23
  };
24
24
 
25
25
  /**
@@ -42,8 +42,8 @@ export function generateColorScale(baseHex, curve) {
42
42
  const stdDev = curve?.preset === 'custom' ? (curve.stdDev ?? 20) : (preset?.stdDev ?? 20);
43
43
  const chromaScale = curve?.preset === 'custom' ? (curve.chromaScale ?? 0.85) : (preset?.chromaScale ?? 0.85);
44
44
 
45
- // Neutral-Erkennung: Basis mit niedriger Chroma
46
- const isNeutral = base.c < 0.04;
45
+ // Neutral-Erkennung: Basis mit sehr niedriger Chroma (reines Grau)
46
+ const isPureNeutral = base.c < 0.008;
47
47
 
48
48
  // Lightness-Rampe adaptiv an Base-Lightness
49
49
  const L = buildLightnessRamp(base.l);
@@ -62,7 +62,8 @@ export function generateColorScale(baseHex, curve) {
62
62
 
63
63
  // Chroma über Gaußkurve berechnen
64
64
  let c;
65
- if (isNeutral) {
65
+ if (isPureNeutral) {
66
+ // Reines Grau: minimale Chroma, Step 1 wird weiß
66
67
  c = base.c * 0.3;
67
68
  } else if (step === 9) {
68
69
  // Geclampt: volle Base-Chroma bei korrigierter Lightness
@@ -75,8 +76,8 @@ export function generateColorScale(baseHex, curve) {
75
76
  scale[step] = oklchToHex(mapped.l, mapped.c, mapped.h);
76
77
  }
77
78
 
78
- // Neutral Step 1 = reines Weiß
79
- if (isNeutral) {
79
+ // Reines Neutral Step 1 = reines Weiß
80
+ if (isPureNeutral) {
80
81
  scale[1] = '#ffffff';
81
82
  }
82
83
 
@@ -96,7 +97,7 @@ export function generateDarkColorScale(baseHex, curve) {
96
97
  const stdDev = curve?.preset === 'custom' ? (curve.stdDev ?? 20) : (preset?.stdDev ?? 20);
97
98
  const chromaScale = curve?.preset === 'custom' ? (curve.chromaScale ?? 0.85) : (preset?.chromaScale ?? 0.85);
98
99
 
99
- const isNeutral = base.c < 0.04;
100
+ const isPureNeutral = base.c < 0.008;
100
101
 
101
102
  // Dark Mode: Base etwas heller für bessere Sichtbarkeit
102
103
  const darkBaseL = Math.min(base.l + 0.08, 0.65);
@@ -108,7 +109,7 @@ export function generateDarkColorScale(baseHex, curve) {
108
109
  for (let i = 0; i < 12; i++) {
109
110
  const step = i + 1;
110
111
  let c;
111
- if (isNeutral) {
112
+ if (isPureNeutral) {
112
113
  c = base.c * 0.3;
113
114
  } else {
114
115
  c = computeChroma(L[i], L[8], base.c, stdDev, chromaScale);
@@ -315,14 +316,26 @@ function buildDarkLightnessRamp(darkBaseL) {
315
316
  * sind — wie bei Radix Colors.
316
317
  */
317
318
  function computeChroma(stepL, baseL, baseC, stdDev, chromaScale) {
318
- // Gaußkurve: Peak bei baseL
319
+ // Gaußkurve: Peak bei baseL, flachere Flanken als vorher
319
320
  const diff = baseL - stepL;
320
- const gaussian = Math.exp((-25 / stdDev) * diff * diff);
321
-
322
- // Lightness-Begrenzung: Wie viel Chroma ist bei dieser Lightness sinnvoll?
323
- // Bei L=0 oder L=1 0, bei L≈0.5-0.7 Maximum
324
- // Formel: sin-artige Kurve die bei L=0 und L=1 null ist
325
- const lightnessLimit = Math.pow(Math.sin(stepL * Math.PI), 1.2);
321
+ const gaussian = Math.exp((-12 / stdDev) * diff * diff);
322
+
323
+ // Lightness-Begrenzung: Asymmetrisch
324
+ // Helle Seite (L > 0.85): Chroma fällt steil auf 0 Steps 1-2 bleiben fast weiß
325
+ // Dunkle Seite (L < 0.3): Chroma fällt moderat Steps 11-12 behalten Farbton
326
+ // Mitte (0.3-0.85): Nahezu volle Chroma möglich
327
+ let lightnessLimit;
328
+ if (stepL > 0.85) {
329
+ // Steep falloff for near-white steps
330
+ const t = (stepL - 0.85) / 0.15; // 0 at L=0.85, 1 at L=1.0
331
+ lightnessLimit = 1.0 - t * t; // quadratic drop
332
+ } else if (stepL < 0.3) {
333
+ // Moderate falloff for near-black steps
334
+ const t = stepL / 0.3; // 0 at L=0, 1 at L=0.3
335
+ lightnessLimit = t * t; // quadratic rise
336
+ } else {
337
+ lightnessLimit = 1.0;
338
+ }
326
339
 
327
340
  return baseC * gaussian * lightnessLimit * chromaScale;
328
341
  }