Initial-Render hatte keine Span-Geometrie:
renderGrid() hing Items in die Origin-Cell mit width:100% height:100%.
Ein 2x2-Item sah damit aus wie eine 1x1-Box mit Mini-Inhalt.
Resize-Code (in BUG-01/02-Branch, applySize) setzte zwar korrekt
grid-column/row per JS — aber nur WÄHREND Resize. Initial war's kaputt.
Fix:
- renderGrid() hängt Items jetzt direkt in den Grid-Container (cont),
nicht mehr in die Origin-Cell.
- style.gridColumn = '${it.x + 1} / span ${it.w}' setzt die CSS-Span-Geometrie
direkt im Inline-Style.
- Origin-Cell bekommt nur noch die 'occupied'-Klasse (für die Optik).
- DOM-Baum: Items sind Geschwister der Cells → keine DOM-Kollision mehr,
Drag-Events auf Nachbar-Cells werden nicht vom Item verschluckt.
Vorteile:
- 2x2-Item rendert visuell über 2x2 Cells (richtige Größe beim ersten Laden)
- Drag auf JEDE Zelle innerhalb der Item-Bbox funktioniert
- applySize (Resize) kann den Span nahtlos aktualisieren ohne DOM-Wechsel
- Kein Flicker beim Resize (initial state ist schon korrekt)
Beweis: tests/test_span_geometry.js (8/8 grün)
1. gridColumn wird per JS gesetzt
2. gridRow wird per JS gesetzt
3. Item wird in Container (cont) gehängt
4. Item wird NICHT mehr in Origin-Cell gehängt
5. Origin-Cell bekommt 'occupied' Klasse
6. gridColumn Format: <x+1> / span <w>
7. Keine width:100% im Item-CSS-Block
8. CSS-Kommentar erwähnt BUG-03
Hinweis: Mein ursprüngliches Issue-Statement war zu pessimistisch (Items
verdecken keine Nachbarzellen visuell). Sie saßen nur 1x1 in der
Origin-Cell. Dennoch ist der Fix substantiell: Initial-Render zeigt jetzt
korrekte Größe, und zukünftige Resize-Codes können sich auf den Span
verlassen ohne DOM-Mutation.
Closes#5
Bei API-Fehler (HTTP 5xx, Timeout, DNS-Fehler, Connection refused) wird
3x retry mit backoff versucht. Bei 3x fail wird ein auffaelliges rotes
"!"-Schild mit Plugin-Name und Fehlermeldung statt leeren Slot gerendert.
base.py: NEU - fetch_url() Helper mit Retry-Logik + Error-Formatting
+ render_error_banner() Funktion fuer Plugin-Slots.
Co-Authored-By: Hermes <noreply@hermes.local>
Aus dem Backup und Live-Pull vom Pi (10.11.3.144):
- dashboard.py: Grid-Linien nur im freien Hintergrund (nicht durch Widgets)
- templates/index.html: komplett redesigned mit Sidebar + Topbar + Toast + Modal
- plugins/clock.py: responsive Layout (1x1 bis 4x4)
- plugins/system.py, weather.py, minimax.py: mit Threshold-Bars und Color-Variants
- plugins/base.py: NEU — fetch_with_retry Helper (3x retry mit backoff)
+ render_error_banner für fehlgeschlagene API-Plugins
(grosses rotes "!" Icon mit Plugin-Name und Fehler statt Crash)
Cleanup: Helfer-Chaos (renderer.py/2/3, design_a/b/c.html, clock_classic.py,
23x clock_*.png, alte test_*.py) wurde bereits im vorherigen Commit entfernt.
Co-Authored-By: Hermes <noreply@hermes.local>
Admin UI: Dark Minimal / Retro Terminal / Warm Editorial via header buttons
Display: Classic White / Dark / Sepia / Nord / Terminal via Settings tab
Both switchers persist via localStorage / config.json