diff --git a/DEVLOG.md b/DEVLOG.md
index 48e5808..2ae0194 100644
--- a/DEVLOG.md
+++ b/DEVLOG.md
@@ -6758,3 +6758,27 @@ Keine Commits in dieser Session.
- frontend/src/styles/tailwind.css | 61 +++++++++++++++++++++++++++++++++++++++++++++----------------
---
+## 2026-09-07 14:31 – 14:36 (4m)
+**Beschreibung:** Claude Code Session
+**Projekt:** asb-material
+
+### Commits
+- e6eda26 fix(frontend): zirkuläre CSS-Variablen endgültig behoben - kein @theme-Namespace mehr
+
+### Geänderte Dateien
+- DEVLOG.md | 60 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+- frontend/src/components/status/ReadinessBadge.tsx | 8 ++++----
+- frontend/src/components/ui/badge.tsx | 10 +++++-----
+- frontend/src/components/ui/button.tsx | 11 ++++++-----
+- frontend/src/components/ui/card.tsx | 7 +++++--
+- frontend/src/pages/dashboard/DashboardPage.tsx | 10 +++++-----
+- frontend/src/pages/dashboard/TileFrame.tsx | 6 +++---
+- frontend/src/pages/dashboard/tiles/AblaufdatenTile.tsx | 8 ++++----
+- frontend/src/pages/dashboard/tiles/EinsatzbereitschaftTile.tsx | 14 +++++++-------
+- frontend/src/pages/dashboard/tiles/KennzahlenTile.tsx | 2 +-
+- frontend/src/pages/dashboard/tiles/MaengelTile.tsx | 6 +++---
+- frontend/src/pages/dashboard/tiles/PrueftermineTile.tsx | 8 ++++----
+- frontend/src/pages/dashboard/tiles/QualifikationTile.tsx | 8 ++++----
+- frontend/src/styles/tailwind.css | 58 +++++++++++-----------------------------------------------
+
+---
diff --git a/frontend/src/components/AppShell.tsx b/frontend/src/components/AppShell.tsx
index 31b4739..756620a 100644
--- a/frontend/src/components/AppShell.tsx
+++ b/frontend/src/components/AppShell.tsx
@@ -1,4 +1,4 @@
-import type { ReactNode } from "react";
+import { useState, type ReactNode } from "react";
import { NavLink, useNavigate } from "react-router-dom";
import { useAuth } from "../auth/AuthContext";
@@ -6,6 +6,24 @@ import { CommandPalette } from "./CommandPalette";
import { SyncStatus } from "./status/SyncStatus";
import { ThemeToggle } from "./ThemeToggle";
+const SPEICHER_KEY = "mabea-sidebar-eingeklappt";
+
+function eingeklapptLaden(): boolean {
+ try {
+ return localStorage.getItem(SPEICHER_KEY) === "1";
+ } catch {
+ return false;
+ }
+}
+
+function eingeklapptSpeichern(wert: boolean): void {
+ try {
+ localStorage.setItem(SPEICHER_KEY, wert ? "1" : "0");
+ } catch {
+ // Speichern optional
+ }
+}
+
function paletteOeffnen() {
window.dispatchEvent(new Event("mabea:open-command-palette"));
}
@@ -14,6 +32,15 @@ function paletteOeffnen() {
export function AppShell({ children }: { children: ReactNode }) {
const { istAdmin, istVerantwortlich, logout } = useAuth();
const navigate = useNavigate();
+ const [eingeklappt, setEingeklappt] = useState(eingeklapptLaden);
+
+ function umschalten() {
+ setEingeklappt((bisherig) => {
+ const neu = !bisherig;
+ eingeklapptSpeichern(neu);
+ return neu;
+ });
+ }
function handleLogout() {
logout();
@@ -22,41 +49,53 @@ export function AppShell({ children }: { children: ReactNode }) {
return (
-
-
- MABEA
-
-
+
+ >
+ )}
{children}
diff --git a/frontend/src/pages/dashboard/DashboardPage.tsx b/frontend/src/pages/dashboard/DashboardPage.tsx
index fc6c513..14d2281 100644
--- a/frontend/src/pages/dashboard/DashboardPage.tsx
+++ b/frontend/src/pages/dashboard/DashboardPage.tsx
@@ -205,7 +205,7 @@ export function DashboardPage() {
const sichtbareIds = ALLE_TILE_IDS.filter((id) => bearbeitenModus || !layout.ausgeblendet.includes(id));
const rasterLayout: Layout = useMemo(
- () => sichtbareIds.map((id) => ({ i: id, ...layout.raster[id], minW: 2, minH: 2 })),
+ () => sichtbareIds.map((id) => ({ i: id, ...layout.raster[id], minW: 4, minH: 2 })),
[sichtbareIds, layout.raster]
);
diff --git a/frontend/src/pages/dashboard/layout.ts b/frontend/src/pages/dashboard/layout.ts
index eb52bff..a4b6f4e 100644
--- a/frontend/src/pages/dashboard/layout.ts
+++ b/frontend/src/pages/dashboard/layout.ts
@@ -19,7 +19,11 @@ export const ALLE_TILE_IDS: DashboardTileId[] = [
"aktivitaet",
];
-export const GRID_SPALTEN = 12;
+// 24 statt 12 Spalten - feineres Raster, mehr Kontrolle beim Breiter/Schmaler
+// ziehen auf großen Desktop-Monitoren (Nutzer-Feedback: bei 12 Spalten waren
+// Reihen sofort randvoll, kein Spielraum zum Vergrößern ohne Nachbarkachel
+// anzufassen).
+export const GRID_SPALTEN = 24;
export const GRID_ZEILENHOEHE = 56;
export interface RasterPosition {
@@ -32,14 +36,14 @@ export interface RasterPosition {
// Freie Grid-Positionen als Startzustand - grob nach Wichtigkeit sortiert,
// Aufgaben-Kachel volle Breite oben.
export const STANDARD_RASTER: Record = {
- aufgaben: { x: 0, y: 0, w: 12, h: 3 },
- einsatzbereitschaft: { x: 0, y: 3, w: 4, h: 5 },
- prueftermine: { x: 4, y: 3, w: 4, h: 5 },
- ablaufdaten: { x: 8, y: 3, w: 4, h: 5 },
- kennzahlen: { x: 0, y: 8, w: 4, h: 5 },
- maengel: { x: 4, y: 8, w: 4, h: 5 },
- qualifikation: { x: 8, y: 8, w: 4, h: 4 },
- aktivitaet: { x: 0, y: 13, w: 8, h: 5 },
+ aufgaben: { x: 0, y: 0, w: 24, h: 3 },
+ einsatzbereitschaft: { x: 0, y: 3, w: 8, h: 5 },
+ prueftermine: { x: 8, y: 3, w: 8, h: 5 },
+ ablaufdaten: { x: 16, y: 3, w: 8, h: 5 },
+ kennzahlen: { x: 0, y: 8, w: 8, h: 5 },
+ maengel: { x: 8, y: 8, w: 8, h: 5 },
+ qualifikation: { x: 16, y: 8, w: 8, h: 4 },
+ aktivitaet: { x: 0, y: 13, w: 16, h: 5 },
};
export interface DashboardLayout {
@@ -47,7 +51,7 @@ export interface DashboardLayout {
ausgeblendet: DashboardTileId[];
}
-const SPEICHER_KEY = "mabea-dashboard-layout-v2";
+const SPEICHER_KEY = "mabea-dashboard-layout-v3";
function istGueltigeId(wert: unknown): wert is DashboardTileId {
return typeof wert === "string" && (ALLE_TILE_IDS as string[]).includes(wert);
diff --git a/frontend/src/styles/global.css b/frontend/src/styles/global.css
index 690674f..804576d 100644
--- a/frontend/src/styles/global.css
+++ b/frontend/src/styles/global.css
@@ -193,6 +193,38 @@ a {
top: 0;
height: 100vh;
overflow-y: auto;
+ transition: width 0.18s ease, flex-basis 0.18s ease, padding 0.18s ease;
+}
+
+/* Sidebar einklappbar - Nutzer-Wunsch (mehr Platz für breite Dashboard-Raster
+ auf Desktop-Monitoren). Nur der Toggle-Button bleibt sichtbar. */
+.topbar-eingeklappt {
+ width: 48px;
+ flex: 0 0 48px;
+ padding: 1.25rem 0.5rem;
+ align-items: center;
+ overflow: visible;
+}
+
+.topbar-toggle {
+ background: none;
+ border: 1px solid var(--color-border);
+ border-radius: var(--radius-sm);
+ color: var(--color-text-muted);
+ cursor: pointer;
+ font-size: 0.9rem;
+ line-height: 1;
+ padding: 0.4rem 0.55rem;
+ align-self: flex-end;
+}
+
+.topbar-eingeklappt .topbar-toggle {
+ align-self: center;
+}
+
+.topbar-toggle:hover {
+ background: var(--color-surface-sunken);
+ color: var(--color-text);
}
.topbar-brand {