/*
 * Reviews display - THE canonical stylesheet for BOTH renders of the contract
 * markup: the PHP SSR fallback inside .w2rr-ssr AND the hydrated React tree
 * (identical classes/structure). PHP enqueues this file whenever a display
 * mount renders, so the SSR view is fully styled before (or without) JS.
 *
 * Selectors are anchored on the `w2rr-` class they style, not wrapped in an
 * ancestor scope. The namespace IS the isolation - `.w2rr-summary__bar` cannot
 * occur in a theme's markup - and an ancestor scope had a real cost: an element
 * shortcode placed outside any wrapper (a review template built from
 * [webrr-review-*] tags) matched nothing and rendered raw.
 *
 * Three kinds of rule keep an explicit scope, for reasons other than isolation:
 *   - `.sp-gallery__item` and `a:focus` are NOT ours alone (a shared gallery
 *     class, and every link on the page), so they must stay narrowed;
 *   - a handful of rules that override host-theme styling double their own class
 *     to keep the weight they need, which says "this weight is deliberate" where
 *     an unrelated ancestor only hid the intent;
 *   - the root rule that styles the wrapper itself.
 *
 * Neutral + theme-friendly like the form styles: fonts/colors inherit, accents
 * ride var(--w2rr-accent) with a fallback.
 */

:is( .w2rr-reviews-mount, .w2rr-summary-mount, .w2rr-single-review, .w2rr-review-el ) {
	font-size: 15px;
	line-height: 1.5;
	color: inherit;
}

/* --- stars (shared renderer) ---------------------------------------------- */

/* Base row in muted #ccc; the fill is the SAME glyph run overlaid and clipped
   by an overflow-hidden wrapper whose inline width = value/scale*100%. */
/* Icon size is ONE number for the whole site: the "Rating size" setting, which
   the shortcodes put on their own root as --w2rr-icon-size. Raising it raises
   the badge on titles, a block's stars, a slide's and the form's together, and
   a shortcode only says something when it wants to differ (icon_size).
   Criteria rows are the single exception and keep their own smaller size. */
.w2rr-stars {
	position: relative;
	display: inline-block;
	line-height: 1;
	white-space: nowrap;
	font-size: var( --w2rr-icon-size, 16px );
}

/* OVERALL rating strip (the review-card header, the summary header) - a single
   icon repeated, so there is nothing to align across rows. Natural glyph width
   + a tight 2px gap, matching the compact badge (Compact::glyph). The
   per-criterion breakdown below overrides this back to the fixed fa-fw box (it
   DOES need its columns to line up). Applied to BASE and FILL alike so the
   clipped overlay stays aligned with the base run. */
.w2rr-stars .w2rr-fa {
	display: inline-block;
	margin-right: 2px;
}

/* Criteria breakdown strips KEEP the fixed advance width (fa-fw metric): each
   criterion may use a different icon, and equal-width strips align the trailing
   avg numbers into a clean column (a bell is far narrower than a circle).
   Higher specificity than the tight default above; margin-right:0 drops its
   gap so only the fixed box governs spacing. */
.w2rr-summary__criterion .w2rr-stars .w2rr-fa,
.w2rr-review__criterion .w2rr-stars .w2rr-fa {
	width: 1.28571429em;
	text-align: center;
	letter-spacing: 2px;
	margin-right: 0;
}

/* Same fixed advance width on the criterion LABEL glyph. FA is a proportional
   font - each glyph carries its own advance width (a bell renders ~18px wide, an
   apple ~14.6px, at the same 16px font-size), so without a fixed box the label
   text after the icon staircases from row to row. The rating strips already get
   this via .w2rr-stars above; this lines the labels up the same way. */
.w2rr-summary__criterion-label .w2rr-fa,
.w2rr-review__criterion-label .w2rr-fa {
	display: inline-block;
	width: 1.28571429em;
	text-align: center;
}

/* "Compact rating display" = single: ONE icon, drawn in the rating color with
   nothing muted behind it - there is no partial fill to show, the number beside
   it carries the value. Same class as the full row so every size rule
   (--w2rr-icon-size, the criteria columns) keeps working unchanged. */
.w2rr-stars--single {
	color: var( --w2rr-stars-color, currentColor );
}

.w2rr-stars--single .w2rr-fa {
	margin-right: 0;
}

.w2rr-stars__base {
	color: #ccc;
}

.w2rr-stars__fill {
	position: absolute;
	top: 0;
	left: 0;
	height: 100%;
	overflow: hidden;
	white-space: nowrap;
	pointer-events: none;
	color: var( --w2rr-stars-color, currentColor );
}

/* --- summary ---------------------------------------------------------------- */

.w2rr-summary {
	margin: 0 0 16px;
}

.w2rr-summary__score {
	display: flex;
	align-items: center;
	flex-wrap: wrap;
	gap: 6px 12px;
}

.w2rr-summary__score .w2rr-stars {
	font-size: var( --w2rr-icon-size, 16px );
}

.w2rr-summary__avg {
	font-size: 32px;
	font-weight: 700;
	line-height: 1;
}

.w2rr-summary__count {
	opacity: 0.7;
}

.w2rr-summary__empty {
	opacity: 0.7;
}

/* histogram: label (bucket) + bar + count per row */

.w2rr-summary__hist {
	max-width: 360px;
	margin: 12px 0 0;
}

.w2rr-summary__hist-row {
	display: flex;
	align-items: center;
	gap: 8px;
	margin: 4px 0;
}

.w2rr-summary__hist-label {
	flex: 0 0 auto;
	min-width: 1.5em;
	white-space: nowrap;
	text-align: right;
	font-size: 0.9em;
	opacity: 0.8;
	/* Equal-width digits so the trailing star lands at the SAME x on every row
	   (proportional figures - "1" narrower than "5" - jag the star column). */
	font-variant-numeric: tabular-nums;
	font-feature-settings: 'tnum';
}

.w2rr-summary__bar {
	flex: 1;
	height: 8px;
	border-radius: 4px;
	background: rgba( 0, 0, 0, 0.08 );
	overflow: hidden;
}

.w2rr-summary__bar > span {
	display: block;
	height: 100%;
	border-radius: inherit;
	background: var( --w2rr-primary, var( --w2dc-primary, var( --rmaps-primary, #2271b1 ) ) );
}

.w2rr-summary__hist-count {
	flex: 0 0 2em;
	font-size: 0.85em;
	opacity: 0.7;
}

/* per-criterion rows: icon+label + stars + numeric */

.w2rr-summary__criteria {
	margin: 12px 0 0;
}

.w2rr-summary__criterion {
	display: flex;
	align-items: center;
	flex-wrap: wrap;
	gap: 4px 10px;
	margin: 4px 0;
}

.w2rr-summary__criterion-label {
	flex: 0 0 11em;
	font-weight: 600;
}

.w2rr-summary__criterion-value {
	font-size: 0.9em;
	opacity: 0.7;
}

/* --- toolbar (React only - SSR renders a static count line) ----------------- */

.w2rr-toolbar {
	display: flex;
	align-items: center;
	justify-content: space-between;
	flex-wrap: wrap;
	gap: 8px 16px;
	margin: 20px 0 12px;
	padding-bottom: 8px;
	border-bottom: 1px solid rgba( 0, 0, 0, 0.1 );
}

.w2rr-toolbar__count {
	font-weight: 600;
}

.w2rr-toolbar__orderby {
	display: inline-flex;
	align-items: center;
	gap: 6px;
}

.w2rr-toolbar__orderby-label {
	font-size: 0.9em;
	opacity: 0.75;
}

.w2rr-toolbar__orderby.w2rr-toolbar__orderby select {
	font: inherit;
	font-size: 0.95em;
	color: inherit;
	/* Opaque, not transparent: the control sits on the page background, and on a
	   tinted or patterned one a see-through select reads as an artefact rather
	   than a field. Matches the legacy toolbar's own dropdown. */
	background: #fff;
	border: 1px solid rgba( 0, 0, 0, 0.25 );
	border-radius: 3px;
	padding: 4px 8px;
}

.w2rr-toolbar__orderby.w2rr-toolbar__orderby select:focus-visible {
	outline: 2px solid var( --w2rr-primary, var( --w2dc-primary, var( --rmaps-primary, #2271b1 ) ) );
	outline-offset: 1px;
}

/* --- list error (single-shot retry) ----------------------------------------- */

.w2rr-list-error {
	padding: 12px 16px;
	border: 1px solid rgba( 0, 0, 0, 0.12 );
	border-left: 4px solid #b32d2e;
	border-radius: 3px;
	background: rgba( 0, 0, 0, 0.02 );
	margin: 0 0 12px;
}

.w2rr-list-error__retry {
	appearance: none;
	margin-left: 12px;
	padding: 3px 12px;
	border: 1px solid rgba( 0, 0, 0, 0.25 );
	border-radius: 3px;
	background: transparent;
	color: inherit;
	font: inherit;
	font-size: 0.9em;
	cursor: pointer;
}

/* --- reviews list ------------------------------------------------------------ */

.w2rr-list.is-loading {
	opacity: 0.5;
	pointer-events: none;
	transition: opacity 0.15s ease;
}

.w2rr-list__empty {
	opacity: 0.7;
	margin: 8px 0;
}

/* --- review card ------------------------------------------------------------- */

/* A review reads as its own card: white plate, rounded, with the separation
   coming from the space BETWEEN cards (margin) rather than padding inside a
   borderless block. The bottom rule stays for themes whose page background is
   also white, where the plate alone would not separate anything. */
.w2rr-review {
	margin: 50px 0;
	background-color: #fff;
	padding: 15px;
	border-radius: 5px;
	border-bottom: 1px solid rgba( 0, 0, 0, 0.08 );
}

.w2rr-review__header {
	display: flex;
	align-items: center;
	flex-wrap: wrap;
	gap: 4px 10px;
}

.w2rr-review__author {
	font-weight: 600;
}

.w2rr-review__date {
	font-size: 0.85em;
	opacity: 0.65;
}

.w2rr-review__stars {
	margin-left: auto;
	display: inline-flex;
	align-items: center;
}

/* --- inside a directory listing page ---------------------------------------
 * A listing page lays its own elements out with the page's horizontal inset,
 * and a block dropped into it inherits that; a second inset from the card's
 * plate would set the reviews in a narrower column than everything above them.
 * Vertical padding stays - the plates still need to breathe.
 *
 * Keyed on the class the mount carries on a listing view (Display::host_class),
 * NOT on the directory's element wrapper: the block reaches most listing pages
 * through the content, with no wrapper around it at all. */
:is( .w2rr-reviews-mount, .w2rr-summary-mount ).w2rr-in-listing .w2rr-review {
	padding-left: 0;
	padding-right: 0;
}

/* --- narrow columns (a sidebar, a widget area, a third-width block) --------
 * Keyed on the CARD's own width, not on where it was placed: the same list is
 * a classic widget on one site, a block in a widget area on the next and a
 * narrow column on a third, and all three want the same thing - a theme's <h3>
 * sizing turns a two-line review title into four lines down there. Only the
 * type scale changes; the cards are the same cards. */
.w2rr-review {
	container-type: inline-size;
	container-name: w2rr-card;
}

@container w2rr-card (max-width: 420px) {
	.w2rr-review__title {
		font-size: 1em;
		line-height: 1.3;
		margin: 0;
	}

	.w2rr-review__title a {
		line-height: inherit;
	}
}

/* The classic-widget wrapper keeps its own rule: a sidebar is narrow whatever
   the card measures, and this also covers browsers without container queries. */
.w2rr-widget .w2rr-review__title {
	font-size: 1em;
	line-height: 1.3;
	margin: 0;
}

.w2rr-widget .w2rr-review__title a {
	line-height: inherit;
}

.w2rr-widget .w2rr-slide__title {
	font-size: 0.95em;
	line-height: 1.3;
}

/* The standalone [webrr-review-rating] element reuses the header's stars+score
   pair, but it is not a header ROW - nothing to push it away from, so the
   auto margin above would shove it to the far edge on its own. */
.w2rr-review-el--rating .w2rr-review__stars {
	margin-left: 0;
}

/* THE rating render (Display::rating_html / <Rating>): icons + the score in
   figures, one box wherever a rating is shown. */
.w2rr-rating {
	display: inline-flex;
	align-items: center;
	line-height: 1;
}

/* The number is sized off --w2rr-icon-size like the icons themselves - a number
   set from the surrounding text would stay put while the icons beside it grew,
   and the pair would stop reading as one rating. Slightly smaller than a glyph,
   so it labels the icons instead of competing with them. */
.w2rr-rating__value {
	margin-left: 0.4em;
	font-size: calc( var( --w2rr-icon-size, 16px ) * 0.85 );
	font-weight: 600;
	line-height: 1;
}

/* The title sits INSIDE the flex header but reads FIRST (order:-1) - a
   full-width row ABOVE the author/date/stars line. No font-size on purpose:
   it's an <h3>, so the theme's heading sizing decides. */
/* The header is a wrapping flex row whose SOURCE order is meta-then-title; the
   negative orders lift the title (and, under it, the attribution) above the
   author/date/stars line. -2 and -1 rather than -1 and 0 so the attribution
   cannot tie with the meta items and fall in beside them. */
.w2rr-review__title {
	order: -2;
	flex-basis: 100%;
	margin: 0 0 10px;
	color: inherit;
}

.w2rr-review__header .w2rr-review__target {
	order: -1;
	flex-basis: 100%;
}

.w2rr-review__body {
	margin: 20px 0;
	overflow-wrap: break-word;
}

.w2rr-review__body p {
	margin: 0 0 8px;
}

.w2rr-review__body p:last-child {
	margin-bottom: 0;
}

.w2rr-review__body img {
	max-width: 100%;
	height: auto;
}

/* small per-criterion rows inside a card */

.w2rr-review__criteria {
	font-size: 0.9em;
	margin: 20px 0;
}

/* Criteria are the exception to the shared size, in BOTH places they appear: a
   list five rows deep at badge size reads as a wall, and these two are meant to
   sit below the score they explain. Fixed at what they have always been, so
   raising the global setting leaves them alone. */
.w2rr-summary__criterion .w2rr-stars {
	font-size: 16px;
}

.w2rr-review__criteria .w2rr-stars {
	font-size: 12px;
}

.w2rr-review__criterion {
	display: flex;
	align-items: center;
	flex-wrap: wrap;
	gap: 2px 8px;
	margin: 2px 0;
}

.w2rr-review__criterion-label {
	flex: 0 0 11em;
	opacity: 0.85;
}

/* image slider - layout + item styling now come from the SHARED gallery
   (.sp-gallery--slider / .sp-gallery__item; the `sp-` prefix is codemod-neutral
   so w2rr's markup matches the codemodded core bundle). The review container
   just carries the vertical spacing. The old scoped 72px-thumb rules were
   removed so they can't out-specify the shared slider. */
/* Doubled class on purpose: this container is ALSO an `.sp-gallery`, and the
   shared gallery stylesheet zeroes that margin at the same weight while loading
   later - a tie the other file would win. */
.w2rr-review__images.w2rr-review__images {
	margin: 8px 0;
}

/* Review-card image collage. The container carries a --list / --grid2 / --grid3 /
   --grid4 modifier (the [webrr-reviews] view+columns; 'list' for the React block
   and single-review pages). EVERY image is emitted as an sp-gallery__item so the
   shared lightbox opens the full set - the layout SHOWS only the first few and
   hides the rest; the last visible one carries a "+N" overflow scrim. These rules
   scope to the modifier only, so the single-review [webrr-review-gallery]
   (.sp-gallery--grid, no modifier) keeps its own layout. */
:is( .w2rr-review__images--list, .w2rr-review__images--grid2, .w2rr-review__images--grid3, .w2rr-review__images--grid4 ) {
	display: grid;
	gap: 6px;
}
:is( .w2rr-review__images--list, .w2rr-review__images--grid2, .w2rr-review__images--grid3, .w2rr-review__images--grid4 ) .sp-gallery__item {
	position: relative;
	display: block;
	margin: 0;
	overflow: hidden;
	border-radius: 6px;
}
:is( .w2rr-review__images--list, .w2rr-review__images--grid2, .w2rr-review__images--grid3, .w2rr-review__images--grid4 ) .sp-gallery__item img {
	display: block;
	width: 100%;
	height: 100%;
	object-fit: cover;
}

/* list: one row of FIVE equal tracks, however many images the review has. The
   count used to drive the track count, which made a two-image review render two
   half-width thumbs; a fifth of the row is the cap, and a short row simply leaves
   the trailing tracks empty. */
.w2rr-review__images--list {
	grid-template-columns: repeat( 5, minmax( 0, 1fr ) );
}
.w2rr-review__images--list .sp-gallery__item {
	aspect-ratio: 1;
}
.w2rr-review__images--list .sp-gallery__item:nth-child( n + 6 ) {
	display: none;
}

/* grid 2-col cards: featured 50% (left) + 2 stacked thumbs in the other 50%. The
   two right thumbs set the row heights (their own aspect-ratio); the featured
   spans both rows and stretches to match, so the block is a clean rectangle
   instead of a short featured over empty space. */
.w2rr-review__images--grid2 {
	grid-template-columns: 1fr 1fr;
}
.w2rr-review__images--grid2 .sp-gallery__item:nth-child( 1 ) {
	grid-row: 1 / span 2;
	/* clear the shared gallery's base aspect-ratio (4/3) so the featured stretches
	   to the full 2-row height instead of sizing to its own image ratio */
	aspect-ratio: auto;
}
.w2rr-review__images--grid2 .sp-gallery__item:nth-child( 2 ),
.w2rr-review__images--grid2 .sp-gallery__item:nth-child( 3 ) {
	aspect-ratio: 3 / 2;
}
.w2rr-review__images--grid2 .sp-gallery__item:nth-child( n + 4 ) {
	display: none;
}
/* only one image: no right thumbs to size the rows, so let the featured fill the row */
.w2rr-review__images--grid2 .sp-gallery__item:only-child {
	grid-row: auto;
	grid-column: 1 / -1;
	aspect-ratio: 16 / 9;
}

/* grid 3-col cards: featured 100% + a row of up to 3 thumbs at 33% */
.w2rr-review__images--grid3 {
	grid-template-columns: repeat( 3, 1fr );
}
.w2rr-review__images--grid3 .sp-gallery__item:nth-child( 1 ) {
	grid-column: 1 / -1;
	aspect-ratio: 16 / 9;
}
.w2rr-review__images--grid3 .sp-gallery__item:nth-child( n + 2 ) {
	aspect-ratio: 1;
}
.w2rr-review__images--grid3 .sp-gallery__item:nth-child( n + 5 ) {
	display: none;
}

/* grid 4-col cards: featured 100% + a row of up to 2 thumbs at 50% */
.w2rr-review__images--grid4 {
	grid-template-columns: repeat( 2, 1fr );
}
.w2rr-review__images--grid4 .sp-gallery__item:nth-child( 1 ) {
	grid-column: 1 / -1;
	aspect-ratio: 16 / 9;
}
.w2rr-review__images--grid4 .sp-gallery__item:nth-child( n + 2 ) {
	aspect-ratio: 1;
}
.w2rr-review__images--grid4 .sp-gallery__item:nth-child( n + 4 ) {
	display: none;
}

/* "+N more" scrim over the last visible thumb (the hidden thumbs still open in the lightbox) */
.w2rr-review__images .sp-gallery__item.is-more .w2rr-review__images-more {
	position: absolute;
	inset: 0;
	display: flex;
	align-items: center;
	justify-content: center;
	background: rgba( 0, 0, 0, 0.55 );
	color: #fff;
	font-size: 1.25rem;
	font-weight: 600;
	pointer-events: none;
}

/* Narrow grid columns (3-4): push each criterion's stars flush right, drop the
   fixed-width label indent so nothing floats in from the left. */
:is( .w2rr-reviews-list--cols3, .w2rr-reviews-list--cols4 ) .w2rr-review__criterion {
	justify-content: space-between;
	flex-wrap: nowrap;
	gap: 8px;
}
:is( .w2rr-reviews-list--cols3, .w2rr-reviews-list--cols4 ) .w2rr-review__criterion-label {
	flex: 0 1 auto;
	min-width: 0;
}

/* votes */

.w2rr-review__votes {
	display: flex;
	align-items: center;
	flex-wrap: wrap;
	gap: 8px;
	margin-top: 20px;
}

.w2rr-review__vote {
	appearance: none;
	display: inline-flex;
	align-items: center;
	gap: 6px;
	padding: 4px 12px;
	border: 1px solid rgba( 0, 0, 0, 0.2 );
	border-radius: 999px;
	background: transparent;
	color: inherit;
	font: inherit;
	font-size: 0.9em;
	cursor: pointer;
}

.w2rr-review__vote.w2rr-review__vote:hover {
	border-color: rgba( 0, 0, 0, 0.45 );
}

.w2rr-review__vote.w2rr-review__vote:focus-visible {
	outline: 2px solid var( --w2rr-primary, var( --w2dc-primary, var( --rmaps-primary, #2271b1 ) ) );
	outline-offset: 1px;
}

.w2rr-review__vote[disabled] {
	opacity: 0.6;
	cursor: default;
}

/* the visitor's current vote */
.w2rr-review__vote.is-active {
	border-color: var( --w2rr-primary, var( --w2dc-primary, var( --rmaps-primary, #2271b1 ) ) );
	color: var( --w2rr-primary, var( --w2dc-primary, var( --rmaps-primary, #2271b1 ) ) );
	font-weight: 600;
}

.w2rr-review__vote-error {
	color: #b32d2e;
	font-size: 0.85em;
}

/* --- load more (React only) --------------------------------------------------- */

.w2rr-more {
	appearance: none;
	display: block;
	margin: 16px auto 0;
	padding: 8px 22px;
	border: 1px solid var( --w2rr-primary, var( --w2dc-primary, var( --rmaps-primary, #2271b1 ) ) );
	border-radius: 3px;
	background: transparent;
	color: inherit;
	font: inherit;
	font-weight: 600;
	cursor: pointer;
}

.w2rr-more.w2rr-more:hover {
	background: var( --w2rr-primary, var( --w2dc-primary, var( --rmaps-primary, #2271b1 ) ) );
	color: #fff;
}

.w2rr-more.w2rr-more:focus-visible {
	outline: 2px solid currentColor;
	outline-offset: 2px;
}

.w2rr-more[disabled] {
	opacity: 0.7;
	cursor: default;
}

.w2rr-list-error__retry:focus-visible {
	outline: 2px solid var( --w2rr-primary, var( --w2dc-primary, var( --rmaps-primary, #2271b1 ) ) );
	outline-offset: 1px;
}

/* --- responsive ---------------------------------------------------------------- */

@media ( max-width: 480px ) {
	:is( .w2rr-reviews-mount, .w2rr-summary-mount, .w2rr-single-review, .w2rr-review-el ) .w2rr-summary__criterion-label,
	:is( .w2rr-reviews-mount, .w2rr-summary-mount, .w2rr-single-review, .w2rr-review-el ) .w2rr-review__criterion-label {
		flex-basis: 100%;
	}

	/* The overall rating keeps its `margin-left: auto` here too - it is NOT given
	   a line of its own. Handing it `flex-basis: 100%` cost a whole row per card
	   (a header measured 131px against 105px) and left the icons hanging on the
	   left under the author, out of line with the criterion strips now flush
	   right below them. The header already wraps, so on a genuinely cramped card
	   the strip still drops to its own line - it is just no longer forced to. */

	/* ...but NOT the per-criterion rows. The `flex-basis: 100%` above hands the
	   label the whole line, so the icon strip wraps underneath it and stretches
	   the width of the card - which is what a phone showed in list view and in a
	   2-column grid. A 3- or 4-column grid escaped it only because its own rule
	   (see `--cols3, --cols4` above) also sets `flex-wrap: nowrap`, keeping the
	   pair on one line with the icons flush right. Every view is one column wide
	   at this width, so give them all that same treatment. Declared after the
	   rule it corrects, at equal weight, so it wins on order. */
	:is( .w2rr-reviews-mount, .w2rr-summary-mount, .w2rr-single-review, .w2rr-review-el ) .w2rr-review__criterion {
		justify-content: space-between;
		flex-wrap: nowrap;
		gap: 8px;
	}

	:is( .w2rr-reviews-mount, .w2rr-summary-mount, .w2rr-single-review, .w2rr-review-el ) .w2rr-review__criterion-label {
		flex: 0 1 auto;
		min-width: 0;
	}
}

/* --- review-card permalinks + single review page ------------------------- */

/* The list card links through to a review's own page (the date is always a
   permalink so rating-only cards are clickable; the title links when present).
   The DATE stays unobtrusive (inherit + hover underline); the TITLE link takes
   the Customization link palette (--w2rr-links / --w2rr-links-hover). */
.w2rr-review__permalink {
	color: inherit;
	text-decoration: none;
}
.w2rr-review__permalink.w2rr-review__permalink:hover {
	text-decoration: underline;
}
/* Doubled like its :hover twin below: a theme's own `.entry-content a` rule
   carries the same weight and loads later, so a tie hands the underline back. */
.w2rr-review__title.w2rr-review__title a {
	color: var( --w2rr-links, inherit );
	text-decoration: none;
}
.w2rr-review__title.w2rr-review__title a:hover {
	color: var( --w2rr-links-hover, var( --w2rr-links, inherit ) );
	text-decoration: underline;
}

/* The standalone single review page (render_single / [webrr-review-page]). The
   inner .w2rr-review__* parts are already styled by the scoped rules above; the
   page/template that hosts it owns the width (no max-width cap here - the
   theme's content column decides), these rules just space the parts. */
/* The single-review page is one plate, styled like a review card in a list: same
   white, same inset, same corner. No margin: a card's 50px separates it from the
   NEXT card, and there is no next one here - the space around this block belongs
   to the host template. */
.w2rr-single-review {
	background-color: #fff;
	padding: 15px;
	border-radius: 5px;
}

.w2rr-single-review .w2rr-review-el {
	margin: 0 0 18px;
}

/* Attribution line - WHAT this page reviews, linked back to the target in the
   Customization link palette. Prominent but subordinate to the review title. */
.w2rr-single-review__target {
	display: flex;
	align-items: center;
	gap: 10px;
	margin: 0 0 14px;
	font-size: 1.05em;
	font-weight: 600;
}

/* The same attribution inside a review CARD ([webrr-reviews], or [webrr] with
   target_link="1"): smaller and quieter than on the single-review page, where it
   is the page's subject line rather than a label on one card among many. */
.w2rr-review__target {
	margin: 0 0 10px;
	font-size: 0.95em;
	font-weight: 500;
}

/* Under the title the chip would otherwise double the line height of an
   otherwise one-line row; a slightly smaller square keeps the block compact
   without shrinking the same chip on the single-review page. */
.w2rr-review__target .w2rr-single-review__target-thumb {
	width: 32px;
	height: 32px;
	max-width: 32px;
}

/* The target's featured image as a fixed 40x40 chip. flex-shrink:0 keeps it
   square when the title wraps; the explicit width/height overrides a theme's
   fluid `img { width: 100% }`, which would otherwise blow it up to the column. */
.w2rr-single-review__target-thumb {
	flex: 0 0 auto;
	width: 40px;
	height: 40px;
	max-width: 40px;
	border-radius: 6px;
	object-fit: cover;
	display: block;
}
.w2rr-single-review__target a {
	color: var( --w2rr-links, inherit );
	text-decoration: none;
}
.w2rr-single-review__target a:hover {
	color: var( --w2rr-links-hover, var( --w2rr-links, inherit ) );
	text-decoration: underline;
}
.w2rr-single-review .w2rr-review-el:last-child {
	margin-bottom: 0;
}

/* Overall (header) rating icons read larger on the single-review page - 22px
   vs the list-card 16px. Scoped to the OVERALL strip; the per-criterion
   breakdown keeps its own fixed-advance sizing. Three classes beat the base
   `:is(...) .w2rr-stars` rule. */
.w2rr-single-review .w2rr-review__stars .w2rr-stars {
	font-size: var( --w2rr-icon-size, 16px );
}

/* --- review filters ([webrr] inline + standalone [webrr-filters]) ----------
 * Inputs/buttons mirror the maps search-form control box; every color comes
 * from the Customization panel (--w2rr-primary / --w2rr-links / --w2rr-button-*),
 * with sensible fallbacks. */

.w2rr-filters {
	/* The panel measures ITSELF, not the viewport: it can sit in a 900px content
	   column or a 240px sidebar on the same screen, and only its own width says
	   which layout is right. See the @container rule at the end of this section. */
	container-type: inline-size;
	container-name: w2rr-filters;
	display: flex;
	flex-wrap: wrap;
	align-items: flex-end;
	gap: 18px;
	margin: 0 0 20px;
	padding: 14px 16px;
	background: #f7f7f8;
	border: 1px solid #e5e7eb;
	border-radius: 10px;
}

.w2rr-filters__group {
	display: flex;
	flex-direction: column;
	gap: 6px;
	/* A flex item refuses to shrink below its content unless told otherwise, and
	   the content here is a control with a mind of its own: an <input> is about
	   twenty characters wide by default and a <select> is as wide as its longest
	   option. In a narrow column - a sidebar, a builder column - the group kept
	   that width and hung out over the panel's edge. */
	min-width: 0;
}

/* The keyword group is a <form>; kill the theme's form margin (e.g. Storefront's
   `form { margin-bottom: 1.618em }`). */
.w2rr-filters form.w2rr-filters__group,
.w2rr-filters__group--keyword {
	margin: 0;
}

.w2rr-filters__label {
	font-size: 11px;
	font-weight: 700;
	letter-spacing: 0.05em;
	text-transform: uppercase;
	color: #6b7280;
}

/* rating range checkboxes */
.w2rr-filters__ratings {
	display: flex;
	flex-wrap: wrap;
	gap: 8px;
}

.w2rr-filters__rating {
	display: inline-flex;
	align-items: center;
	gap: 6px;
	padding: 5px 9px;
	border: 1px solid #e5e7eb;
	border-radius: 8px;
	background: #fff;
	cursor: pointer;
	line-height: 1;
	box-sizing: border-box;
}

.w2rr-filters__rating:hover {
	border-color: #cbd5e1;
}

.w2rr-filters__rating.is-on {
	border-color: var(--w2rr-primary, #2271b1);
	box-shadow: inset 0 0 0 1px var(--w2rr-primary, #2271b1);
}

/* native checkboxes/radios follow the brand primary (maps form does the same) */
.w2rr-filters input[type='checkbox'],
.w2rr-filters input[type='radio'] {
	margin: 0;
	accent-color: var(--w2rr-primary, #2271b1);
}

.w2rr-filters__stars {
	display: inline-flex;
	gap: 1px;
	/* The buckets are rating icons like any other, so they take the shared size
	   (see the note at the top). 15px only as the fallback for markup that
	   carries no variable. */
	font-size: var( --w2rr-icon-size, 15px );
}

.w2rr-filters__stars .is-full {
	opacity: 1;
}

.w2rr-filters__stars .is-half {
	opacity: 0.4;
}

.w2rr-filters__stars .is-empty {
	opacity: 0.2;
}

/* inputs + select - the maps search-form control box. Container-prefixed (0,2,0)
   + appearance:none so a theme's `input[type=search] {…}` (0,1,1) can't repaint
   the background grey or re-add native search chrome. */
.w2rr-filters .w2rr-filters__select,
.w2rr-filters .w2rr-filters__search {
	box-sizing: border-box;
	/* Never wider than the column it sits in, whatever its content would like:
	   a <select> is as wide as its longest option, and one of ours reads
	   "Only reviews without photos". */
	max-width: 100%;
	min-width: 0;
	height: 38px;
	border: 1px solid #e5e7eb;
	background: #fff;
	border-radius: 8px;
	padding: 8px 14px;
	font-size: 13px;
	line-height: 1.2;
	color: #1f2937;
	outline: none;
	-webkit-appearance: none;
	appearance: none;
	transition: border-color 0.12s, box-shadow 0.12s;
}

/* appearance:none drops the select caret - redraw a slim arrow so it still reads
   as a dropdown. */
.w2rr-filters .w2rr-filters__select {
	background-image: url( "data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 width=%2710%27 height=%276%27%3E%3Cpath fill=%27%236b7280%27 d=%27M0 0l5 6 5-6z%27/%3E%3C/svg%3E" );
	background-repeat: no-repeat;
	background-position: right 12px center;
	padding-right: 30px;
}

.w2rr-filters__search::placeholder {
	color: #9ca3af;
}

.w2rr-filters .w2rr-filters__select:focus,
.w2rr-filters .w2rr-filters__search:focus {
	border-color: var(--w2rr-primary, #2271b1);
	box-shadow: 0 0 0 3px color-mix(in srgb, var(--w2rr-primary, #2271b1) 18%, transparent);
}

/* --- the host theme's focus ring, once, for everything in here -------------
   Storefront and themes like it paint
     a:focus, input:focus, textarea:focus, button:focus { outline: 2px solid <accent> }
   and it fires on a plain MOUSE CLICK, so a review title, the pager button, a
   vote, the sort dropdown and a slider arrow each kept a hard rectangle long
   after the click that caused it. Silencing that control by control meant a new
   rule for every control ever added, and one was always missed.

   `:focus:not( :focus-visible )` is the whole trick: it matches exactly when the
   browser would NOT have drawn a ring of its own - a click, never a Tab - so
   keyboard focus still reaches every :focus-visible ring below and nothing has
   to be reinstated per element.

   Scoped, unlike the rest of this file: `a:focus` and `button:focus` are not
   ours to silence anywhere else on the page. The list covers the React mounts,
   the static list, the single-review page and a bare element shortcode dropped
   on a builder page. (0,3,1) outranks the theme's (0,1,1).

   Outline only. A text field's own focus ring is a border plus a shadow, and it
   has to survive a mouse click - you must be able to see which field you are
   typing in. */
:is(
	.w2rr-reviews-mount,
	.w2rr-reviews-wrap,
	.w2rr-summary-mount,
	.w2rr-single-review,
	.w2rr-review-el,
	.w2rr-filters-mount,
	.w2rr-filters,
	.w2rr-post-rating,
	.w2rr-add-review-button
) :is( a, button, input, select, textarea, summary ):focus:not( :focus-visible ) {
	outline: none;
}

/* Links get their own ring: a link has no border to tint, so the outline is all
   there is to see when tabbing through a review. */
:is(
	.w2rr-reviews-mount,
	.w2rr-reviews-wrap,
	.w2rr-summary-mount,
	.w2rr-single-review,
	.w2rr-review-el,
	.w2rr-filters-mount,
	.w2rr-filters,
	.w2rr-post-rating,
	.w2rr-add-review-button
) a:focus-visible {
	outline: 2px solid var(--w2rr-primary, #2271b1);
	outline-offset: 2px;
	border-radius: 3px;
}

/* --- focus: replace the host theme's ring, never remove it ----------------
   Storefront (and themes like it) paint `a:focus, input:focus, textarea:focus,
   button:focus { outline: 2px solid <accent> }` and repaint
   `input[type=text]:focus` grey - on controls this compact the ring reads as an
   error state and the grey fill looks disabled. So the panel suppresses those
   and draws its own: the control's border turns primary with a soft ring, which
   is the maps search-form treatment. Buttons and checkboxes keep a
   :focus-visible ring, so tabbing stays perfectly legible while a mouse click
   leaves nothing behind. Selectors carry the container AND the element type to
   outrank the theme's (0,2,1) rules whichever stylesheet loads last. */
/* Idle: drop the theme's inset shadow so the control box stays flat. */
.w2rr-filters input.w2rr-filters__search,
.w2rr-filters select.w2rr-filters__select {
	box-shadow: none;
}

.w2rr-filters input.w2rr-filters__search:focus,
.w2rr-filters select.w2rr-filters__select:focus {
	background-color: #fff;
	border-color: var(--w2rr-primary, #2271b1);
	box-shadow: 0 0 0 3px color-mix(in srgb, var(--w2rr-primary, #2271b1) 18%, transparent);
}

/* Keyboard-only ring for the things that have no border of their own to tint. */
.w2rr-filters button:focus-visible {
	/* This ring is a shadow, so it does not replace the theme outline on its own. */
	outline: none;
	box-shadow: 0 0 0 3px color-mix(in srgb, var(--w2rr-primary, #2271b1) 35%, transparent);
}

/* The rating pills hide their checkbox behind a label, so the pill itself shows
   the ring when the checkbox inside it takes focus. */
.w2rr-filters input[type='checkbox']:focus-visible {
	outline: 2px solid var(--w2rr-primary, #2271b1);
	outline-offset: 1px;
}

.w2rr-filters__rating:focus-within {
	border-color: var(--w2rr-primary, #2271b1);
	box-shadow: 0 0 0 3px color-mix(in srgb, var(--w2rr-primary, #2271b1) 25%, transparent);
}

.w2rr-filters__group--keyword {
	flex-direction: row;
	align-items: flex-end;
	gap: 6px;
	flex-wrap: wrap;
}

.w2rr-filters__group--keyword .w2rr-filters__label {
	flex-basis: 100%;
}

.w2rr-filters__search {
	/* Room for a query when there is room to give, but a floor it can drop
	   through: as a flex-basis with shrink allowed this is a preference, where
	   the old `min-width: 180px` was a hard minimum that pushed the field out
	   past the panel's edge in any column narrower than it. */
	flex: 1 1 180px;
	min-width: 0;
}

/* --- narrow panel: one control per row ------------------------------------
   All three groups side by side need roughly 520px (rating pills ~200, the
   photos select ~130, the keyword field 180, plus two 18px gaps). Below that
   they stop competing for a line: every group takes the full width and every
   control fills its group, which is the layout a sidebar or a builder column
   actually wants. A browser without container queries still never overflows -
   the group can shrink and the controls cap at 100% - it just keeps the
   controls at their natural widths. */
@container w2rr-filters ( max-width: 520px ) {
	.w2rr-filters__group {
		flex-basis: 100%;
	}

	.w2rr-filters__select,
	.w2rr-filters__search {
		width: 100%;
	}

	/* The field owns its row; the button wraps under it at its own size. */
	.w2rr-filters__search {
		flex-basis: 100%;
	}
}

/* primary button - maps search-form __btn--primary, tinted by Customization.
   !important guards the palette against a host theme's bare-button :hover. */
.w2rr-filters__go {
	box-sizing: border-box;
	height: 38px;
	padding: 7px 16px;
	border: 1px solid var(--w2rr-button-primary, var(--w2rr-primary, #2271b1)) !important;
	background-color: var(--w2rr-button-primary, var(--w2rr-primary, #2271b1)) !important;
	color: var(--w2rr-button-text, #fff) !important;
	font-size: 13px;
	font-weight: 500;
	border-radius: 8px;
	cursor: pointer;
	transition: box-shadow 0.12s, border-color 0.12s;
}

.w2rr-filters__go:hover {
	box-shadow: 0 2px 6px rgba(0, 0, 0, 0.12);
}

/* clear - a plain link in the Customization link color */
.w2rr-filters__clear {
	align-self: flex-end;
	margin-left: auto;
	border: 0;
	background: none;
	color: var(--w2rr-links, var(--w2rr-primary, #2271b1));
	font-size: 13px;
	text-decoration: underline;
	cursor: pointer;
	padding: 6px 0;
}

.w2rr-filters__clear:hover {
	color: var(--w2rr-links-hover, var(--w2rr-links, #b32d2e));
}

/* =============================================================================
 * Shortcode blocks: the cross-target review list, its toolbar and pager, the
 * photo slider, and the two compact target widgets.
 *
 * These lived in a separate legacy.css for historical reasons - the file was
 * named after the ONE thing in it that is actually legacy (the two post-* badge
 * widgets), while the list, slider, toolbar and pager it also held are ordinary
 * shortcodes. Since every page rendering them already loads this stylesheet,
 * a second file bought nothing but a second request and a misleading name.
 *
 * Unscoped by design, unlike the rules above: the list wrapper, toolbar and
 * pager sit OUTSIDE .w2rr-reviews-mount, so the :is() scope those rules share
 * cannot reach them. The class names carry the namespace instead.
 * ============================================================================= */

.w2rr-post-rating { display: inline-flex; align-items: center; gap: 6px; line-height: 1; }
.w2rr-post-reviews-counter { font-weight: 600; }

.w2rr-add-review-button {
	display: inline-block;
	padding: 8px 16px;
	border-radius: 6px;
	background: var(--w2rr-accent, #2271b1);
	color: #fff;
	text-decoration: none;
	font-weight: 600;
	line-height: 1.2;
	cursor: pointer;
}
.w2rr-add-review-button:hover { opacity: .9; color: #fff; }

.w2rr-reviews-list--grid { display: grid; gap: 16px; }
.w2rr-reviews-list--cols2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.w2rr-reviews-list--cols3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.w2rr-reviews-list--cols4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }
/* In a grid or a masonry column the plate is the CARD, so the base rule's 50px
   vertical margin would push every card away from its neighbours; the gap
   between columns already spaces them. */
.w2rr-reviews-list--grid .w2rr-review,
.w2rr-reviews-list--masonry .w2rr-review {
	margin: 0;
	border: 1px solid #e5e7eb;
	border-radius: 8px;
	padding: 14px;
}

/* --- masonry ---------------------------------------------------------------
 * The same columns as the grid, but each card keeps its own height instead of
 * stretching to the tallest in its row - a one-line review no longer leaves a
 * hole under it. CSS columns, not a layout script: nothing to measure, nothing
 * to re-run on image load, and it degrades to a single column on its own.
 *
 * Reading order runs DOWN each column rather than across, which is what a wall
 * of reviews wants: each column is its own strip to read. */
.w2rr-reviews-list--masonry {
	display: block;
	column-gap: 16px;
}

.w2rr-reviews-list--masonry.w2rr-reviews-list--cols2 { column-count: 2; }
.w2rr-reviews-list--masonry.w2rr-reviews-list--cols3 { column-count: 3; }
.w2rr-reviews-list--masonry.w2rr-reviews-list--cols4 { column-count: 4; }

/* inline-block + break-inside: Chrome and Safari still split a card across a
   column boundary without both. The bottom margin is the vertical gap:
   column-gap only spaces the columns themselves. */
.w2rr-reviews-list--masonry .w2rr-review {
	break-inside: avoid;
	-webkit-column-break-inside: avoid;
	display: inline-block;
	width: 100%;
	margin: 0 0 16px;
}

@media (max-width: 782px) {
	.w2rr-reviews-list--grid { grid-template-columns: 1fr; }
	.w2rr-reviews-list--masonry { column-count: 1 !important; }
}

.w2rr-reviews-pager { display: flex; gap: 6px; flex-wrap: wrap; justify-content: center; margin: 16px 0; }
.w2rr-reviews-pager .page-numbers {
	background-color: #fff;
	padding: 4px 10px;
	border: 1px solid #d1d5db;
	border-radius: 4px;
	text-decoration: none;
	color: inherit;
}
.w2rr-reviews-pager .current { background: var(--w2rr-accent, #2271b1); color: #fff; border-color: transparent; }

.w2rr-reviews-wrap.is-loading { opacity: .55; pointer-events: none; transition: opacity .15s; }

/* --- [webrr-slider] -------------------------------------------------------
   A scroll-snap strip of review photos, mirroring the directory slider so both
   products' strips behave identically. No slider library: the track does the
   sliding in CSS and stays usable with JS off; arrows, dots, autoplay and
   drag-to-scroll (slider.js) are enhancement on top. Size rides the inline vars
   the shortcode sets: --w2rr-slider-h / -ratio / -fit. */
.w2rr-slider__viewport {
	/* The arrows position against this, and its height is the track's (one
	   slide), so top:50% is the slide's true middle whatever the height. */
	position: relative;
}
.w2rr-slider__track {
	display: flex;
	/* A variable, because the per-view width calc has to subtract exactly this
	   gap - hardcoding it in two places is how the last slide ends up clipped. */
	gap: var(--w2rr-slider-gap, 12px);
	overflow-x: auto;
	scroll-snap-type: x mandatory;
	scroll-behavior: smooth;
	-webkit-overflow-scrolling: touch;
	scrollbar-width: none;          /* it navigates by arrows/dots/swipe */
	-ms-overflow-style: none;
	cursor: grab;
	padding-bottom: 0;
}
.w2rr-slider__track::-webkit-scrollbar { display: none; }

/* While dragging: no snapping, no smoothing, no text selection - the strip
   tracks the cursor 1:1. All three come back on release. */
.w2rr-slider__track.is-dragging {
	cursor: grabbing;
	scroll-snap-type: none;
	scroll-behavior: auto;
	user-select: none;
}

.w2rr-slide {
	position: relative;
	flex: 0 0 auto;
	height: var(--w2rr-slider-h, 400px);
	/* Width derives from height x ratio: banner-wide at 16/9, square at 1/1. */
	aspect-ratio: var(--w2rr-slider-ratio, 16 / 9);
	scroll-snap-align: start;
	border-radius: 8px;
	overflow: hidden;
	background: #f9fafb;
	line-height: 0;
	text-decoration: none;
	/* Images and links are natively draggable, and that ghost-drag eats the
	   pointer and kills drag-to-scroll. */
	-webkit-user-drag: none;
	user-select: none;
}
.w2rr-slide img,
.w2rr-slide__img {
	display: block;
	width: 100%;
	height: 100%;
	object-fit: var(--w2rr-slider-fit, cover);
	transition: opacity .15s ease;
	-webkit-user-drag: none;
	pointer-events: none;           /* clicks land on the slide, not the image */
}
.w2rr-slide:hover img { opacity: .88; }

/* Bottom overlay: a gradient keeps the title and stars readable on any photo. */
.w2rr-slide__meta {
	position: absolute;
	left: 0;
	right: 0;
	bottom: 0;
	padding: 34px 12px 10px;
	/* Three stops rather than two: a straight transparent-to-dark ramp is at half
	   strength exactly where the text sits, so a pale photo washes out an 18px
	   bold title and the star glyphs alike. The middle stop gets the ramp dark
	   early and the bottom lands nearly opaque, while the top stays clear so the
	   photo is not visibly boxed off. */
	background: linear-gradient(
		to top,
		rgba(17, 24, 39, .92) 0%,
		rgba(17, 24, 39, .78) 38%,
		rgba(17, 24, 39, .35) 72%,
		transparent 100%
	);
	color: #fff;
	display: flex;
	flex-direction: column;
	gap: 3px;
	line-height: 1.35;
}
.w2rr-slide__title {
	font-size: 18px;
	font-weight: bold;
	white-space: nowrap;
	overflow: hidden;
	text-overflow: ellipsis;
}
.w2rr-slide__rating {
	display: inline-flex;
	align-items: center;
	line-height: 1;
	pointer-events: none;           /* display only - never intercept the click */
}
/* The star glyphs size themselves from the admin's "Rating size" setting, which
   the shortcode puts on the wrapper as an inline font-size. Three classes so this
   beats the display stylesheet's fixed 16px .w2rr-stars rule outright, rather than
   tying with it and depending on which sheet the page loads last. */
.w2rr-slider .w2rr-slide__rating .w2rr-stars {
	font-size: inherit;
}

/* On a slide the wrapper carries an inline font-size (the strip's own icon
   size), so the shared .w2rr-rating__value rule - which sizes off
   --w2rr-icon-size - is pinned back to the glyphs beside it. */
.w2rr-slider .w2rr-slide__rating .w2rr-rating__value {
	font-size: 0.82em;
}

/* Arrows, centred on the slide. slider.js toggles [hidden] by overflow. */
.w2rr-slider__nav {
	position: absolute;
	top: 50%;
	margin-top: -20px;              /* half the button - no transform, which a
	                                   theme's button{transform} would wipe */
	z-index: 2;
	display: flex;
	align-items: center;
	justify-content: center;
	width: 40px;
	height: 40px;
	padding: 0;
	border: 0;
	border-radius: 50%;
	background: rgba(17, 24, 39, .55);
	color: #fff;
	font-size: 22px;
	line-height: 1;
	cursor: pointer;
	transition: background .15s ease;
}
.w2rr-slider__nav:hover { background: rgba(17, 24, 39, .82); }
.w2rr-slider__nav[hidden] { display: none; }
.w2rr-slider__nav--prev { left: 8px; }
.w2rr-slider__nav--next { right: 8px; }

/* Dots (opt-in) - built by slider.js from the current slide count. */
.w2rr-slider__dots {
	display: flex;
	justify-content: center;
	flex-wrap: wrap;
	gap: 7px;
	margin-top: 10px;
}
.w2rr-slider__dot {
	width: 8px;
	height: 8px;
	padding: 0;
	border: 0;
	border-radius: 50%;
	background: rgba(17, 24, 39, .25);
	cursor: pointer;
	transition: background .15s ease, transform .15s ease;
}
.w2rr-slider__dot:hover { background: rgba(17, 24, 39, .5); }
.w2rr-slider__dot.is-active {
	background: rgba(17, 24, 39, .8);
	transform: scale(1.25);
}

/* --- per_view: N slides fill the strip ------------------------------------
   Default sizing runs height -> width (the slide is as wide as height x ratio),
   which means "show exactly three" is a sum the author has to do by hand against
   the theme's column width, and it breaks the moment that width changes. With
   per_view the direction flips: the slide takes a SHARE of the strip and the
   ratio derives the height, so N slides fit at any width. */
.w2rr-slider--pv .w2rr-slide {
	width: calc(
		(100% - (var(--w2rr-slider-gap, 12px) * (var(--w2rr-slider-pv, 3) - 1)))
		/ var(--w2rr-slider-pv, 3)
	);
	min-width: 0;
	height: auto;                    /* the ratio owns the height now */
	aspect-ratio: var(--w2rr-slider-ratio, 16 / 9);
}

/* --- keyboard rings for the slider controls -------------------------------
   The theme's mouse-click ring is already gone (see the blanket rule above);
   these are the rings a Tab should leave, and on a dark photo overlay the
   theme's accent would read as damage anyway. */

/* On the arrows a white ring reads against both the dark button and any photo
   behind it; the brand color would vanish on a dark image. */
.w2rr-slider__nav:focus-visible {
	/* Shadow ring: clear the theme outline it would otherwise sit inside. */
	outline: none;
	box-shadow: 0 0 0 2px rgba(255, 255, 255, .9), 0 0 0 4px rgba(17, 24, 39, .55);
}

.w2rr-slider__dot:focus-visible {
	/* Shadow ring: clear the theme outline it would otherwise sit inside. */
	outline: none;
	box-shadow: 0 0 0 3px color-mix(in srgb, var(--w2rr-primary, #2271b1) 35%, transparent);
}

/* The slide is the photo itself - an offset outline sits clear of the image
   instead of over it. */
.w2rr-slide:focus-visible {
	outline: 2px solid var(--w2rr-primary, #2271b1);
	outline-offset: 2px;
}

@media (max-width: 600px) {
	/* Phones: drive from WIDTH instead - a definite width lets the ratio derive
	   the height reliably, and one slide plus a peek of the next fits anything.
	   Swipe scrolls natively, so the arrows go away. */
	.w2rr-slide {
		width: min(88vw, 460px);
		height: auto;
		aspect-ratio: var(--w2rr-slider-ratio, 16 / 9);
	}
	/* Two classes, so a per_view strip keeps its own count here instead of being
	   overwritten by the generic phone rule above. */
	.w2rr-slider--pv .w2rr-slide {
		width: calc(
			(100% - (var(--w2rr-slider-gap, 12px) * (var(--w2rr-slider-pv-m, 1) - 1)))
			/ var(--w2rr-slider-pv-m, 1)
		);
	}
	.w2rr-slider__nav { display: none; }
}

/* [webrr-reviews] toolbar: found-count + sort dropdown (inside .w2rr-reviews-wrap
   so it refreshes on a filter/sort AJAX swap). */
.w2rr-reviews-toolbar {
	display: flex;
	align-items: center;
	justify-content: space-between;
	flex-wrap: wrap;
	gap: 8px 16px;
	margin: 0 0 14px;
	padding-bottom: 8px;
	border-bottom: 1px solid rgba(0, 0, 0, 0.1);
}
.w2rr-reviews-toolbar__count { font-weight: 600; }
.w2rr-reviews-toolbar__sort {
	display: inline-flex;
	align-items: center;
	gap: 6px;
	font-size: 0.9em;
}
.w2rr-reviews-toolbar__sort select {
	font: inherit;
	font-size: 0.95em;
	color: inherit;
	background: #fff;
	border: 1px solid rgba(0, 0, 0, 0.25);
	border-radius: 6px;
	padding: 5px 10px;
}

/* The Sort dropdown takes the same theme focus outline the filter panel does
   (Storefront: `input:focus, button:focus { outline: 2px solid <accent> }`), which
   is loud on a control this small. Same replacement as the filters: suppress it and
   tint the control's own border instead. */
.w2rr-reviews-toolbar__sort select:focus {
	outline: none;
	border-color: var(--w2rr-primary, #2271b1);
	box-shadow: 0 0 0 3px color-mix(in srgb, var(--w2rr-primary, #2271b1) 18%, transparent);
}

/* Pager links live in the wrap, outside any card: the blanket rule above has
   already dropped the theme's click rectangle, this is the ring a Tab leaves. */
.w2rr-reviews-wrap a:focus-visible {
	outline: 2px solid var(--w2rr-primary, #2271b1);
	outline-offset: 2px;
	border-radius: 3px;
}


