diff --git a/admin-lehrer/components/ocr-kombi/StepAnsicht.tsx b/admin-lehrer/components/ocr-kombi/StepAnsicht.tsx
index 841a4e1..5fc1520 100644
--- a/admin-lehrer/components/ocr-kombi/StepAnsicht.tsx
+++ b/admin-lehrer/components/ocr-kombi/StepAnsicht.tsx
@@ -173,6 +173,22 @@ export function StepAnsicht({ sessionId, onNext }: StepAnsichtProps) {
const panelHeight = imgH * scale
const contentZone = grid.zones.find((z) => z.zone_type === 'content')
+ // Dominant row height: median of row-to-row spacings (excluding box-gap jumps)
+ const dominantRowH = useMemo(() => {
+ const cz = grid.zones.find((z) => z.zone_type === 'content')
+ if (!cz || cz.rows.length < 2) return 47
+ const spacings: number[] = []
+ for (let i = 0; i < cz.rows.length - 1; i++) {
+ const y1 = cz.rows[i].y_min_px ?? (cz.rows[i] as any).y_min ?? 0
+ const y2 = cz.rows[i + 1].y_min_px ?? (cz.rows[i + 1] as any).y_min ?? 0
+ const d = y2 - y1
+ if (d > 0 && d < 100) spacings.push(d)
+ }
+ if (spacings.length === 0) return 47
+ spacings.sort((a, b) => a - b)
+ return spacings[Math.floor(spacings.length / 2)]
+ }, [grid])
+
return (
{/* Header */}
@@ -237,7 +253,7 @@ export function StepAnsicht({ sessionId, onNext }: StepAnsichtProps) {
rows={sec.rows}
yStart={sec.yStart}
scale={scale}
- avgRowH={sec.avgRowH}
+ avgRowH={dominantRowH}
/>
)
}
@@ -375,13 +391,19 @@ function BoxSectionRenderer({ zone, scale, avgRowH }: {
const colScale = totalColW > 0 ? width / totalColW : 1
const numCols = zone.columns.length
- // Evenly distribute rows within the box
- const numRows = zone.rows.length
- const evenRowH = numRows > 0 ? height / numRows : rowH
+ // Distribute box height proportionally by text line count per row
+ const rowLineCounts = zone.rows.map((row) => {
+ const maxLines = Math.max(1, ...zone.cells
+ .filter((c) => c.row_index === row.index)
+ .map((c) => (c.text ?? '').split('\n').length))
+ return maxLines
+ })
+ const totalLines = rowLineCounts.reduce((s, n) => s + n, 0)
+ const lineUnitH = totalLines > 0 ? height / totalLines : height
return (
`${(w * colScale).toFixed(1)}px`).join(' ') }}>
- {zone.rows.map((row) => {
+ {zone.rows.map((row, rowIdx) => {
const isSpanning = zone.cells.some((c) => c.row_index === row.index && c.col_type === 'spanning_header')
- // Multi-line height
- const maxLines = Math.max(1, ...zone.cells
- .filter((c) => c.row_index === row.index)
- .map((c) => (c.text ?? '').split('\n').length))
- const cellRowH = evenRowH * (maxLines > 1 ? maxLines * 0.7 : 1)
+ // Height proportional to text line count
+ const rowLines = rowLineCounts[rowIdx] || 1
+ const cellRowH = lineUnitH * rowLines
return (