diff --git a/src/components/gallery/JustifiedGallery.tsx b/src/components/gallery/JustifiedGallery.tsx index 2364d10..c7956d7 100644 --- a/src/components/gallery/JustifiedGallery.tsx +++ b/src/components/gallery/JustifiedGallery.tsx @@ -125,7 +125,13 @@ export default function JustifiedGallery({ const isMobile = containerWidth < 640; const targetH = isMobile ? targetRowHeightMobile : targetRowHeight; - const maxItems = isMobile ? maxRowItemsMobile : maxRowItems; + const minRowHeight = Math.round(targetH * 0.8); + const maxItems = (() => { + if (containerWidth < 480) return Math.min(2, maxRowItemsMobile); + if (containerWidth < 720) return Math.min(3, maxRowItems); + if (containerWidth < 1024) return Math.min(4, maxRowItems); + return maxRowItems; + })(); const rowTiles: RowTile[][] = []; let current: Array<{ item: JustifiedGalleryItem; aspect: number }> = []; @@ -164,6 +170,23 @@ export default function JustifiedGallery({ // Estimate the row width if we were to keep targetH const estimatedWidth = aspectSum * targetH + gap * (current.length - 1); + // If the computed height would be too small, split the row earlier. + if (current.length > 1) { + const gaps = gap * (current.length - 1); + const widthWithoutGaps = Math.max(0, available - gaps); + const computedH = widthWithoutGaps / aspectSum; + if (computedH < minRowHeight) { + const last = current.pop(); + if (last) { + aspectSum -= last.aspect; + flush(); + current = [last]; + aspectSum = last.aspect; + } + continue; + } + } + // If we've filled the row (or reached max items) and have at least 2 tiles, flush. if ( (estimatedWidth >= available || current.length >= maxItems) &&