/**
 * Sticky Sidebar Scroll — the sheet.
 *
 * The front page's filter column is taller than a short window, so the column itself is capped and
	 * given a scroll of its own: the site title and the filter panel scroll together as one stack, while
	 * the products scroll past in the next column and the panel's Apply and Clear stay at the foot. The
	 * box is a full window less the admin bar tall - the room between where the sticky top pins it and
	 * the window's foot - so its foot is the window's foot and the row that ends it sits flush there,
	 * and the card holding the filter grows into the room the title leaves, so the sidebar reads as one
	 * block down to that row. The padding at the foot stays in place, which is the band the pinned row
	 * sits over; overscroll-behavior keeps the column's own scroll from chaining into the page at its
	 * ends. Above core's 782px breakpoint only: below it the filter block renders as a full-screen
	 * overlay of its own, and a nested scroll container would fight it. The column is found by the panel
	 * it holds, not by the core filter block: that block is rendered for signed-in readers only, so
	 * anchoring on it left the cap off - and the script unattached - for everyone else.
 *
 * The box is the column, not the panel inside it: the column is what has the title and the filter to
 * show, and the whole of the sidebar is what should scroll. The group around the panel no longer
 * sticks - a sticky box inside a scroll box would pin the filters and let the title travel out from
 * above them - so the column holds the sidebar in the window instead, at the admin bar's offset,
 * which is also where the cap is measured from: pinned, the column's foot is the window's foot, and
 * the row that ends it sits flush there. The room that row needs is the band the column's own padding
 * keeps at its foot: the row's height and a little air above it.
 *
 * The bar is drawn by the script rather than asked of the platform. On macOS the platform
 * scrollbar is an overlay that fades out when idle, and styling ::-webkit-scrollbar does not make
 * it persistent: a probe page holding all three techniques side by side — the pseudo-elements, the
 * standard pair, and neither — showed every one of them reserving no space and painting nothing
 * while idle. So no CSS yields an always-visible bar here, and the track and thumb below are
 * elements instead. That also lets the bar be visible while the panel has nothing to scroll, which
 * is the point of it: it says the column scrolls before you try.
 *
 * The native bar is hidden only once the drawn one is in place, by the class the script adds
 * alongside it, so a reader without the script keeps the scrollbar their browser gives them.
 */

/*
 * Every query below asks for the column that holds the storefront's own filter, and the column holding
 * the search row's popup is not it. Both columns now contain a copy of the filter block - the sidebar's
 * and the popup's - so the bare `:has(.woo-filter)` matched the content column as well, and gave it the
 * sidebar's window-tall sticky scroll box and its foot padding. That took the page's own height with it:
 * the document came out one window tall, the grid scrolling inside the column instead. The popup row is
 * what tells the two columns apart, and it stands in the content column only.
 */
@media (min-width: 782px) {
	body.home .wp-block-columns > .wp-block-column:has(.woo-filter):not(:has(.woo-filter-popup-row)) {
		/*
		 * Sticky, so the sidebar stays while the products scroll past, and a full window tall: the window
		 * less the admin bar, which is the room between where the sticky top pins the column's top and the
		 * window's foot. So the box's foot is the window's foot, the row pinned at it sits flush with the
		 * window's bottom edge, and the whole of the sidebar - title, filter and all - has that height to
		 * be laid out in. Capped instead at the height its content needs, the box stopped short of the
		 * window's foot wherever there was room to spare, and left the row hanging below the panel; where
		 * the content is genuinely taller than the window the box scrolls, which is what it is here for.
		 * Border-box sizing, so the band the pinned row needs at the foot - kept by the padding below -
		 * comes out of that height rather than adding to it and putting the box past the window's foot.
		 */
		/*
		 * The admin bar's offset, asked for here the way core asks for it on the blocks it pins itself.
		 * Core defines this value only for its own sticky blocks - the rule is scoped to .is-position-sticky
		 * - and this column is not one of them, so the pair of measures below were reading the 0px fallback
		 * for a signed-in reader as well. That read as a full window tall box pinned at the window's own top:
		 * its foot sat 32px past the window's foot, and its travel in the row fell exactly that far short of
		 * the page's own scroll, so the last 32px of that scroll - the height of the bar - carried the sidebar
		 * up with the page. A drift of that size at the end of a scroll is what a box pinned here must never
		 * do, and it is invisible to anyone signed out, where no bar is printed and 0px is the true figure.
		 * Declared, the box is a window less the bar, its foot is the window's foot, and the two agree
		 * however far the page scrolls. Below core's 600px the block sets this to 0 itself; this sheet's
		 * queries start at 782px, where that override does not reach.
		 */
		--wp-admin--admin-bar--position-offset: var(--wp-admin--admin-bar--height, 0px);
		position: sticky;
		top: var(--wp-admin--admin-bar--position-offset, 0px);
		align-self: start;
		display: flex;
		flex-direction: column;
		box-sizing: border-box;
		height: calc(100vh - var(--wp-admin--admin-bar--position-offset, 0px));
		overscroll-behavior: contain;
		overflow-y: scroll;
	}

	/*
	 * The card that holds the filter takes the room the title leaves, so the sidebar reaches the row at
	 * its foot as one block instead of stopping above it with the page showing through. Growing, never
	 * shrinking: it stretches into spare room, and where the filter needs more than that the box scrolls
	 * rather than squeezing the card. The air the pinned row keeps below the filter is this card's own
	 * padding at its foot, set with the pinned rules below, so that it too is grey.
	 */
	body.home .wp-block-columns > .wp-block-column:has(.woo-filter):not(:has(.woo-filter-popup-row)) > .wp-block-group:has(.woo-filter) {
		flex: 1 0 auto;
	}

	/*
	 * The group around the panel stops sticking: the column holds the sidebar in the window now, and a
	 * sticky box inside the scroll box would pin the filter while the title scrolled out from above it.
	 */
	body.home .wp-block-columns > .wp-block-column:has(.woo-filter):not(:has(.woo-filter-popup-row)) > .wp-block-group.is-position-sticky {
		position: static;
	}

	/*
	 * Firefox draws a bar of its own only when it is told to, so a reader without the script keeps
	 * a persistent one there. The query is a real discriminator: Blink parses ::-webkit-scrollbar,
	 * so "not selector(...)" is false in Chrome and Safari and this never reaches them. Once the
	 * script's bar is in place the class below overrides the pair, which is what keeps Firefox from
	 * showing two bars at once. The pair below keeps Firefox's rail to the same pair as the drawn one:
	 * the thumb's fill over the strip's own #252525, so the page behind it never shows through there.
	 */
	@supports not selector(::-webkit-scrollbar) {
		body.home .wp-block-columns > .wp-block-column:has(.woo-filter):not(:has(.woo-filter-popup-row)) {
			scrollbar-color: var(--wp--preset--color--control, #292929) #252525;
			scrollbar-width: thin;
		}
	}

	/* Both mechanisms, because Blink honours the standard one only from 121 and the pseudo-element
	   is what the older WebKit builds read. */
	body.home .wp-block-columns > .wp-block-column:has(.woo-filter):not(:has(.woo-filter-popup-row)).has-sticky-sidebar-scrollbar {
		scrollbar-width: none;
	}

	body.home .wp-block-columns > .wp-block-column:has(.woo-filter):not(:has(.woo-filter-popup-row)).has-sticky-sidebar-scrollbar::-webkit-scrollbar {
		display: none;
	}

	/*
	 * The filter panel's own Apply / Clear, held at the foot of the sidebar.
	 *
	 * The panel's footer cannot be held there by sticky, for the reason the staging plugin's sheet
	 * records: a sticky box travels only as far as the content that follows it, and the footer is the
	 * panel's last child, so it came to rest at the end of the plates and rode up with them. Fixed
	 * instead, and placed by the script: its left edge and width are the panel's own, so the row lines
	 * up with the card it belongs to rather than with the column that scrolls, and its foot is the
	 * column's box, which is a full window tall and so ends at the window's foot - so the row ends the
	 * sidebar and sits flush with the window's bottom edge. That placing is the one the staging plugin's
	 * search row had, and this row takes its place; that row is stood down below. The row keeps the panel's own radius,
	 * so the card's foot still reads as rounded where the row comes to rest on it.
	 *
	 * Three rules wait on the class the script sets on the body, so a reader without the script keeps
	 * the footer in the panel's flow and the staging plugin's row in place: the pinned row is an
	 * enhancement, not the only way to reach Apply. The bottom below is the fallback for the first
	 * frame, before the script has measured anything. The room the row needs is the band at the foot of
	 * the sidebar: the row's own height as the column's padding, with the card's own background carrying
	 * the sidebar's colour down to it, so that the colour reaches the row's top edge rather than stopping
	 * short and leaving the page showing between the two. The row comes to rest over that band, which is
	 * what the column's scroll keeps clear of as well.
	 *
	 * The card keeps a band of its own colour below the filter, so the row pinned at the box's foot has the
	 * sidebar's grey above it rather than the page showing through. This is the one value to tune when the
	 * filter should stand closer to the row: 0 puts the last section right up against it.
	 */
	body.home.has-pinned-filter-footer .woo-filter__footer {
		position: fixed;
		bottom: 0;
		z-index: 12;
	}

	body.home.has-pinned-filter-footer .wp-block-columns > .wp-block-column:has(.woo-filter):not(:has(.woo-filter-popup-row)) {
		padding-bottom: 73px !important;
	}

	body.home.has-pinned-filter-footer .wp-block-columns > .wp-block-column:has(.woo-filter):not(:has(.woo-filter-popup-row)) > .wp-block-group:has(.woo-filter) {
		padding-bottom: 32px !important;
	}

	body.home.has-pinned-filter-footer .woo-filter-staging {
		display: none;
	}
}

/*
 * The drawn bar. The script places it — fixed, against the panel's rectangle, so it stays with the
 * panel while the page scrolls and does not move with the plates inside it — and sizes the thumb;
 * everything else is here. The bar carries #252525 as its track: opaque, so the page behind it never
 * shows through, and one step above the panel's own ground, #202020, which is what the strip wore
 * until now; it is two steps above the site's own surface, #1a1a1a, which is what it wore before that.
 * It has no border of its own. Two 1px hairlines of custom-color-3, #303030, ran down its
 * sides until they were asked to go: at 1.32 to 1 against the strip they were a hairline rather than a
 * line, and they were the one part of the rail that said where the strip's sides are - but the sides
 * are read from the strip's own colour meeting the page's, and the rail reads the same without them.
 * The thumb is what answers the pointer, and it is the full width of the bar, so the
 * whole strip is grabbable: a press anywhere in it drags, there being no beside the thumb left
 * to page from. Its left margin, 8px, is what lands it flush against the column it marks: the script
 * sets the bar's left edge 8px inside that column's right edge, so the margin brings the strip's first
 * pixel onto the panel's last one. At 9px a single pixel of the page showed between the two - the light
 * line that read as the rail's border, and the one place the page did not belong. A fixed box adds its
 * margin to the offset the script sets, so the placement is settled here while the script stays out of it.
 * The borders that sat in the 8px are gone, so nothing has to be taken out of it: 8px is the strip and
 * the strip is the 8px, its first pixel still on the panel's last one, and nothing the script measures
 * has moved.
 */
.sticky-sidebar-scroll__bar {
	position: fixed;
	z-index: 11;
	width: 8px;
	margin-left: 8px;
	background-color: #252525;
	touch-action: none;
	user-select: none;
	-webkit-user-select: none;
}

/*
 * The thumb is square-ended and carries no border of its own: no radius, no outline, so its corners
 * and its sides meet the strip's own and the rail reads as one straight band down the panel's edge.
 * The absent border is a decision rather than an omission - the thumb spans the bar's full 8px, so a
 * border of its own would have nowhere to sit that its own fill is not already, and pushing one
 * outside would take the thumb's edge off the panel's last pixel, the one place the page must never
 * show. There are no edges under it now either: the hairlines the strip used to carry are gone, so the
 * sides of the rail are the strip's own colour meeting the page's on both sides, with nothing drawn
 * between them. Square where the filter's own
 * scrollbars are rounded: their 13px radius (--woo-filter-sb-radius) still draws them as pills - the
 * variable stays theirs and is no longer read here. The fill is #303030, asked for by name and written
 * out rather than read through the palette: the entry it read until now, filter-dark-chip-bg, is the
 * #2c3138 behind every chip in the dashboard - the filter's own controls, the inbox, the cart drawer
 * and the add-product tile - so retuning it there would have carried all of them. #303030 is the
 * palette's custom-color-3, and it is the fill the header's search box rests on and the one the panel's
 * own Apply and Clear carry, so the rail and the plates it was matched to answer each other again. It
 * is a step up from the #252525 the strip behind it is painted, and the strip is in turn a step up from
 * the site's own #1a1a1a surface, so the rail reads as two rises rather than as one grey band. Stated
 * as channel values rather than as contrast ratios: #30 over #25, and #25 over #1a. That is the point of
 * it - a rail that marks the panel's edge without drawing a channel on it. The rail was asked #252525
 * for the thumb's own fill and #303030 for its hover in between, and both askings were withdrawn: what
 * the thumb wears now is the pair it wore before them. #252525 is asked for again here, but for the
 * track rather than the thumb - a different part of the rail, so the two askings do not collide. The light muted grey that filled it before, #5f6570, has no
 * part in a dark rail. Two parts of the filter's recipe have no counterpart in an 8px rail: its 5px inset (a
 * 26px channel carrying a 16px bar) would leave nothing to see here, and a native scrollbar's own width
 * rules do not apply where the thumb is sized from the scroll ratio. The thumb is there to be seen and
 * grabbed: a full-width bar in the 8px strip, its ends square, an even 8px of it under the cursor
 * anywhere along the strip. Nothing here is keyed to light or dark mode: the panel is pinned to its dark
 * theme in every page mode, and the strip the thumb runs in is painted the rail's own #252525, so the
 * pair reads the same in both.
 */
.sticky-sidebar-scroll__thumb {
	position: absolute;
	top: 0;
	/* The bar has no border, so its padding box begins at its own left edge and 0 is the strip's first
	   pixel: the thumb's 8px ends on the strip's last one. */
	left: 0;
	width: 8px;
	/* The palette's control step, asked onto every control on the site and now onto these thumbs with
	   them: this bar is a control the reader drags, so it reads the same entry as the fields, pills,
	   links and buttons rather than the #303030 it stated before. */
	background-color: var(--wp--preset--color--control, #292929);
	transition: background-color 0.15s ease;
	border-radius: 0;
	cursor: grab;
}

/*
 * The thumb answers the pointer as the header's search box does, and now on the same pair: the two rest
 * on the palette's control step, which the reader has just asked onto every control on the site, and the
 * two warm to #303030. Hovering anywhere in the 8px strip warms the thumb over its
 * own 0.15s fade. Scoped to the strip rather than to the
 * thumb, because the strip is what the pointer lands on - the thumb answers the drag, and the whole
 * strip is grabbable - so the warm holds while the thumb is being dragged too.
 * #303030 is written out rather than read from the palette, whose control-hover entry still holds the
 * #353535 that this strip, the panel's two footer buttons and the card's add to cart wore until this
 * round: the reader has asked every one of them onto #303030 together, so that entry would now name a
 * different figure than the warm they take. The filter's own hover was a near-by grey, #353a42, and this
 * round moved the chips, the sort trigger and the locate field onto #303030 with everything else, so the
 * panel answers with the family too; #353a42 is left to the admin menu's rows, and no control on the site
 * takes it now. A hover matched to a near-by grey would not be the same hover.
 * Only the thumb warms. The strip behind it is the rail's own #252525 track, and the search box has no
 * counterpart to it: there the plate is the whole control.
 * One asymmetry to name: the bar is aria-hidden and carries no tabindex, so this hover has no keyboard
 * counterpart. It does not need one - the strip is a pointer affordance over a scroller that still takes
 * the arrow keys - but the warm is a mouse-only signal.
 */
.sticky-sidebar-scroll__bar:hover .sticky-sidebar-scroll__thumb {
	background-color: #303030;
}

.sticky-sidebar-scroll__bar.is-dragging .sticky-sidebar-scroll__thumb {
	cursor: grabbing;
}

/*
 * The page's own bar, at the far right of the window, dressed as this rail.
 *
 * The rail above is drawn because the platform's bar cannot be dressed the way it needs to be; the
 * page's bar is the one scrollbar on the site that no script can draw instead, so it is written in
 * the two ways a bar can be reached and reads as this rail wherever the engine draws one at all: the
 * 8px width, the square ends and the strip's own pair - the thumb's control step over the track's #252525,
 * warming to #303030, which is the pair and the two figures the thumb here wears. The radius is
 * written as 0 rather than left out: a build that draws a bar of its own rounds the thumb by default,
 * and this rail's ends are square, so the default is the one figure that has to be named to be undone.
 *
 * Two limits, stated rather than hidden. On macOS the platform draws its scrollbar over the content
 * and fades it out while idle, and no rule reaches that overlay: the page's bar reads as the
 * platform's there, which is the very reason the sidebar's rail is drawn rather than styled. And,
 * following the rail, this pair is the same in both page modes - the rail does not answer the theme
 * toggle either, so the two bars read as one; a light-mode pair is one override away if the page's
 * bar should answer it instead. Where an engine does take the 8px, the page's content gains whatever
 * its platform's bar was wider by, since a bar's width is content it does not overlap.
 *
 * The hover answers without a fade: this sheet's own thumb takes the 0.15s, but a scrollbar thumb is
 * a pseudo-element no transition reaches, so the warm lands at once there. The pair for the engines
 * that do not read the pseudo-element is behind the same discriminator this sheet uses for the
 * sidebar, so Blink and Safari take the rules above and Firefox takes the pair below; setting either
 * standard property makes those engines ignore the pseudo-element rules and draw their own bar
 * instead, which is why the two are kept apart rather than written together. Firefox's thin is a step
 * off the 8px - it is the narrowest the property offers, and the colour pair is what the two bars
 * then share.
 */
html::-webkit-scrollbar {
	width: 8px;
}

html::-webkit-scrollbar-button {
	display: none;
}

html::-webkit-scrollbar-track {
	background-color: #252525;
}

html::-webkit-scrollbar-thumb {
	background-color: var(--wp--preset--color--control, #292929);
	border-radius: 0;
}

html::-webkit-scrollbar-thumb:hover {
	background-color: #303030;
}

/*
 * Firefox's copy of the pair, behind the same discriminator the sidebar's own pair uses: the query
 * reads false in Blink and Safari, which parse ::-webkit-scrollbar, so only the engines that would
 * otherwise show an undressed bar take these. It sits on the root rather than on a box, because this
 * bar belongs to the document.
 */
@supports not selector(::-webkit-scrollbar) {
	html {
		scrollbar-color: var(--wp--preset--color--control, #292929) #252525;
		scrollbar-width: thin;
	}
}

/*
 * After the rule it neutralises: a media query does not win on its own, and at equal specificity the
 * later declaration is the one that counts.
 */
@media (prefers-reduced-motion: reduce) {
	.sticky-sidebar-scroll__thumb {
		transition: none;
	}
}
