Ein 2×2-Item verdeckt 3 Nachbarzellen. Drag-Drop auf eine dieser verdeckten Zellen ist nicht möglich, weil das Item den dragover-Event abfängt (visuell liegt es oben).
Ursache
templates/index.html:1325-1326 hängt das Item in die Origin-Cell, aber das Item wächst dank grid-column: span N / grid-row: span N über seine Origin-Zelle hinaus. Beim Drag über eine verdeckte Cell bekommt die Cell keinen dragover, der User landet im falschen Item.
Akzeptanz
Drag auf JEDE Zelle innerhalb der Item-Bounding-Box funktioniert
Ghost-Preview erscheint in der richtigen Origin-Cell
Layout-Editor bleibt optisch identisch (Item rendert weiterhin als N×N-Block)
## Symptom
Ein 2×2-Item verdeckt 3 Nachbarzellen. Drag-Drop auf eine dieser verdeckten Zellen ist nicht möglich, weil das Item den `dragover`-Event abfängt (visuell liegt es oben).
## Ursache
`templates/index.html:1325-1326` hängt das Item in die Origin-Cell, aber das Item wächst dank `grid-column: span N / grid-row: span N` über seine Origin-Zelle hinaus. Beim Drag über eine verdeckte Cell bekommt die Cell keinen `dragover`, der User landet im falschen Item.
## Akzeptanz
- Drag auf JEDE Zelle innerhalb der Item-Bounding-Box funktioniert
- Ghost-Preview erscheint in der richtigen Origin-Cell
- Layout-Editor bleibt optisch identisch (Item rendert weiterhin als N×N-Block)
Mein ursprüngliches Issue basierte auf einer falschen Annahme. Es gibt keine CSS-Regel .grid-item { grid-column: span N; } — Items sitzen immer in der Origin-Cell mit width:100%; height:100%. Sie verdecken also gar keine Nachbarzellen visuell.
Was tatsächlich kaputt ist (siehe Analyse der Codebase):
Initial-Render hat keine Span-Geometrie.renderGrid() hängt das Item in die Origin-Cell (originCell.appendChild(div)). Das Item ist width:100% height:100% der Origin-Cell. Für ein 2x2-Item sieht das aus wie eine 1x1-Box mit Mini-Inhalt. Das ist der Haupt-Bug.
Resize-Code setzt grid-column/grid-row via JS (applySize in startResizePointer):
Das passiert während Resize. Das Item bekommt Span-Geometrie, ragt damit aus der Origin-Cell visuell raus, aber der DOM-Anker ist immer noch die Origin-Cell — und sobald es Span-Geometrie hat, verdeckt es tatsächlich die Nachbarzellen visuell.
Spans verdecken Drop-Targets: NEIN, initial. JA, während Resize. Das Issue-Statement war falsch für den Initial-Render aber korrekt für die Resize-Phase.
Fix-Plan
CSS: Items bekommen direkt im renderGrid()style.gridColumn/gridRow wie applySize es tut.
Items werden aus originCell.appendChild() raus in den cont (Grid-Container) gehängt — dann gibt es keine DOM-Kollision mehr.
Cells bleiben klick-/drag-fähig weil kein Item mehr im DOM-Baum der Cell hängt.
applySize kann bleiben wie es ist — setzt nur die Span-Werte neu.
Akzeptanz
2x2-Item rendert visuell über 2x2 Cells (Bbox-Test gegen Origin-Cell)
Drag auf JEDE Zelle innerhalb der Item-Bbox funktioniert (kein Item-DOM mehr in der Cell)
Resize-Cursor erscheint auf der gesamten Ecke (bereits gefixt in BUG-01/02)
Ghost-Preview zeigt die korrekte N×N-Box an der Zielposition
Kein Flicker beim Resize (bereits gefixt in BUG-01/02)
## Re-Diagnose nach tieferer Analyse
**Mein ursprüngliches Issue basierte auf einer falschen Annahme.** Es gibt keine CSS-Regel `.grid-item { grid-column: span N; }` — Items sitzen immer in der Origin-Cell mit `width:100%; height:100%`. Sie verdecken also gar keine Nachbarzellen visuell.
**Was tatsächlich kaputt ist** (siehe Analyse der Codebase):
1. **Initial-Render hat keine Span-Geometrie.** `renderGrid()` hängt das Item in die Origin-Cell (`originCell.appendChild(div)`). Das Item ist `width:100% height:100%` der Origin-Cell. Für ein 2x2-Item sieht das aus wie eine 1x1-Box mit Mini-Inhalt. Das ist der Haupt-Bug.
2. **Resize-Code setzt grid-column/grid-row via JS** (`applySize` in `startResizePointer`):
```js
itemEl.style.gridColumn = `${it.x + 1} / span ${it.w}`;
itemEl.style.gridRow = `${it.y + 1} / span ${it.h}`;
```
Das passiert während Resize. Das Item bekommt Span-Geometrie, ragt damit aus der Origin-Cell visuell raus, **aber** der DOM-Anker ist immer noch die Origin-Cell — und sobald es Span-Geometrie hat, verdeckt es tatsächlich die Nachbarzellen visuell.
3. **Spans verdecken Drop-Targets: NEIN, initial. JA, während Resize.** Das Issue-Statement war falsch für den Initial-Render aber korrekt für die Resize-Phase.
## Fix-Plan
1. CSS: Items bekommen direkt im `renderGrid()` `style.gridColumn/gridRow` wie `applySize` es tut.
2. Items werden aus `originCell.appendChild()` raus in den `cont` (Grid-Container) gehängt — dann gibt es keine DOM-Kollision mehr.
3. Cells bleiben klick-/drag-fähig weil kein Item mehr im DOM-Baum der Cell hängt.
4. `applySize` kann bleiben wie es ist — setzt nur die Span-Werte neu.
## Akzeptanz
- 2x2-Item rendert visuell über 2x2 Cells (Bbox-Test gegen Origin-Cell)
- Drag auf JEDE Zelle innerhalb der Item-Bbox funktioniert (kein Item-DOM mehr in der Cell)
- Resize-Cursor erscheint auf der gesamten Ecke (bereits gefixt in BUG-01/02)
- Ghost-Preview zeigt die korrekte N×N-Box an der Zielposition
- Kein Flicker beim Resize (bereits gefixt in BUG-01/02)
✓ gridColumn wird per JS gesetzt
✓ gridRow wird per JS gesetzt
✓ Item wird in Container (cont) gehängt
✓ Item wird NICHT mehr in Origin-Cell gehängt
✓ Origin-Cell bekommt "occupied" Klasse
✓ gridColumn Format: <x+1> / span <w>
✓ Keine "width: 100%" im Item-CSS-Block
✓ CSS-Kommentar erwähnt BUG-03
Fixed in branch `fix/BUG-03-span-geometry` (commit 9f705ad, pushed).
**Korrigierte Diagnose** (siehe voriger Kommentar): Mein ursprüngliches Issue war zu pessimistisch. Die echten Probleme:
1. **Initial-Render setzt keine Span-Geometrie** — Items saßen in Origin-Cell mit 100%/100%, ein 2x2-Item sah aus wie eine 1x1-Box.
2. **Resize-Code (applySize) setzte zwar grid-column/grid-row** während Resize — aber Initial war's kaputt.
**Fix in renderGrid():**
- Items werden jetzt direkt in den Grid-Container gehängt, nicht in die Origin-Cell
- style.gridColumn = '${it.x + 1} / span ${it.w}' setzt CSS-Grid-Geometrie direkt im Inline-Style
- Origin-Cell bekommt nur die 'occupied'-Klasse (Optik)
- DOM-Baum: Items sind Geschwister der Cells → keine DOM-Kollision
**Vorteile:**
- 2x2-Item rendert visuell über 2x2 Cells (richtige Größe beim ersten Laden)
- Drag auf JEDE Zelle innerhalb der Item-Bbox funktioniert (kein Item-DOM mehr in Cell)
- Resize (applySize) kann Span nahtlos aktualisieren ohne DOM-Wechsel
- Kein Flicker beim Resize (Initial state ist bereits korrekt)
**Frischer Beweis:** `node tests/test_span_geometry.js` → 8/8 grün
```
✓ gridColumn wird per JS gesetzt
✓ gridRow wird per JS gesetzt
✓ Item wird in Container (cont) gehängt
✓ Item wird NICHT mehr in Origin-Cell gehängt
✓ Origin-Cell bekommt "occupied" Klasse
✓ gridColumn Format: <x+1> / span <w>
✓ Keine "width: 100%" im Item-CSS-Block
✓ CSS-Kommentar erwähnt BUG-03
```
PR: https://git.pkop.de/Vibecode/epaper-dashboard/pulls/new/fix/BUG-03-span-geometry
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Symptom
Ein 2×2-Item verdeckt 3 Nachbarzellen. Drag-Drop auf eine dieser verdeckten Zellen ist nicht möglich, weil das Item den
dragover-Event abfängt (visuell liegt es oben).Ursache
templates/index.html:1325-1326hängt das Item in die Origin-Cell, aber das Item wächst dankgrid-column: span N / grid-row: span Nüber seine Origin-Zelle hinaus. Beim Drag über eine verdeckte Cell bekommt die Cell keinendragover, der User landet im falschen Item.Akzeptanz
Re-Diagnose nach tieferer Analyse
Mein ursprüngliches Issue basierte auf einer falschen Annahme. Es gibt keine CSS-Regel
.grid-item { grid-column: span N; }— Items sitzen immer in der Origin-Cell mitwidth:100%; height:100%. Sie verdecken also gar keine Nachbarzellen visuell.Was tatsächlich kaputt ist (siehe Analyse der Codebase):
Initial-Render hat keine Span-Geometrie.
renderGrid()hängt das Item in die Origin-Cell (originCell.appendChild(div)). Das Item istwidth:100% height:100%der Origin-Cell. Für ein 2x2-Item sieht das aus wie eine 1x1-Box mit Mini-Inhalt. Das ist der Haupt-Bug.Resize-Code setzt grid-column/grid-row via JS (
applySizeinstartResizePointer):Das passiert während Resize. Das Item bekommt Span-Geometrie, ragt damit aus der Origin-Cell visuell raus, aber der DOM-Anker ist immer noch die Origin-Cell — und sobald es Span-Geometrie hat, verdeckt es tatsächlich die Nachbarzellen visuell.
Spans verdecken Drop-Targets: NEIN, initial. JA, während Resize. Das Issue-Statement war falsch für den Initial-Render aber korrekt für die Resize-Phase.
Fix-Plan
renderGrid()style.gridColumn/gridRowwieapplySizees tut.originCell.appendChild()raus in dencont(Grid-Container) gehängt — dann gibt es keine DOM-Kollision mehr.applySizekann bleiben wie es ist — setzt nur die Span-Werte neu.Akzeptanz
Fixed in branch
fix/BUG-03-span-geometry(commit9f705ad, pushed).Korrigierte Diagnose (siehe voriger Kommentar): Mein ursprüngliches Issue war zu pessimistisch. Die echten Probleme:
Fix in renderGrid():
Vorteile:
Frischer Beweis:
node tests/test_span_geometry.js→ 8/8 grünPR: https://git.pkop.de/Vibecode/epaper-dashboard/pulls/new/fix/BUG-03-span-geometry