<!DOCTYPE html>
<html lang="de">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Chordprogressor</title>
    <script src="
https://cdn.tailwindcss.com"></script>
    <link href="
https://fonts.googleapis.com/css2?family=Roboto+Mono:wght@400;700&display=swap" rel="stylesheet">
    <style>
        body {
            font-family: 'Roboto Mono', monospace;
        }
        .chord-card {
            transition: all 0.3s ease-in-out;
            box-shadow: 0 4px 6px rgba(0,0,0,0.1), 0 1px 3px rgba(0,0,0,0.08);
        }
        .chord-card:hover {
            transform: translateY(-5px);
            box-shadow: 0 10px 15px -3px rgba(0,0,0,0.1), 0 4px 6px -2px rgba(0,0,0,0.05);
        }
        .btn-rock {
            transition: all 0.2s ease;
            box-shadow: 0 4px 6px rgba(0,0,0,0.1);
        }
        .btn-rock:active {
            transform: translateY(2px) scale(0.98);
            box-shadow: 0 2px 3px rgba(0,0,0,0.1);
        }
        /* Removed the background-image arrow from the select element */
        select {
            -webkit-appearance: none;
            -moz-appearance: none;
            appearance: none;
        }
    </style>
</head>
<body class="bg-gray-800 text-gray-100 flex flex-col items-center justify-center min-h-screen p-4">
    <div class="w-full max-w-5xl text-center">
        <header class="mb-8">
            <h1 class="text-4xl md:text-5xl font-bold text-amber-400 mb-2 tracking-wider">Chordprogressor</h1>
            <p class="text-lg text-gray-400">Finde deine nächste Song-Inspiration.</p>
        </header>
        <main class="bg-gray-900 rounded-2xl p-6 md

-8 shadow-2xl border border-gray-700">
            <!-- Controls -->
            <div class="flex flex-col md:flex-row items-center justify-center gap-4 mb-8 flex-wrap">
                <div class="flex items-center gap-3">
                    <label for="key-select" class="text-lg font-semibold">Tonart:</label>
                    <select id="key-select" class="bg-gray-700 text-white border border-gray-600 rounded-lg pl-4 pr-8 py-2 focus

utline-none focus:ring-2 focus:ring-amber-400"></select>
                </div>
                <div class="flex items-center gap-3">
                    <label for="style-select" class="text-lg font-semibold">Stil:</label>
                    <select id="style-select" class="bg-gray-700 text-white border border-gray-600 rounded-lg pl-4 pr-8 py-2 focus

utline-none focus:ring-2 focus:ring-amber-400"></select>
                </div>
                 <div class="flex items-center gap-3">
                    <label for="mode-select" class="text-lg font-semibold">Modus:</label>
                    <select id="mode-select" class="bg-gray-700 text-white border border-gray-600 rounded-lg pl-4 pr-8 py-2 focus

utline-none focus:ring-2 focus:ring-amber-400"></select>
                </div>
                 <div class="flex items-center gap-3">
                    <label for="bars-select" class="text-lg font-semibold">Takte:</label>
                    <select id="bars-select" class="bg-gray-700 text-white border border-gray-600 rounded-lg pl-4 pr-8 py-2 focus

utline-none focus:ring-2 focus:ring-amber-400"></select>
                </div>
                <button id="generate-btn" class="btn-rock w-full lg:w-auto bg-amber-500 hover:bg-amber-600 text-gray-900 font-bold py-2 px-6 rounded-lg text-lg mt-4 md:mt-0">
                    Progression generieren
                </button>
            </div>
            <!-- Display Area -->
            <div id="progression-display" class="min-h-[250px] bg-gray-800 rounded-xl p-6 flex flex-col items-center justify-center text-center border-2 border-dashed border-gray-700">
                 <p id="initial-message" class="text-gray-500 text-lg">Wähle deine Optionen und klicke auf den Button, um zu starten!</p>
                 <div id="results-container" class="hidden">
                    <p id="progression-name" class="text-2xl font-bold text-amber-300 mb-4"></p>
                    <div id="chords-container" class="flex flex-wrap items-center justify-center gap-4">
                        <!-- Chords will be injected here -->
                    </div>
                    <p id="roman-numerals" class="text-gray-500 mt-6 text-xl tracking-widest"></p>
                </div>
            </div>
        </main>
        <footer class="mt-8 text-gray-500">
            <p>© 2025 Für Songwriter gemacht.</p>
        </footer>
    </div>
    <script>
        // --- Data ---
        const notes = {
            sharp: ['C', 'C#', 'D', 'D#', 'E', 'F', 'F#', 'G', 'G#', 'A', 'A#', 'B'],
            flat:  ['C', 'Db', 'D', 'Eb', 'E', 'F', 'Gb', 'G', 'Ab', 'A', 'Bb', 'B']
        };
        const keyUseFlat = ['F', 'Bb', 'Eb', 'Ab', 'Db', 'Gb'];
        const modeInfo = {
            'Ionian':    { intervals: [0, 2, 4, 5, 7, 9, 11], qualities: ['maj', 'min', 'min', 'maj', 'maj', 'min', 'dim'], name: 'Ionisch (Dur)' },
            'Dorian':    { intervals: [0, 2, 3, 5, 7, 9, 10], qualities: ['min', 'min', 'maj', 'maj', 'min', 'dim', 'maj'], name: 'Dorisch' },
            'Phrygian':  { intervals: [0, 1, 3, 5, 7, 8, 10], qualities: ['min', 'maj', 'maj', 'min', 'dim', 'maj', 'min'], name: 'Phrygisch' },
            'Lydian':    { intervals: [0, 2, 4, 6, 7, 9, 11], qualities: ['maj', 'maj', 'min', 'dim', 'maj', 'min', 'min'], name: 'Lydisch' },
            'Mixolydian':{ intervals: [0, 2, 4, 5, 7, 9, 10], qualities: ['maj', 'min', 'dim', 'maj', 'min', 'min', 'maj'], name: 'Mixolydisch' },
            'Aeolian':   { intervals: [0, 2, 3, 5, 7, 8, 10], qualities: ['min', 'dim', 'maj', 'min', 'min', 'maj', 'maj'], name: 'Äolisch (Moll)' },
            'Locrian':   { intervals: [0, 1, 3, 5, 6, 8, 10], qualities: ['dim', 'maj', 'min', 'min', 'maj', 'maj', 'min'], name: 'Lokrisch' }
        };
        const classicProgressions = [
            { name: "Die Pop-Punk-Hymne", roman: "I-V-vi-IV", bars: 4, styles: ['Pop', 'Rock'] },
            { name: "Die klassische 50er-Jahre", roman: "I-vi-IV-V", bars: 4, styles: ['Pop', 'Rock'] },
            { name: "Die 'Wonderwall'", roman: "vi-IV-I-V", bars: 4, styles: ['Pop', 'Rock'] },
            { name: "Die sanfte Moll-Folge", roman: "i-VI-III-VII", bars: 4, styles: ['Pop', 'Metal'] },
            { name: "Die 'Pachelbel'-Progression", roman: "I-V-vi-iii-IV-I-IV-V", bars: 8, styles: ['Pop', 'Rock'] },
            { name: "Der epische Aufbau", roman: "I-vi-V-IV", bars: 4, styles: ['Rock', 'Pop'] },
            { name: "Hard Rock Power", roman: "I-♭VII-IV", bars: 3, styles: ['Rock', 'Metal'] },
            { name: "Die 'Sweet Home Alabama'", roman: "V-IV-I", bars: 3, styles: ['Rock', 'Blues'] },
            { name: "Arena Rock Anthem", roman: "vi-V-IV", bars: 3, styles: ['Rock']},
            { name: "12-Takt-Blues", roman: "I-I-I-I-IV-IV-I-I-V-IV-I-I", bars: 12, styles: ['Blues'] },
            { name: "Moll-Blues", roman: "i-i-i-i-iv-iv-i-i-v-iv-i-i", bars: 12, styles: ['Blues'] },
            { name: "Dunkle Vorahnung", roman: "i-VI-VII-i", bars: 4, styles: ['Metal', 'Rock'] },
            { name: "Phrygischer Riff", roman: "i-♭II-i-V", bars: 4, styles: ['Metal']},
            { name: "Power Metal Galopp", roman: "vi-iv-v-i", bars: 4, styles: ['Metal']}
        ];
        
        const styleRules = {
            'Pop':  { palette: ['I', 'IV', 'V', 'vi', 'ii', 'iii'], tonic: 'I' },
            'Rock': { palette: ['I', 'IV', 'V', 'vi', '♭VII', 'iii', 'v'], tonic: 'I' },
            'Blues':{ palette: ['I', 'IV', 'V'], tonic: 'I' },
            'Metal':{ palette: ['i', 'VI', 'VII', 'iv', 'v', '♭II', 'III'], tonic: 'i' },
        };
        // --- DOM Elements ---
        const keySelect = document.getElementById('key-select');
        const styleSelect = document.getElementById('style-select');
        const modeSelect = document.getElementById('mode-select');
        const barsSelect = document.getElementById('bars-select');
        const generateBtn = document.getElementById('generate-btn');
        const resultsContainer = document.getElementById('results-container');
        const progressionNameEl = document.getElementById('progression-name');
        const chordsContainer = document.getElementById('chords-container');
        const romanNumeralsEl = document.getElementById('roman-numerals');
        const initialMessage = document.getElementById('initial-message');
        // --- Functions ---
        
        function populateSelectors() {
            notes.flat.forEach(key => keySelect.add(new Option(key, key)));
            keySelect.value = 'C';
            Object.keys(styleRules).forEach(style => styleSelect.add(new Option(style, style)));
            styleSelect.add(new Option('Alle', 'Alle'), styleSelect.options[0]);
            styleSelect.value = 'Alle';
            Object.keys(modeInfo).forEach(modeKey => modeSelect.add(new Option(modeInfo[modeKey].name, modeKey)));
            modeSelect.value = 'Ionian';
            barsSelect.add(new Option('Alle', 'Alle'));
            for (let i = 2; i <= 12; i++) barsSelect.add(new Option(i, i));
            barsSelect.value = 'Alle';
        }
        function getScale(rootKey, mode) {
            const currentNotes = keyUseFlat.includes(rootKey) ? notes.flat : notes.sharp;
            const rootIndex = currentNotes.indexOf(rootKey);
            const modeDetails = modeInfo[mode];
            
            if (rootIndex === -1 || !modeDetails) return [];
            return modeDetails.intervals.map((interval, i) => {
                const noteIndex = (rootIndex + interval) % 12;
                const noteName = currentNotes[noteIndex];
                const quality = modeDetails.qualities
;
                let chordName = noteName;
                if (quality === 'min') chordName += 'm';
                if (quality === 'dim') chordName += 'dim';
                return chordName;
            });
        }
        
        function generateDynamicProgression(style, bars) {
            const rules = styleRules[style] || styleRules['Rock']; // Default to Rock rules
            const progression = [rules.tonic];
            for (let i = 1; i < bars; i++) {
                progression.push(rules.palette[Math.floor(Math.random() * rules.palette.length)]);
            }
            return {
                name: `Dynamische ${style}-Progression`,
                roman: progression.join('-'),
                bars: bars,
                styles: [style]
            };
        }
        function translateProgression(romanProgression, scale, rootKey) {
            const romanMap = { 'i': 0, 'I': 0, '♭ii': 1, 'ii': 1, 'II': 1, 'iii': 2, 'III': 2, 'iv': 3, 'IV': 3, 'v': 4, 'V': 4, 'vi': 5, 'VI': 5, 'vii': 6, 'VII': 6, '♭vii': 6 };
            const romanNumerals = romanProgression.split('-');
            
            const currentNotes = keyUseFlat.includes(rootKey) ? notes.flat : notes.sharp;
            const rootIndex = currentNotes.indexOf(rootKey);
            
            return romanNumerals.map(numeral => {
                if (numeral.toLowerCase() === '♭vii') {
                    const flatSeventhNoteIndex = (rootIndex + 10) % 12;
                    return currentNotes[flatSeventhNoteIndex].replace('b','♭');
                }
                 if (numeral.toLowerCase() === '♭ii') {
                    const flatSecondNoteIndex = (rootIndex + 1) % 12;
                    return currentNotes[flatSecondNoteIndex].replace('b','♭');
                }
                const index = romanMap[numeral.toLowerCase()];
                if (index === undefined || !scale[index]) return '?';
                
                // Adjust for major/minor numeral casing
                if (numeral === numeral.toUpperCase()) { // E.g. V in a minor key
                    const noteName = scale[index].replace('m','').replace('dim','');
                    return noteName;
                }
                if (numeral === numeral.toLowerCase()) { // E.g. i
                     if (scale[index].includes('m') || scale[index].includes('dim')) {
                        return scale[index];
                     }
                     return scale[index] + 'm';
                }
                
                return scale[index];
            });
        }
        
        function displayProgression(progression, key, mode) {
             const scale = getScale(key, mode);
             const chords = translateProgression(progression.roman, scale, key);
            
             progressionNameEl.textContent = progression.name;
             romanNumeralsEl.textContent = `(${modeInfo[mode].name}) ${progression.roman}`;
            
             chordsContainer.innerHTML = '';
             chords.forEach(chord => {
                 if (!chord) return;
                 const chordDiv = document.createElement('div');
                 chordDiv.className = 'chord-card bg-gray-700 rounded-lg w-28 h-28 flex items-center justify-center text-3xl font-bold text-amber-400';
                 chordDiv.textContent = chord.replace('b', '♭').replace('#', '♯');
                 chordsContainer.appendChild(chordDiv);
             });
        }
        
        function findProgression() {
            initialMessage.style.display = 'none';
            resultsContainer.classList.remove('hidden');
            const selectedKey = keySelect.value;
            const selectedStyle = styleSelect.value;
            const selectedMode = modeSelect.value;
            const selectedBars = barsSelect.value;
            let availableProgressions = classicProgressions;
            
            if (selectedStyle !== 'Alle') {
                availableProgressions = availableProgressions.filter(p => p.styles.includes(selectedStyle));
            }
            if (selectedBars !== 'Alle') {
                availableProgressions = availableProgressions.filter(p => p.bars == selectedBars);
            }
            let progressionToDisplay;
            if (availableProgressions.length > 0) {
                // Found a classic progression
                progressionToDisplay = availableProgressions[Math.floor(Math.random() * availableProgressions.length)];
            } else {
                // No classic match, generate one dynamically
                const bars = selectedBars === 'Alle' ? 4 : parseInt(selectedBars);
                const style = selectedStyle === 'Alle' ? 'Rock' : selectedStyle;
                progressionToDisplay = generateDynamicProgression(style, bars);
            }
            
            displayProgression(progressionToDisplay, selectedKey, selectedMode);
        }
        // --- Event Listeners ---
        generateBtn.addEventListener('click', findProgression);
        
        // --- Initial Setup ---
        window.addEventListener('load', populateSelectors);
    </script>
</body>
</html>