4 Commits

Author SHA1 Message Date
AliceDarkest b4d71d7d59 Merge pull request 'Feature/responsive mobile' (#5) from feature/responsive-mobile into main
mindflux-ci / build (push) Successful in 29s
Reviewed-on: #5
2026-06-29 17:51:19 +00:00
AliceDarkest e26a0c059c Fehler-Rot von Orange abgesetzt (kuehleres Crimson)
--danger lag farblich zu nah am orangen Akzent (v.a. Light-Mode:
accent #d65116 vs danger #c61f2b). Jetzt kuehleres Crimson-Rose:
dunkel #ff4d6d, hell #be123c -> klare Abgrenzung von Orange, weiterhin
eindeutig Alarm-Rot. Erbt automatisch in alle Spiele-/Alert-States.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-29 19:48:03 +02:00
AliceDarkest bf27c9ccdc Fix: Login-Overlay im Light-Mode lesbar (Orange-Panel statt weiss-auf-weiss)
Das Overlay nutzt im Dark-Mode dunkle Surface-Toene mit Glow. Im Light-Mode
sind diese weiss -> das rechte Panel verschwand (weiss auf weiss). Per
[data-theme="light"]-Overrides bekommt es jetzt ein kraeftiges Orange-Panel
(accent-2 -> accent) mit weissem Text, Emblem und Ghost-Button. Dark-Mode
bleibt unveraendert.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-29 19:43:14 +02:00
AliceDarkest 0e4645541d Responsive: mobile Off-Canvas-Navigation + Layout-Anpassungen
- Sidebar wird auf <=820px nicht mehr ausgeblendet (kein Nav-Verlust), sondern
  zu einem Off-Canvas-Drawer mit Hamburger-Button + Backdrop (theme.js
  injiziert ihn auf allen .mf-shell-Seiten; Styles in theme.css).
- Topbar stapelt/umbricht auf Mobil (dekorativer Puls + Suche ausgeblendet,
  kleinere Begrüßung), HUD-Karten-Grid 3->2->1, breite mf-Tabellen horizontal
  scrollbar. Schließen per Backdrop, Nav-Link oder Escape.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-29 19:39:33 +02:00
4 changed files with 76 additions and 4 deletions
+3 -1
View File
@@ -19,12 +19,14 @@ Konto-Löschung sowie ein app-weiter Farb-Relaunch auf das
### Geändert
- **FinalFlux-Inhalte komplett überarbeitet (28 Themen, ~742 Fragen):** die generischen Dummy-Falschantworten („nur Dekoration", „zufälliger Begriff" …) durch plausible, themennahe Distraktoren ersetzt, jede Frage mit echter Begründung und variierender Antwortposition. Jede Themenseite hat jetzt **echten Lehrtext** (Definitionen, Funktionsweise, Rechenbeispiele, Merksätze) statt des bisherigen Stubs.
- **App-weiter Farb-Relaunch auf „Back to the Future"-Palette:** Primär **Feuer-Amber** (`#f0a81a`) + Gelb-Glow, **Flux-Blau** (`#2d9cce`) als Zweitakzent (u. a. Links); warmer Bernstein-Glow statt Matrix-Grün. Dark/Light bleiben (sehr dunkler/sehr heller Grund). Zentral über `theme.css`-Tokens; Legacy-Cyan in `style.css` auf Theme-Variablen umgestellt.
- **Spiele-Feedback ohne Grün:** richtig = **Flux-Blau + ✓**, falsch = **Rot + ✗** in FinalFlux, MindMatch und TechTacular (löst den fehlenden Kontrast von „grün auf grün"); neue Tokens `--success`, `--danger`, `--secondary`.
- **Spiele-Feedback ohne Grün:** richtig = **Flux-Blau + ✓**, falsch = **Rot + ✗** in FinalFlux, MindMatch und TechTacular (löst den fehlenden Kontrast von „grün auf grün"); neue Tokens `--success`, `--danger`, `--secondary`. Das Fehler-Rot ist ein kühleres Crimson (`#ff4d6d` dunkel / `#be123c` hell), damit es sich klar vom orangen Akzent abhebt (v. a. im Light-Mode).
- Registrierungs-Duplikat leitet auf `/?registerError` (kombinierte Seite öffnet automatisch das Signup-Panel).
- **Vollständig responsive / mobiltauglich:** Auf schmalen Screens wird die App-Sidebar nicht mehr ausgeblendet (vorher fehlte die Navigation komplett), sondern zu einer Off-Canvas-Schublade mit Hamburger-Button + Backdrop (global via `theme.js` injiziert, Styles in `theme.css`). Topbar stapelt/umbricht (dekorativer Puls + Suche ausgeblendet), Spielkarten-Grid 3→2→1, breite Tabellen horizontal scrollbar. Spiele, FinalFlux und Login/Registrierung waren bereits responsiv.
### Behoben
- **Konto-Löschung repariert:** „Profil löschen" warf einen 500er (fehlendes `@Transactional` bei einer abgeleiteten Delete-Query) und löschte nichts. Jetzt werden Konto **plus** Spielstände, Achievements und Profilbild-Datei in einer Transaktion entfernt — erfüllt die in der Datenschutzerklärung zugesicherte Löschung (Art. 17 DSGVO).
- Impressum-„Zurück"-Link loggte eingeloggte Nutzer scheinbar aus; jetzt login-abhängig (eingeloggt → Dashboard, sonst → Startseite). Gleiche Logik auf den Rechtsseiten.
- Login-Overlay im **Light-Mode** war weiß-auf-weiß/verwaschen; jetzt kräftiges Orange-Panel mit weißem Text (Dark-Mode unverändert).
### Sicherheit
- Neue Rechtsseiten öffentlich erreichbar (`permitAll` für `/impressum`, `/nutzungsbedingungen`, `/datenschutz`, `/richtlinien`).
+15
View File
@@ -110,6 +110,21 @@
}
.ghost-btn:hover { transform:translateY(-2px); background:var(--surface-2); box-shadow:0 0 22px var(--glow-s); }
/* ---- Light-Mode: Overlay als kräftiges Orange-Panel mit weißem Text ----
(im Dark-Mode ist das Overlay ein dunkles Panel mit Glow; im Light-Mode
wären die Surface-Töne weiß -> Panel verschwände. Daher hier farbig.) */
[data-theme="light"] .overlay {
background:
radial-gradient(600px 340px at 28% 6%, rgba(255,255,255,.18), transparent 60%),
linear-gradient(150deg, var(--accent-2), var(--accent) 48%);
}
[data-theme="light"] .overlay-panel { color:#fff; }
[data-theme="light"] .overlay-panel h3 { color:#fff; text-shadow:0 1px 12px rgba(0,0,0,.22); }
[data-theme="light"] .overlay-panel p { color:#fff; opacity:.96; }
[data-theme="light"] .overlay-panel .o-emblem { background:#fff; filter:drop-shadow(0 0 10px rgba(0,0,0,.25)); }
[data-theme="light"] .ghost-btn { color:#fff; border-color:rgba(255,255,255,.9); box-shadow:none; }
[data-theme="light"] .ghost-btn:hover { background:rgba(255,255,255,.18); box-shadow:none; }
.mobile-switch { display:none; text-align:center; margin-top:1.2rem; color:var(--muted); font-size:.84rem; }
.mobile-switch a { color:var(--accent); font-weight:700; text-decoration:none; cursor:pointer; }
+32 -3
View File
@@ -13,7 +13,7 @@
--border-accent:rgba(240,168,26,.45); --accent:#f0a81a; --accent-2:#f7dc11; --accent-ink:#1c1100;
--secondary:#2d9cce; --secondary-2:#5cc4e8;
--text:#ece3d2; --muted:#8c8170; --heading:#ffffff;
--success:#2d9cce; --danger:#ff5a5f;
--success:#2d9cce; --danger:#ff4d6d;
--glow-s:rgba(240,168,26,.55); --glow-w:rgba(240,168,26,.16);
--g-soft:0 0 18px var(--glow-w);
}
@@ -24,7 +24,7 @@
--border-accent:rgba(214,81,22,.40); --accent:#d65116; --accent-2:#e4801d; --accent-ink:#ffffff;
--secondary:#1f86b8; --secondary-2:#2d9cce;
--text:#33271c; --muted:#8a7d6c; --heading:#241a12;
--success:#1f86b8; --danger:#c61f2b;
--success:#1f86b8; --danger:#be123c;
--glow-s:rgba(214,81,22,.40); --glow-w:rgba(214,81,22,.12);
--g-soft:0 6px 18px var(--glow-w);
}
@@ -171,6 +171,35 @@ a { color:var(--secondary); }
.mf-footer a:hover { color:var(--accent); }
.mf-footer a + a::before { content:"·"; position:absolute; left:-.6rem; color:var(--border); }
/* ===== Mobile-Nav (Off-Canvas-Drawer; Button/Backdrop per theme.js injiziert) ===== */
.mf-burger { display:none; position:fixed; top:.7rem; left:.7rem; z-index:1300; width:42px; height:42px; border-radius:10px; border:1px solid var(--border-accent); background:var(--surface); color:var(--accent); align-items:center; justify-content:center; cursor:pointer; box-shadow:0 0 14px var(--glow-w); }
.mf-burger svg { width:20px; height:20px; }
.mf-nav-backdrop { position:fixed; inset:0; background:rgba(0,0,0,.5); opacity:0; pointer-events:none; transition:opacity .28s ease; z-index:1100; }
body.mf-nav-open .mf-nav-backdrop { opacity:1; pointer-events:auto; }
@media (max-width:1180px){ .mf-shell{grid-template-columns:240px 1fr;} .mf-rightbar{display:none;} .mf-topbar{grid-column:2;} .mf-main{grid-column:2;} }
@media (max-width:820px){ .mf-shell{grid-template-columns:1fr;} .mf-sidebar{display:none;} .mf-topbar,.mf-main{grid-column:1;} .mf-grid{grid-template-columns:repeat(2,1fr);} }
@media (max-width:820px){
/* Shell stapelt; Sidebar wird zum Off-Canvas-Drawer */
.mf-shell, .mf-shell.no-right { display:block; }
.mf-topbar { padding:1.05rem 1rem 0 3.7rem; flex-wrap:wrap; gap:.7rem; }
.mf-main { padding:1.1rem 1rem 1.4rem; }
.mf-rightbar { padding:0 1rem 1.4rem; }
.mf-grid { grid-template-columns:repeat(2,1fr); }
.mf-pulse, .mf-search { display:none; }
.mf-hello h1 { font-size:1.4rem; }
.mf-tools { margin-left:auto; }
.mf-sidebar {
position:fixed; top:0; left:0; height:100dvh; width:min(284px,82vw); z-index:1200;
transform:translateX(-100%); transition:transform .28s ease; overflow-y:auto;
box-shadow:0 18px 50px rgba(0,0,0,.55);
}
body.mf-nav-open .mf-sidebar { transform:translateX(0); }
.mf-burger { display:inline-flex; }
/* breite Tabellen horizontal scrollbar statt überlaufend */
.mf-table { display:block; overflow-x:auto; white-space:nowrap; }
}
@media (max-width:560px){ .mf-grid{grid-template-columns:1fr;} }
+26
View File
@@ -23,6 +23,31 @@
}
window.MindfluxTheme = { toggle: toggle, apply: apply };
// Mobile-Nav: Off-Canvas-Drawer für Seiten mit App-Sidebar (.mf-shell)
function initMobileNav() {
var sidebar = document.querySelector('.mf-sidebar');
if (!sidebar || document.querySelector('.mf-burger')) return;
var burger = document.createElement('button');
burger.className = 'mf-burger';
burger.setAttribute('aria-label', 'Menü öffnen');
burger.innerHTML = '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M3 6h18M3 12h18M3 18h18"/></svg>';
var backdrop = document.createElement('div');
backdrop.className = 'mf-nav-backdrop';
function close() { document.body.classList.remove('mf-nav-open'); }
function toggleNav() { document.body.classList.toggle('mf-nav-open'); }
burger.addEventListener('click', toggleNav);
backdrop.addEventListener('click', close);
sidebar.querySelectorAll('a').forEach(function (a) { a.addEventListener('click', close); });
window.addEventListener('keydown', function (e) { if (e.key === 'Escape') close(); });
document.body.appendChild(backdrop);
document.body.appendChild(burger);
}
document.addEventListener('DOMContentLoaded', function () {
document.querySelectorAll('.mf-theme').forEach(function (b) {
b.setAttribute('role', 'button');
@@ -30,5 +55,6 @@
b.addEventListener('click', toggle);
});
paint();
initMobileNav();
});
})();