/* Grid overlay
---------------------------------------------
   A ruled grid drawn over a Cover's media, with cards dropped into its cells by
   core's grid layout (columnStart / rowStart on each child).

   The rules below need the column and row counts to space their gradients, and
   block attributes are not reachable from CSS. So features/grid-overlay/
   render.php reads them off the block's `layout` attribute and writes them onto
   the element as --campweb-grid-columns / --campweb-grid-rows — on the front end
   through render_block, and in the editor canvas through
   src/grid-overlay/index.js. The layout attribute stays the single source of
   truth, which is what lets an editor change the grid size without the lines
   drifting out of step.

   The fallbacks below are what renders if those counts are ever missing.

   The counts in use are --campweb-grid-current-columns / -rows. They are the
   desktop counts here, and the tablet media query in styles.php swaps in the
   tablet ones; the breakpoints come from theme.json, which is why that media
   query and the mobile one are generated there, not written here.

   Rows get a fixed height rather than a content-sized one. core's rowCount
   emits `minmax(1rem, auto)`, which collapses every row holding no card, and
   this layout is mostly empty rows by design. The height is one column's
   width, so the cells are square at any column count. 100cqw is the width of
   the Cover's inner container, made a query container at the bottom of this
   file. 10rem is the floor: below it a card's padding, icon and two-line title
   no longer fit, so near the bottom of a band the cells turn taller than wide.

   Every track is a whole number of pixels. A 1px rule on a fractional track
   edge (1500 / 8 = 187.5) is antialiased across two pixels at half strength,
   while the cards' edges and the crosses snap to one — so the grid is made
   a little wider than its container, rounded up to a multiple of the column
   count, and the Cover's own `overflow: clip` hides the few pixels (at most
   one fewer than the column count) past the right edge.

   Moved here from the Campweb theme's core-group.css and core-cover.css
   unchanged, physical properties included: unlike this plugin's other
   stylesheets it has never been laid out for right-to-left. */

.wp-block-group.is-style-grid-overlay {
	--campweb-grid-current-columns: var(--campweb-grid-columns, 8);
	--campweb-grid-current-rows: var(--campweb-grid-rows, 3);
	--campweb-grid-width: round(up, 100cqw, var(--campweb-grid-current-columns) * 1px);
	--campweb-grid-row-height: max(10rem, var(--campweb-grid-width) / var(--campweb-grid-current-columns));
	/* The editor's Grid line colour and opacity settings, the opacity as 0–1;
	   see custom_properties() in render.php. */
	--campweb-grid-line-color: #fff;
	--campweb-grid-line-opacity: 0.32;
	--campweb-grid-line: color-mix(in srgb, var(--campweb-grid-line-color) calc(var(--campweb-grid-line-opacity) * 100%), transparent);

	position: relative;
	width: var(--campweb-grid-width);
	max-width: none;
	grid-template-rows: repeat(var(--campweb-grid-current-rows), var(--campweb-grid-row-height));
}

/* Two tiled layers of rules on ::before, and on ::after a cross centred on
   every intersection. An SVG data URI cannot read a custom property, so the
   cross is a mask over a plain fill of the line colour, on a pseudo-element
   of its own so its opacity can differ from the lines'. The crosses stay
   0.7 / 0.32 times as strong as the lines, the ratio the design started
   from, until they reach full strength.

   The cross is an SVG with no viewBox, so its path keeps its 13px size while
   mask-size stretches only the tile it repeats in. The offset puts the
   cross's 1px strokes (centred at 6.5 in the SVG, so covering 6–7) on the
   rules' first pixel column and row (0–1): -6px, not the -6.5px that would
   centre them on the tile edge, straddle two pixels and snap one up and
   left of the line.

   Each tile draws only its left and top rule, so the grid's right and bottom
   edges get a border of their own. The right one goes where the grid stops
   being visible: the grid runs up to a few pixels past its container (see
   --campweb-grid-width), so ::before ends at the container's edge instead,
   and its tiles are sized from the grid's width rather than its own. */
.wp-block-group.is-style-grid-overlay::before,
.wp-block-group.is-style-grid-overlay::after {
	content: "";
	position: absolute;
	inset: 0;
	z-index: 0;
	pointer-events: none;
}

.wp-block-group.is-style-grid-overlay::before {
	right: calc(var(--campweb-grid-width) - 100cqw);
	border-right: 1px solid var(--campweb-grid-line);
	border-bottom: 1px solid var(--campweb-grid-line);
	background-image:
		linear-gradient(90deg, var(--campweb-grid-line) 0 1px, transparent 1px),
		linear-gradient(180deg, var(--campweb-grid-line) 0 1px, transparent 1px);
	background-size:
		calc(var(--campweb-grid-width) / var(--campweb-grid-current-columns)) 100%,
		100% var(--campweb-grid-row-height);
}

.wp-block-group.is-style-grid-overlay::after {
	--campweb-grid-mark: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M6.5 2v9M2 6.5h9' stroke='white' stroke-width='1'/%3E%3C/svg%3E");

	opacity: min(1, var(--campweb-grid-line-opacity) * 2.1875);
	background: var(--campweb-grid-line-color);
	-webkit-mask: var(--campweb-grid-mark) -6px -6px / calc(var(--campweb-grid-width) / var(--campweb-grid-current-columns)) var(--campweb-grid-row-height) repeat;
	mask: var(--campweb-grid-mark) -6px -6px / calc(var(--campweb-grid-width) / var(--campweb-grid-current-columns)) var(--campweb-grid-row-height) repeat;
}

/* Cards sit above the rules. They are opaque, but the pseudo-elements paint
   after them at the same stacking level without this.

   The rules stop at a card rather than framing it. Those along its left and
   top edges are its own cells' first pixels, so it already covers them; the
   ones along its right and bottom belong to the next cells, so it reaches a
   pixel further on those two sides. In the last column or row that pixel is
   the grid's edge rule instead, and past it the Cover's overflow clips. */
.wp-block-group.is-style-grid-overlay > * {
	position: relative;
	z-index: 1;
	margin-right: -1px;
	margin-bottom: -1px;
}

/* Tablet and mobile: see breakpoint_css() in styles.php. */

/* The Cover around a grid overlay
---------------------------------------------
   These two style the Cover rather than the Group, but only a Cover holding a
   grid overlay, and this file is loaded wherever a Group is rendered — which a
   grid overlay always is. */

/* A grid overlay defines the section's height itself — rows times row height.
   Core's 430px floor on Cover would otherwise leave a strip of bare video
   below the grid whenever that total comes out shorter. */
.wp-block-cover:has(> .wp-block-cover__inner-container > .is-style-grid-overlay) {
	min-height: 0;
}

/* The grid overlay sizes its rows from this container's width (100cqw), which
   excludes the scrollbar where 100vw would not. */
.wp-block-cover__inner-container:has(> .is-style-grid-overlay) {
	container-type: inline-size;
}
