diff --git a/.gamification.json b/.gamification.json index 8d4287b..25906f3 100644 --- a/.gamification.json +++ b/.gamification.json @@ -10,5 +10,5 @@ "streak_tage": 1, "letzter_aktiver_tag": "2026-08-29", "historie": [], - "zuletzt_aktualisiert": "2026-08-29T15:58:35.233410" + "zuletzt_aktualisiert": "2026-08-29T16:00:34.190254" } \ No newline at end of file diff --git a/.nojekyll b/.nojekyll new file mode 100644 index 0000000..1b641f3 --- /dev/null +++ b/.nojekyll @@ -0,0 +1 @@ +# Disable Jekyll on GitHub Pages diff --git a/assets/gamification_data.js b/assets/gamification_data.js index 5057ad2..3825302 100644 --- a/assets/gamification_data.js +++ b/assets/gamification_data.js @@ -11,7 +11,7 @@ window.GAMIFICATION_DATA = { "streak_tage": 1, "letzter_aktiver_tag": "2026-08-29", "historie": [], - "zuletzt_aktualisiert": "2026-08-29T15:58:35.233410" + "zuletzt_aktualisiert": "2026-08-29T16:00:34.190254" }; window.GAMIFICATION_BADGES_KATALOG = { "rechenkonegin": { diff --git a/assets/sidebar.js b/assets/sidebar.js index 80609e5..97b0b5b 100644 --- a/assets/sidebar.js +++ b/assets/sidebar.js @@ -1,181 +1,54 @@ /** - * ๐งญ NEXT-GEN SIDEBAR COMPONENT ๐งญ - * ================================= - * Rendert eine saubere, linksbรผndige Sidebar-Navigation - * fรผr das Hauptportal und alle 27 Kapitel-Seiten. + * ๐งญ NEXT-GEN SIDEBAR LOGIC ๐งญ + * ============================= + * Verwaltet Mobile Drawer Toggles und Live-Lernfortschritt (โ Gelรถst-Badges). */ (function () { - const LEHRPFADE = [ - { - id: "lehrpfad_1", - title: "๐ฑ 1. Grundlagen", - badge: "G01โG10", - items: [ - { id: "01_erste_schritte_taschenrechner", num: "G01", icon: "๐งฎ", title: "Taschenrechner", path: "lehrpfad_1_grundlagen/01_erste_schritte_taschenrechner/index.html" }, - { id: "02_variablen_und_datentypen", num: "G02", icon: "๐ฆ", title: "Variablen & Typen", path: "lehrpfad_1_grundlagen/02_variablen_und_datentypen/index.html" }, - { id: "03_ein_und_ausgabe", num: "G03", icon: "๐ฌ", title: "Ein- & Ausgabe", path: "lehrpfad_1_grundlagen/03_ein_und_ausgabe/index.html" }, - { id: "04_verzweigungen_und_bedingungen", num: "G04", icon: "๐ฆ", title: "Bedingungen (if)", path: "lehrpfad_1_grundlagen/04_verzweigungen_und_bedingungen/index.html" }, - { id: "05_schleifen_und_wiederholungen", num: "G05", icon: "๐ก", title: "Schleifen (for/while)", path: "lehrpfad_1_grundlagen/05_schleifen_und_wiederholungen/index.html" }, - { id: "06_funktionen_und_module", num: "G06", icon: "๐ช", title: "Funktionen & Module", path: "lehrpfad_1_grundlagen/06_funktionen_und_module/index.html" }, - { id: "07_listen_und_sequenzen", num: "G07", icon: "๐", title: "Listen & Sequenzen", path: "lehrpfad_1_grundlagen/07_listen_und_sequenzen/index.html" }, - { id: "08_textverarbeitung_und_strings", num: "G08", icon: "๐ค", title: "String-Methoden", path: "lehrpfad_1_grundlagen/08_textverarbeitung_und_strings/index.html" }, - { id: "09_dictionaries_und_sets", num: "G09", icon: "๐๏ธ", title: "Dicts & Sets", path: "lehrpfad_1_grundlagen/09_dictionaries_und_sets/index.html" }, - { id: "10_comprehensions_datum_algorithmen", num: "G10", icon: "๐", title: "Comprehensions", path: "lehrpfad_1_grundlagen/10_comprehensions_datum_algorithmen/index.html" }, - ] - }, - { - id: "lehrpfad_2", - title: "๐๏ธ 2. OOP Einstieg", - badge: "00โ06", - items: [ - { id: "00_fehlersuche_und_grundlagen", num: "00", icon: "๐", title: "Fehlersuche & Debug", path: "lehrpfad_2_oop_einstieg/00_fehlersuche_und_grundlagen/index.html" }, - { id: "01_einstieg_klassen", num: "01", icon: "๐๏ธ", title: "Einstieg in Klassen", path: "lehrpfad_2_oop_einstieg/01_einstieg_klassen/index.html" }, - { id: "02_init_und_self", num: "02", icon: "โ๏ธ", title: "Konstruktor & self", path: "lehrpfad_2_oop_einstieg/02_init_und_self/index.html" }, - { id: "03_methoden_und_verhalten", num: "03", icon: "๐๏ธ", title: "Methoden & Verhalten", path: "lehrpfad_2_oop_einstieg/03_methoden_und_verhalten/index.html" }, - { id: "04_str_und_darstellung", num: "04", icon: "๐งพ", title: "__str__ Darstellung", path: "lehrpfad_2_oop_einstieg/04_str_und_darstellung/index.html" }, - { id: "04b_umstieg_vscode", num: "04b", icon: "๐ป", title: "VS Code Setup", path: "lehrpfad_2_oop_einstieg/04b_umstieg_vscode/index.html" }, - { id: "04c_git_und_versionskontrolle", num: "04c", icon: "๐ฟ", title: "Git-Versionskontrolle", path: "lehrpfad_2_oop_einstieg/04c_git_und_versionskontrolle/index.html" }, - { id: "05_objekte_kombinieren", num: "05", icon: "๐ต", title: "Objekte kombinieren", path: "lehrpfad_2_oop_einstieg/05_objekte_kombinieren/index.html" }, - { id: "06_abschlussprojekt_tamagotchi", num: "06", icon: "๐ฅ", title: "Projekt: Tamagotchi", path: "lehrpfad_2_oop_einstieg/06_abschlussprojekt_tamagotchi/index.html" }, - ] - }, - { - id: "lehrpfad_3", - title: "๐ 3. Fortgeschritten", - badge: "07โ16", - items: [ - { id: "07_referenzen_und_speicher", num: "07", icon: "๐ง ", title: "Referenzen & Speicher", path: "lehrpfad_3_fortgeschrittenes_oop/07_referenzen_und_speicher/index.html" }, - { id: "08_operator_overloading_dunder", num: "08", icon: "โ", title: "Operator Overloading", path: "lehrpfad_3_fortgeschrittenes_oop/08_operator_overloading_dunder/index.html" }, - { id: "09_eigene_unit_tests_schreiben", num: "09", icon: "๐งช", title: "Unit Tests & TDD", path: "lehrpfad_3_fortgeschrittenes_oop/09_eigene_unit_tests_schreiben/index.html" }, - { id: "10_vererbung_und_super", num: "10", icon: "๐งฌ", title: "Vererbung & super()", path: "lehrpfad_3_fortgeschrittenes_oop/10_vererbung_und_super/index.html" }, - { id: "11_polymorphie_und_interfaces", num: "11", icon: "๐ญ", title: "Polymorphie", path: "lehrpfad_3_fortgeschrittenes_oop/11_polymorphie_und_interfaces/index.html" }, - { id: "12_exceptions_und_fehlerbehandlung", num: "12", icon: "๐ก๏ธ", title: "Exceptions & Fehler", path: "lehrpfad_3_fortgeschrittenes_oop/12_exceptions_und_fehlerbehandlung/index.html" }, - { id: "13_persistenz_json_und_csv", num: "13", icon: "๐พ", title: "Persistenz (JSON/CSV)", path: "lehrpfad_3_fortgeschrittenes_oop/13_persistenz_json_und_csv/index.html" }, - { id: "14_gui_mit_tkinter", num: "14", icon: "๐ฅ๏ธ", title: "Desktop-GUIs (Tkinter)", path: "lehrpfad_3_fortgeschrittenes_oop/14_gui_mit_tkinter/index.html" }, - { id: "15_parameter_und_container", num: "15", icon: "๐", title: "Container & *args", path: "lehrpfad_3_fortgeschrittenes_oop/15_parameter_und_container/index.html" }, - { id: "16_master_abschlussprojekt", num: "16", icon: "๐", title: "Master-Abschlussprojekt", path: "lehrpfad_3_fortgeschrittenes_oop/16_master_abschlussprojekt/index.html" }, - ] - } - ]; - - function detectRootPrefix() { - const p = window.location.pathname; - if (p.includes("/lehrpfad_1_grundlagen/") || p.includes("/lehrpfad_2_oop_einstieg/") || p.includes("/lehrpfad_3_fortgeschrittenes_oop/")) { - return "../../"; - } - return "./"; - } - - function initSidebar() { - const prefix = detectRootPrefix(); - const currentPath = window.location.pathname; - - // Wrap existing body content in .app-main if not wrapped yet - if (!document.querySelector(".app-main")) { - const mainWrapper = document.createElement("div"); - mainWrapper.className = "app-main"; - while (document.body.firstChild) { - mainWrapper.appendChild(document.body.firstChild); - } - document.body.appendChild(mainWrapper); - } - - // Check if sidebar already exists - if (document.querySelector(".app-sidebar")) return; - - // Gamification Data - const gData = window.GAMIFICATION_DATA || { xp: 0, level: 1, titel: "Code-Kรผken ๐ฃ", geloeste_kapitel: [] }; - const solvedSet = new Set(gData.geloeste_kapitel || []); - + document.addEventListener("DOMContentLoaded", () => { // 1. Mobile Drawer Toggle Button - const toggleBtn = document.createElement("button"); - toggleBtn.type = "button"; - toggleBtn.className = "sidebar-mobile-toggle"; - toggleBtn.innerHTML = "โฐ Menรผ"; - document.body.appendChild(toggleBtn); + const toggleBtn = document.querySelector(".sidebar-mobile-toggle"); + const sidebar = document.querySelector(".app-sidebar"); + const overlay = document.querySelector(".sidebar-overlay"); - // 2. Mobile Overlay - const overlay = document.createElement("div"); - overlay.className = "sidebar-overlay"; - document.body.appendChild(overlay); - - // 3. Sidebar Element - const sidebar = document.createElement("aside"); - sidebar.className = "app-sidebar"; - - let navSectionsHtml = ""; - LEHRPFADE.forEach(track => { - let itemsHtml = ""; - track.items.forEach(item => { - const fullLink = prefix + item.path; - const isActive = currentPath.includes(item.id); - const isSolved = solvedSet.has(item.path.replace("/index.html", "")); - - itemsHtml += ` - - - - ${isSolved ? 'โ ' : ''} - - `; + if (toggleBtn && sidebar && overlay) { + toggleBtn.addEventListener("click", () => { + sidebar.classList.toggle("open"); + overlay.classList.toggle("active"); }); - navSectionsHtml += ` -
- `; - }); + overlay.addEventListener("click", () => { + sidebar.classList.remove("open"); + overlay.classList.remove("active"); + }); + } - sidebar.innerHTML = ` - + // 2. Mark Solved Chapters in Sidebar from LocalStorage / GAMIFICATION_DATA + try { + const gData = window.GAMIFICATION_DATA || JSON.parse(localStorage.getItem("python_gamification_progress") || "{}"); + const solvedList = gData.geloeste_kapitel || []; + const solvedSet = new Set(solvedList); - + document.querySelectorAll(".app-sidebar .sidebar-link").forEach(link => { + const href = link.getAttribute("href") || ""; + for (const chapId of solvedSet) { + if (href.includes(chapId)) { + if (!link.querySelector(".sidebar-check")) { + const checkSpan = document.createElement("span"); + checkSpan.className = "sidebar-check"; + checkSpan.innerText = " โ "; + checkSpan.style.fontSize = "0.75rem"; + link.appendChild(checkSpan); + } + } + } + }); - - - - `; - - document.body.prepend(sidebar); - - // Toggle Handler - toggleBtn.addEventListener("click", () => { - sidebar.classList.toggle("open"); - overlay.classList.toggle("active"); - }); - - overlay.addEventListener("click", () => { - sidebar.classList.remove("open"); - overlay.classList.remove("active"); - }); - } - - document.addEventListener("DOMContentLoaded", initSidebar); + // Update Sidebar Footer Level + const levelEl = document.getElementById("sidebar-level-text"); + const xpEl = document.getElementById("sidebar-xp-text"); + if (levelEl && gData.level) levelEl.innerText = "โญ Level " + gData.level; + if (xpEl && gData.xp !== undefined) xpEl.innerText = gData.xp + " XP"; + } catch (e) {} + }); })(); diff --git a/assets/style.css b/assets/style.css index 287c214..605b354 100644 --- a/assets/style.css +++ b/assets/style.css @@ -1,5 +1,5 @@ /* ========================================================================== - โจ PYTHON LERNPORTAL โ CLEAN MODERN DESIGN SYSTEM โจ + โจ PYTHON LERNPORTAL โ ROCK-SOLID MODERN DESIGN SYSTEM โจ ========================================================================== */ :root { @@ -9,9 +9,6 @@ --primary-light: #eef2ff; --primary-glow: rgba(79, 70, 229, 0.15); - --teal: #0d9488; - --teal-light: #f0fdfa; - --emerald: #059669; --emerald-light: #ecfdf5; @@ -24,16 +21,19 @@ --rose: #e11d48; --rose-light: #fff1f2; + --success: #10b981; + --success-light: #ecfdf5; + /* Surfaces & Backgrounds */ --bg-body: #f8fafc; --bg-surface: #ffffff; --bg-subtle: #f1f5f9; - --bg-sidebar: #0f172a; + --bg-sidebar: #090d16; --bg-code: #0b0f19; /* Borders */ --border-color: #e2e8f0; - --border-dark: rgba(255, 255, 255, 0.1); + --border-dark: rgba(255, 255, 255, 0.08); /* Typography */ --text-main: #0f172a; @@ -48,11 +48,11 @@ --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.05); --shadow-md: 0 4px 6px -1px rgba(0, 0, 0, 0.07), 0 2px 4px -1px rgba(0, 0, 0, 0.04); --shadow-lg: 0 10px 15px -3px rgba(0, 0, 0, 0.08), 0 4px 6px -2px rgba(0, 0, 0, 0.04); - --shadow-xl: 0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04); + --shadow-xl: 0 20px 25px -5px rgba(0, 0, 0, 0.12), 0 10px 10px -5px rgba(0, 0, 0, 0.04); --radius-sm: 6px; - --radius-md: 10px; - --radius-lg: 16px; + --radius-md: 12px; + --radius-lg: 18px; --radius-full: 9999px; } @@ -73,17 +73,25 @@ body { color: var(--text-body); line-height: 1.65; font-size: 16px; - display: flex; - min-height: 100vh; + margin: 0; + padding: 0; } /* ========================================================================== - LAYOUT: SIDEBAR (LEFT) + MAIN CONTENT (RIGHT) + APP LAYOUT (FLEX CONTAINER) ========================================================================== */ +.app-layout { + display: flex; + min-height: 100vh; + width: 100%; +} + +/* Sidebar (Left) */ .app-sidebar { width: 290px; min-width: 290px; + max-width: 290px; height: 100vh; position: sticky; top: 0; @@ -94,22 +102,29 @@ body { border-right: 1px solid var(--border-dark); z-index: 100; overflow: hidden; + flex-shrink: 0; } .sidebar-header { padding: 20px 18px; border-bottom: 1px solid var(--border-dark); + background: rgba(255, 255, 255, 0.02); +} + +.sidebar-brand-link { display: flex; align-items: center; gap: 12px; + text-decoration: none; + color: white; } .sidebar-logo { - font-size: 1.7rem; + font-size: 1.6rem; background: rgba(79, 70, 229, 0.2); border: 1px solid var(--primary); - width: 42px; - height: 42px; + width: 40px; + height: 40px; border-radius: var(--radius-sm); display: flex; align-items: center; @@ -124,19 +139,28 @@ body { } .sidebar-subtitle { - font-size: 0.75rem; - color: var(--text-muted); + font-size: 0.72rem; + color: #94a3b8; text-transform: uppercase; letter-spacing: 0.5px; } +.sidebar-quick-nav { + padding: 10px 14px; + border-bottom: 1px solid var(--border-dark); + display: flex; + flex-direction: column; + gap: 2px; + background: rgba(0, 0, 0, 0.2); +} + .sidebar-nav { flex: 1; overflow-y: auto; padding: 14px 12px; display: flex; flex-direction: column; - gap: 16px; + gap: 18px; } .sidebar-nav::-webkit-scrollbar { @@ -149,7 +173,7 @@ body { } .sidebar-group-title { - font-size: 0.75rem; + font-size: 0.74rem; font-weight: 800; color: #94a3b8; text-transform: uppercase; @@ -165,11 +189,11 @@ body { display: flex; align-items: center; gap: 10px; - padding: 8px 12px; + padding: 7px 12px; border-radius: var(--radius-sm); color: #cbd5e1; text-decoration: none; - font-size: 0.88rem; + font-size: 0.86rem; font-weight: 500; transition: all 0.15s ease; border-left: 3px solid transparent; @@ -200,33 +224,30 @@ body { } .sidebar-footer { - padding: 14px 16px; + padding: 12px 16px; border-top: 1px solid var(--border-dark); - background: rgba(0, 0, 0, 0.2); + background: rgba(0, 0, 0, 0.3); } -/* ========================================================================== - MAIN CONTENT AREA - ========================================================================== */ - +/* Main Content Area */ .app-main { flex: 1; + min-width: 0; display: flex; flex-direction: column; - min-width: 0; background: var(--bg-body); } header { background: linear-gradient(135deg, #090d16 0%, #1e1b4b 100%); color: white; - padding: 35px 30px; + padding: 35px 24px; border-bottom: 1px solid var(--border-color); box-shadow: var(--shadow-sm); } .header-container { - max-width: 900px; + max-width: 920px; margin: 0 auto; } @@ -259,7 +280,6 @@ header p { line-height: 1.55; } -/* Nav Links inside Header */ .nav-links { display: flex; gap: 8px; @@ -282,12 +302,11 @@ header p { color: white; } -/* Main Content Container */ .container { - max-width: 900px; + max-width: 920px; width: 100%; - margin: 30px auto; - padding: 0 24px; + margin: 0 auto; + padding: 30px 24px 60px 24px; } /* ========================================================================== @@ -297,7 +316,7 @@ header p { .card { background: var(--bg-surface); border-radius: var(--radius-md); - padding: 28px; + padding: 26px; margin-bottom: 24px; border: 1px solid var(--border-color); box-shadow: var(--shadow-sm); @@ -327,7 +346,6 @@ header p { color: var(--text-body); } -/* Section Header */ .section-header { margin: 35px 0 15px 0; padding-bottom: 8px; @@ -352,7 +370,7 @@ header p { margin-top: 2px; } -/* Track Badges */ +/* Badges */ .track-badge { display: inline-flex; padding: 4px 12px; @@ -368,7 +386,7 @@ header p { .track-3-badge { background: var(--purple-light); color: var(--purple); } /* ========================================================================== - ROADMAP MODULE CARDS (CLEAN & NON-NESTED) + ROADMAP MODULE CARDS ========================================================================== */ .roadmap-grid { @@ -409,7 +427,7 @@ header p { } .roadmap-title { - font-size: 1.15rem; + font-size: 1.12rem; font-weight: 800; margin-bottom: 6px; color: var(--text-main); @@ -449,7 +467,7 @@ header p { } .card-primary-btn:hover { - background: var(--primary-hover); + filter: brightness(0.9); } .card-sublinks { @@ -479,7 +497,7 @@ header p { } /* ========================================================================== - BOXES, CODE & DIDACTICS + BOXES & CODE ========================================================================== */ .box { @@ -504,7 +522,6 @@ header p { .box-danger { background: var(--rose-light); border-left-color: var(--rose); color: #881337; } .box-success { background: var(--emerald-light); border-left-color: var(--emerald); color: #064e3b; } -/* Code Blocks */ .code-container { background: var(--bg-code); border-radius: var(--radius-md); @@ -599,7 +616,7 @@ pre code { flex-wrap: wrap; } -/* Search Bar */ +/* Live Search */ .search-bar-container { background: #ffffff; border: 1px solid var(--border-color); @@ -622,7 +639,289 @@ pre code { background: transparent; } -/* Mobile Toggle */ +/* Gamification HUD */ +.hud-card { + background: linear-gradient(145deg, #090d16 0%, #0f172a 100%); + color: #f8fafc; + border-radius: var(--radius-md); + padding: 24px; + margin-bottom: 25px; + box-shadow: var(--shadow-md); + border: 1px solid rgba(255, 255, 255, 0.1); +} + +.hud-header { + display: flex; + justify-content: space-between; + align-items: center; + flex-wrap: wrap; + gap: 16px; + margin-bottom: 16px; +} + +.hud-user { + display: flex; + align-items: center; + gap: 14px; +} + +.hud-avatar { + font-size: 2.2rem; + background: rgba(79, 70, 229, 0.2); + border: 2px solid #818cf8; + width: 52px; + height: 52px; + display: flex; + align-items: center; + justify-content: center; + border-radius: 50%; +} + +.hud-name { + font-size: 1.25rem; + font-weight: 800; + color: #ffffff; +} + +.hud-title { + font-size: 0.9rem; + color: #94a3b8; +} + +.hud-rank { + color: #fbbf24; + font-weight: 800; +} + +.hud-stats { + display: flex; + gap: 10px; + flex-wrap: wrap; +} + +.hud-stat-box { + background: rgba(255, 255, 255, 0.06); + border: 1px solid rgba(255, 255, 255, 0.1); + padding: 8px 14px; + border-radius: var(--radius-sm); + display: flex; + flex-direction: column; + align-items: center; + min-width: 85px; +} + +.hud-stat-value { + font-size: 1.1rem; + font-weight: 800; + color: #38bdf8; +} + +.hud-stat-label { + font-size: 0.7rem; + color: #94a3b8; + text-transform: uppercase; + letter-spacing: 0.6px; + font-weight: 700; +} + +.hud-progress-container { + margin: 14px 0; +} + +.hud-progress-labels { + display: flex; + justify-content: space-between; + font-size: 0.85rem; + color: #cbd5e1; + margin-bottom: 6px; + font-weight: 600; +} + +.hud-progress-bar-bg { + background: rgba(255, 255, 255, 0.1); + height: 14px; + border-radius: 7px; + overflow: hidden; +} + +.hud-progress-bar-fill { + background: linear-gradient(90deg, #10b981 0%, #06b6d4 50%, #6366f1 100%); + height: 100%; + border-radius: 7px; + transition: width 0.6s ease; +} + +.hud-footer { + display: flex; + justify-content: space-between; + align-items: center; + flex-wrap: wrap; + gap: 12px; + margin-top: 16px; + padding-top: 14px; + border-top: 1px solid rgba(255, 255, 255, 0.08); +} + +.hud-btn { + background: var(--primary); + color: white; + border: none; + padding: 8px 16px; + border-radius: var(--radius-sm); + font-weight: 800; + font-size: 0.88rem; + cursor: pointer; + transition: all 0.15s ease; +} + +.hud-btn:hover { + background: var(--primary-hover); +} + +.hud-cli-tip { + font-size: 0.82rem; + color: #94a3b8; +} + +.hud-cli-tip code { + background: rgba(0, 0, 0, 0.4); + color: #38bdf8; + border: 1px solid rgba(255, 255, 255, 0.1); +} + +/* Parsons */ +.parsons-box { + background: #ffffff; + border: 2px solid #e0e7ff; + border-radius: var(--radius-md); + padding: 20px; + margin: 24px 0; + box-shadow: var(--shadow-sm); +} + +.parsons-header { + margin-bottom: 14px; +} + +.parsons-title { + display: flex; + justify-content: space-between; + align-items: center; + font-size: 1.15rem; + font-weight: 800; + color: var(--primary); + margin-bottom: 4px; +} + +.parsons-badge { + background: var(--amber-light); + color: var(--amber); + padding: 3px 10px; + border-radius: var(--radius-full); + font-size: 0.78rem; + font-weight: 800; +} + +.parsons-instruction { + font-size: 0.9rem; + color: var(--text-muted); + margin: 0; +} + +.parsons-board { + display: flex; + flex-direction: column; + gap: 8px; + margin: 16px 0; +} + +.parsons-line { + display: flex; + align-items: center; + gap: 12px; + background: #f8fafc; + border: 1px solid var(--border-color); + border-radius: var(--radius-sm); + padding: 10px 14px; +} + +.parsons-line:hover { + border-color: var(--primary); + background: var(--primary-light); +} + +.parsons-code { + flex: 1; +} + +.parsons-code code { + background: transparent; + color: var(--text-main); + font-size: 0.92rem; + padding: 0; +} + +.btn-parsons-move { + background: #ffffff; + border: 1px solid var(--border-color); + border-radius: 4px; + padding: 3px 8px; + font-size: 0.75rem; + cursor: pointer; + color: var(--text-muted); + font-weight: 700; +} + +.btn-parsons-move:hover:not(:disabled) { + background: var(--primary); + color: white; + border-color: var(--primary); +} + +.btn-parsons-move:disabled { + opacity: 0.25; + cursor: not-allowed; +} + +/* Certificate Overlay */ +.certificate-overlay { + position: fixed; + inset: 0; + background: rgba(15, 23, 42, 0.85); + backdrop-filter: blur(6px); + z-index: 9999; + display: flex; + align-items: center; + justify-content: center; + padding: 20px; +} + +.certificate-container { + background: #ffffff; + border-radius: var(--radius-lg); + padding: 24px; + max-width: 750px; + width: 100%; + max-height: 90vh; + overflow-y: auto; + box-shadow: var(--shadow-xl); +} + +.certificate-border { + border: 6px double #d97706; + border-radius: var(--radius-sm); + padding: 30px 20px; + text-align: center; + background: #fffdfa; +} + +.certificate-badge { font-size: 0.85rem; font-weight: 800; letter-spacing: 2px; color: #b45309; margin-bottom: 10px; } +.certificate-headline { font-size: 2rem; color: #1e293b; margin-bottom: 6px; font-weight: 800; } +.certificate-student-name { font-size: 1.8rem; font-weight: 800; color: var(--primary); margin: 14px 0; } +.certificate-track-title { font-size: 1.35rem; color: #0f172a; margin: 10px 0; font-weight: 800; } +.certificate-meta { display: flex; justify-content: space-around; font-size: 0.9rem; margin: 20px 0; padding: 10px 0; border-top: 1px solid #e2e8f0; border-bottom: 1px solid #e2e8f0; } + +/* Mobile Sidebar Drawer */ .sidebar-mobile-toggle { display: none; position: fixed; @@ -648,9 +947,8 @@ pre code { z-index: 99; } -/* Responsive Breakpoints */ -@media (max-width: 900px) { - body { +@media (max-width: 960px) { + .app-layout { flex-direction: column; } @@ -677,10 +975,10 @@ pre code { } .container { - padding: 0 16px; + padding: 20px 16px; } header h1 { - font-size: 1.7rem; + font-size: 1.6rem; } } diff --git a/index.html b/index.html index 7aaf8e4..2c196bd 100644 --- a/index.html +++ b/index.html @@ -8,10 +8,177 @@ - -Die Krรถnung aller 3 Lehrpfade: Model-View-Controller (MVC), Vererbung, Polymorphie, JSON- & CSV-Persistenz, robuste Exceptions und eine vollwertige Tkinter Desktop-Applikation!
-