diff --git a/index.html b/index.html
index b3825cb..579a34d 100644
--- a/index.html
+++ b/index.html
@@ -71,8 +71,11 @@
- Harmonien kommen hier
-
+
Farbharmonien
+ Ausgangsfarbe: #3a8fc1
+
+
+
diff --git a/js/app.js b/js/app.js
index b3c40ed..db257ae 100644
--- a/js/app.js
+++ b/js/app.js
@@ -1,5 +1,6 @@
import { initEingabe } from './eingabe.js';
import { initPicker } from './picker.js';
+import { initHarmonien } from './harmonien.js';
// Globaler State — aktive Farbe als { h, s, l } (HSL, 0-360, 0-100, 0-100)
// state.color is read-only from outside — always use setColor() to update,
@@ -30,3 +31,4 @@ function addColorToSchema(hsl) { console.log('addColorToSchema', hsl); }
initEingabe(addFavorit, addColorToSchema);
initPicker(addFavorit, addColorToSchema);
+initHarmonien(addFavorit, addColorToSchema);
diff --git a/js/harmonien.js b/js/harmonien.js
new file mode 100644
index 0000000..0839dbb
--- /dev/null
+++ b/js/harmonien.js
@@ -0,0 +1,77 @@
+import { getHarmonies, hslToHex } from './converter.js';
+import { state } from './app.js';
+
+function renderHarmony(label, colors, onSaveFavorit, onSaveSchema) {
+ const row = document.createElement('div');
+ row.className = 'harmony-row';
+
+ const heading = document.createElement('h3');
+ heading.textContent = label;
+ row.appendChild(heading);
+
+ const swatchesDiv = document.createElement('div');
+ swatchesDiv.className = 'harmony-swatches';
+
+ colors.forEach(hsl => {
+ const hex = hslToHex(hsl);
+
+ const div = document.createElement('div');
+ div.className = 'harmony-swatch';
+
+ const swatch = document.createElement('div');
+ swatch.className = 'swatch';
+ swatch.style.background = hex;
+ swatch.title = hex;
+
+ const hexLabel = document.createElement('span');
+ hexLabel.textContent = hex;
+
+ const btnRow = document.createElement('div');
+ btnRow.style.cssText = 'display:flex;gap:0.25rem';
+
+ const favBtn = document.createElement('button');
+ favBtn.className = 'action-btn';
+ favBtn.textContent = 'Fav';
+ favBtn.style.fontSize = '0.7rem';
+ favBtn.addEventListener('click', () => onSaveFavorit(hsl));
+
+ const schemaBtn = document.createElement('button');
+ schemaBtn.className = 'action-btn';
+ schemaBtn.textContent = '+Schema';
+ schemaBtn.style.fontSize = '0.7rem';
+ schemaBtn.addEventListener('click', () => onSaveSchema(hsl));
+
+ btnRow.appendChild(favBtn);
+ btnRow.appendChild(schemaBtn);
+
+ div.appendChild(swatch);
+ div.appendChild(hexLabel);
+ div.appendChild(btnRow);
+ swatchesDiv.appendChild(div);
+ });
+
+ row.appendChild(swatchesDiv);
+ return row;
+}
+
+function render(onSaveFavorit, onSaveSchema) {
+ const hsl = state.color;
+ const hex = hslToHex(hsl);
+
+ document.getElementById('harmonien-base-hex').textContent = hex;
+ document.getElementById('harmonien-base-preview').style.background = hex;
+
+ const grid = document.getElementById('harmonien-grid');
+ grid.textContent = '';
+
+ const h = getHarmonies(hsl);
+ grid.appendChild(renderHarmony('Komplementar', h.komplementaer, onSaveFavorit, onSaveSchema));
+ grid.appendChild(renderHarmony('Analog', h.analog, onSaveFavorit, onSaveSchema));
+ grid.appendChild(renderHarmony('Triade', h.triade, onSaveFavorit, onSaveSchema));
+ grid.appendChild(renderHarmony('Split-Komplementar', h.splitKomplementaer, onSaveFavorit, onSaveSchema));
+}
+
+export function initHarmonien(onSaveFavorit, onSaveSchema) {
+ document.addEventListener('colorChanged', () => render(onSaveFavorit, onSaveSchema));
+ render(onSaveFavorit, onSaveSchema);
+}
diff --git a/style.css b/style.css
index 7e8a4d6..0805036 100644
--- a/style.css
+++ b/style.css
@@ -103,3 +103,17 @@ button.action-btn:hover { background: #f0f0f0; }
}
#picker-dropzone p { margin-bottom: 0.75rem; color: #666; font-size: 0.9rem; }
+
+/* --- Harmonien-Tab --- */
+.subtitle { font-size: 0.85rem; color: #666; margin-bottom: 0.5rem; }
+
+.harmony-row h3 { font-size: 0.9rem; margin-bottom: 0.5rem; }
+.harmony-swatches { display: flex; gap: 0.75rem; flex-wrap: wrap; align-items: flex-start; }
+.harmony-swatch {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ gap: 0.25rem;
+}
+.harmony-swatch .swatch { width: 56px; height: 56px; }
+.harmony-swatch span { font-size: 0.75rem; font-family: monospace; }