/* HyperKit - Infinity Board
 *
 * Masonry, and it is a GRID rather than CSS columns. That is the whole design
 * decision and it is worth writing down, because columns look like the easier
 * answer right up until you use them:
 *
 *   - `column-count` fills top-to-bottom THEN across, so the reading order runs
 *     down each column. Pinterest fills row-wise, left to right, and that is
 *     what people mean when they say a wall feels like Pinterest.
 *   - Columns are BALANCED by height. Append a batch and the browser
 *     redistributes everything already on screen to re-balance, so tiles the
 *     visitor was looking at jump to another column.
 *   - And nothing about it guarantees that equal-sized tiles line up in rows.
 *
 * The grid fixes all three. Each tile spans a whole number of 1px rows equal to
 * its own measured height plus the gap, so:
 *
 *   - fill order is row-wise, because that is how grid auto-placement works
 *   - appending never moves an existing tile
 *   - tiles of the SAME size get the SAME span, so their rows start at exactly
 *     the same point, which is the aligned-rows behaviour that was asked for,
 *     while mixed sizes still stagger like a proper masonry
 *
 * 1px rows with a zero row-gap rather than a coarser unit plus a real gap:
 * rounding a tile up to an 8px unit leaves up to 8px of slack under it, and
 * that slack is visible as an uneven gutter. At 1px the reserved space is the
 * tile's height plus the gap exactly.
 *
 * Without JS the grid stays on `grid-auto-rows: auto`, which is an ordinary
 * aligned gallery: not a masonry, but not broken either.
 */

.hk-inf {
	position: relative;
}

.hk-inf--empty {
	padding: 24px;
	color: #888;
	text-align: center;
}

.hk-inf__grid {
	--hk-inf-cols: 4;
	--hk-inf-gap: 16px;

	display: grid;
	grid-template-columns: repeat(var(--hk-inf-cols), minmax(0, 1fr));
	column-gap: var(--hk-inf-gap);
	row-gap: var(--hk-inf-gap);
	/* Tiles are their own height; the span reserves the space. Without this
	   every tile stretches to fill its span and the masonry disappears. */
	align-items: start;
}

/* Added by the script once it can measure. */
.hk-inf__grid.is-masonry {
	grid-auto-rows: 1px;
	row-gap: 0;
}

.hk-inf__item {
	margin: 0;
	min-width: 0;
	line-height: 0;
	overflow: hidden;
	border-radius: 10px;
}

/* Two classes, because Elementor's `.elementor img { height:auto; max-width:100% }`
   is (0,1,1) and a bare element selector loses to it. `video` is not in that
   rule at all, so stating both here is what keeps the two identical. */
.hk-inf .hk-inf__item img,
.hk-inf .hk-inf__item video {
	display: block;
	width: 100%;
	height: auto;
	max-width: 100%;
	border-radius: inherit;
}

/* A video with no poster paints nothing until the first frame decodes, which
   in a masonry column reads as a hole. */
.hk-inf__item--video {
	background: rgba(17, 17, 17, .06);
}

/* Newly appended tiles fade and rise in. Server-rendered tiles carry the class
   too, but they are already on screen so it plays once. */
.hk-inf--fade .hk-inf__item {
	animation: hk-inf-in 500ms cubic-bezier(0.16, 1, 0.3, 1) both;
}

.hk-inf__sentinel {
	width: 100%;
	height: 1px;
}

@keyframes hk-inf-in {
	from { opacity: 0; transform: translateY(14px); }
	to   { opacity: 1; transform: translateY(0); }
}

@media (prefers-reduced-motion: reduce) {
	.hk-inf--fade .hk-inf__item {
		animation: none;
	}
}
