/**
 * Smart Reviews & FAQs — frontend styles.
 *
 * Design system: every color, size, radius and spacing value is driven from CSS
 * custom properties ("tokens") defined once on the app container below. No rule
 * in this stylesheet uses a hardcoded color/length — change the look by editing
 * the token block (Phase 3.8 exposes these as settings). A test asserts that no
 * hex value appears outside the token definitions.
 *
 * Cascade order (see CLAUDE.md):
 *   1. Divi/theme globals (lowest — element/body selectors)
 *   2. This stylesheet: neutralization layer (.srf-reviews.srf-reviews …) +
 *      component rules (.srf-reviews …). Scoped so Divi cannot leak in, and
 *      raised just enough that Divi's globals cannot win.
 *   3. User custom CSS (equal-or-higher specificity, or !important) — always wins.
 */

/* -------------------------------------------------------------------------- */
/* Token layer — the ONLY place hex/length literals live.                     */
/* -------------------------------------------------------------------------- */

.srf-reviews,
.srf-faqs {
	/* Palette (from the approved mockup: soft peach page, deeper peach cards,
	   near-black pills/tags, muted-gold source + READ). */
	--srf-color-bg: #f2e8de;
	--srf-color-surface: #ece0d1;
	--srf-color-surface-2: #faf6f0;
	--srf-color-ink: #17130f;
	--srf-color-ink-2: #4a423b;
	--srf-color-on-ink: #f6efe6;
	/* The client-approved gold. DECORATIVE USE ONLY — it measures 2.55:1 on the
	   card surface, so it must never be used for small text. Keep it for
	   non-text ornament, text that meets the large-text threshold, or text on a
	   dark background. */
	--srf-color-accent: #b1854a;
	/* Hover fill for solid dark buttons. Light text sits on it, so it must clear
	   AA as a background: --srf-color-on-ink on this measures 4.79:1. */
	--srf-color-accent-2: #866330;
	/* Darkened gold for SMALL GOLD TEXT on the page/card surfaces.
	   Measured: 4.85:1 on --srf-color-surface (#ece0d1),
	             5.22:1 on --srf-color-bg (#f2e8de),
	             5.86:1 on --srf-color-surface-2 (#faf6f0).  WCAG AA needs 4.5:1. */
	--srf-color-accent-text: #7a5a2e;
	/* Hover partner for accent-text. Measured 5.54:1 on --srf-color-surface. */
	--srf-color-accent-text-strong: #6f5228;
	--srf-color-border: #dcccb6;
	/* Pill outline. It is the sole visual boundary of an unselected pill (its
	   fill matches the page), so WCAG 1.4.11 wants 3:1. Measured 3.12:1 on
	   --srf-color-bg. */
	--srf-color-border-2: #9c7f50;
	/* Secondary text (placeholder, empty state, ellipsis). Measured 4.95:1 on
	   --srf-color-bg, 5.56:1 on --srf-color-surface-2, 4.60:1 on surface. */
	--srf-color-muted: #6b6257;
	--srf-color-focus: #916b39;
	/* Stars are decorative (aria-hidden) with a real text alternative, but they
	   still convey the rating visually — treated as a graphic needing 3:1.
	   Measured 3.80:1 on --srf-color-surface. */
	--srf-color-star: #8f6a22;
	--srf-color-mark-bg: #f5e2b8;
	--srf-color-verified-bg: #e4ede0;
	--srf-color-verified-ink: #3f5b3a;
	--srf-color-error-bg: #f7e4e2;
	--srf-color-error-border: #e3b8b4;
	--srf-color-error-ink: #8a2c25;
	--srf-color-track: #e0d2c0;

	/* Radii. */
	--srf-radius-card: 6px;
	--srf-radius-input: 12px;
	--srf-radius-pill: 999px;

	/* Spacing scale. */
	--srf-space-1: 0.35rem;
	--srf-space-2: 0.6rem;
	--srf-space-3: 0.9rem;
	--srf-space-4: 1.25rem;
	--srf-space-5: 1.75rem;
	--srf-gap: 1.5rem;

	/* Typography (family inherits from the theme). */
	--srf-heading-size: clamp( 1.4rem, 2.4vw, 1.9rem );
	--srf-heading-weight: 800;
	--srf-heading-spacing: 0.02em;
	--srf-body-size: 0.98rem;
	--srf-body-line: 1.55;
	--srf-label-size: 0.72rem;
	--srf-pill-size: 0.74rem;
	--srf-tag-size: 0.68rem;
	--srf-meta-size: 0.78rem;

	/* Grid columns (overridden by .srf-cols-N and the responsive layer). */
	--srf-cols: 3;

	/* Effects. */
	--srf-focus-width: 2px;
	--srf-border-width: 1px;
	--srf-transition: 0.15s ease;

	/* Breakpoint. Mobile is "this width and below" — where the filter controls
	   collapse behind a disclosure.

	   A media query CANNOT read a custom property (there is no var() in @media,
	   and @custom-media is an unimplemented draft), so the same number also
	   appears as a literal in the @media rules at the end of this file and as
	   Settings::MOBILE_BREAKPOINT in PHP. This token is the documented source of
	   truth and tests/standalone/css-tokens.php asserts all three agree, so they
	   cannot drift apart. Change the value here and the test will tell you every
	   other place that must follow. */
	--srf-breakpoint-mobile: 600px;

	box-sizing: border-box;
	color: var( --srf-color-ink );
	background: var( --srf-color-bg );
	padding: var( --srf-space-5 );
	border-radius: var( --srf-radius-card );
}

/* -------------------------------------------------------------------------- */
/* Divi/theme neutralization (scoped; specificity raised via doubled class).  */
/* -------------------------------------------------------------------------- */

.srf-reviews.srf-reviews,
.srf-faqs.srf-faqs {
	max-width: 100%;
}

.srf-reviews.srf-reviews *,
.srf-faqs.srf-faqs * {
	box-sizing: border-box;
}

/* IMPORTANT: this layer must never set a property that a component owns
   (color / background / border). It sits at higher specificity than the
   component rules, so doing so silently overrides them — that is what made the
   selected pill's label invisible and stripped the Apply button in 1.0.3.
   Components declare their own color/background/border explicitly, which is
   what beats Divi. Here we only undo decoration/appearance/spacing. */
.srf-reviews.srf-reviews a,
.srf-faqs.srf-faqs a {
	text-decoration: none;
	box-shadow: none;
}

.srf-reviews.srf-reviews button,
.srf-faqs.srf-faqs button {
	margin: 0;
	font: inherit;
	text-transform: none;
	letter-spacing: normal;
	cursor: pointer;
	box-shadow: none;
	-webkit-appearance: none;
	appearance: none;
}

/* Links inside rendered content carry no component class, so give them an
   explicit color rather than inheriting the theme's link blue. */
.srf-reviews.srf-reviews .srf-card-body a,
.srf-reviews.srf-reviews .srf-card-full a,
.srf-faqs.srf-faqs .srf-faq-answer a {
	color: var( --srf-color-accent-text );
	text-decoration: underline;
}

.srf-reviews.srf-reviews input,
.srf-reviews.srf-reviews select,
.srf-faqs.srf-faqs input,
.srf-faqs.srf-faqs select {
	font: inherit;
	color: var( --srf-color-ink );
	line-height: normal;
	-webkit-appearance: none;
	appearance: none;
}

.srf-reviews.srf-reviews ul,
.srf-reviews.srf-reviews ol,
.srf-reviews.srf-reviews li,
.srf-faqs.srf-faqs ul,
.srf-faqs.srf-faqs ol,
.srf-faqs.srf-faqs li {
	list-style: none;
	margin: 0;
	padding: 0;
	background: none;
}

/* -------------------------------------------------------------------------- */
/* Utilities                                                                  */
/* -------------------------------------------------------------------------- */

/* Visually hidden but exposed to assistive tech. PLUGIN-OWNED: do not use the
   theme's `screen-reader-text` in front-end output — that class is defined by
   themes, not by WordPress core CSS on the front end, so if the active theme
   omits it every "hidden" string renders visible. This class keeps the node in
   the accessibility tree (unlike display:none), so live regions still announce.
   The 1px/clip values are technique constants, not design tokens. */
.srf-reviews .srf-sr-only,
.srf-faqs .srf-sr-only {
	position: absolute;
	width: 1px;
	height: 1px;
	margin: -1px;
	padding: 0;
	overflow: hidden;
	clip: rect( 0, 0, 0, 0 );
	clip-path: inset( 50% );
	white-space: nowrap;
	border: 0;
}

/* -------------------------------------------------------------------------- */
/* Header (heading + "Showing X–Y of TOTAL")                                  */
/* -------------------------------------------------------------------------- */

.srf-header {
	display: flex;
	flex-wrap: wrap;
	align-items: baseline;
	justify-content: space-between;
	gap: var( --srf-space-2 );
	margin-bottom: var( --srf-space-4 );
}

.srf-heading {
	margin: 0;
	font-size: var( --srf-heading-size );
	font-weight: var( --srf-heading-weight );
	letter-spacing: var( --srf-heading-spacing );
	text-transform: uppercase;
	color: var( --srf-color-ink );
	line-height: 1.1;
}

.srf-showing {
	margin: 0;
	color: var( --srf-color-ink-2 );
	font-size: var( --srf-meta-size );
	white-space: nowrap;
}

/* -------------------------------------------------------------------------- */
/* Controls (search, pills, selects)                                          */
/* -------------------------------------------------------------------------- */

.srf-controls {
	display: flex;
	flex-wrap: wrap;
	gap: var( --srf-space-3 );
	align-items: flex-end;
	margin-bottom: var( --srf-space-5 );
}

.srf-control {
	display: flex;
	flex-direction: column;
	gap: var( --srf-space-1 );
	min-width: 0;
	flex: 1 1 180px;
}

.srf-control-search,
.srf-control-pills {
	flex: 1 1 100%;
}

.srf-control-actions {
	flex: 0 0 auto;
	flex-direction: row;
	align-items: center;
	gap: var( --srf-space-2 );
}

.srf-control-label {
	font-size: var( --srf-label-size );
	font-weight: 700;
	text-transform: uppercase;
	letter-spacing: 0.04em;
	color: var( --srf-color-ink-2 );
}

/* -------------------------------------------------------------------------- */
/* Mobile filter disclosure (native <details>/<summary>).                     */
/* -------------------------------------------------------------------------- */

/*
 * Base = the WIDE-SCREEN treatment, i.e. no disclosure at all: the panel simply
 * lays its controls out and the summary is hidden. Mobile is the override in
 * the responsive layer at the end of this file.
 *
 * Desktop-as-default is deliberate on two counts:
 *
 *  1. If a media query never matches, the fallback is the fully expanded,
 *     everything-visible layout — degrading to the known-good pre-1.0.9 state
 *     rather than to a collapsed panel.
 *  2. It keeps the wide-screen rules OUT of a specificity fight. The mobile
 *     rules need `[open]` to key off the disclosure state, which makes them
 *     (0,3,0); a wide-screen rule on `.srf-filters-panel` alone is (0,1,0), and
 *     a media query adds NO specificity. Written the other way round the mobile
 *     rule silently wins at every width — which is exactly the bug that shipped
 *     the Rating/Verified/Sort selects onto three separate desktop rows.
 *
 * The panel mirrors `.srf-controls`' own flex settings, so the controls inside
 * it wrap into shared rows exactly as they did before the wrapper existed. No
 * `display: contents` and no overriding of user-agent <details> rendering is
 * involved in the open case — just ordinary flexbox.
 *
 * Nothing here sets a colour or size that is not a token, and the summary's
 * ink-on-surface-2 pairing is the same one already audited for the search field
 * and selects (see Contrast::pairs()).
 */

.srf-filters-disclosure {
	flex: 1 1 100%;
	min-width: 0;
}

.srf-filters-panel {
	display: flex;
	flex-wrap: wrap;
	gap: var( --srf-space-3 );
	align-items: flex-end;
	width: 100%;
}

/* The native marker is kept — it is the familiar disclosure affordance and
   needs no extra markup or ARIA to convey open/closed state. */

.srf-filters-summary:focus-visible {
	outline: var( --srf-focus-width ) solid var( --srf-color-focus );
	outline-offset: var( --srf-focus-width );
}

/*
 * The active-filter count is REAL TEXT inside the summary, so it forms part of
 * the summary's accessible name ("Filters (2)") and is announced while
 * collapsed. It is deliberately not a decorative pseudo-element or a badge with
 * an aria-label, and it is not faded with opacity (which would lower contrast).
 */
.srf-filters-count {
	font-weight: 700;
	color: var( --srf-color-ink );
}

.srf-search-input,
.srf-select {
	width: 100%;
	max-width: 100%;
	min-height: 44px;
	padding: var( --srf-space-3 ) var( --srf-space-4 );
	border: var( --srf-border-width ) solid var( --srf-color-border );
	border-radius: var( --srf-radius-input );
	background: var( --srf-color-surface-2 );
	color: var( --srf-color-ink );
	font: inherit;
}

.srf-search-input {
	font-size: 1.02rem;
}

.srf-search-input::placeholder {
	color: var( --srf-color-muted );
}

.srf-select {
	min-height: 40px;
	padding: var( --srf-space-2 ) var( --srf-space-3 );
	border-radius: var( --srf-radius-pill );
}

/* Focus states (visible, token-driven). */
.srf-search-input:focus-visible,
.srf-select:focus-visible,
.srf-submit:focus-visible,
.srf-clear-filters:focus-visible,
.srf-loadmore:focus-visible,
.srf-page-link:focus-visible,
.srf-retry:focus-visible,
.srf-pill:focus-visible,
.srf-card-read:focus-visible {
	outline: var( --srf-focus-width ) solid var( --srf-color-focus );
	outline-offset: 2px;
}

/* Pills */
.srf-pill-row {
	display: flex;
	flex-wrap: wrap;
	gap: var( --srf-space-2 );
}

.srf-pill {
	display: inline-flex;
	align-items: center;
	min-height: 40px;
	padding: var( --srf-space-2 ) var( --srf-space-4 );
	border: var( --srf-border-width ) solid var( --srf-color-border-2 );
	border-radius: var( --srf-radius-pill );
	background: var( --srf-color-bg );
	color: var( --srf-color-ink );
	font-size: var( --srf-pill-size );
	font-weight: 700;
	letter-spacing: 0.06em;
	text-transform: uppercase;
	line-height: 1;
	cursor: pointer;
	transition: background var( --srf-transition ), color var( --srf-transition ), border-color var( --srf-transition );
}

.srf-pill:hover {
	border-color: var( --srf-color-ink );
}

.srf-pill.is-selected {
	background: var( --srf-color-ink );
	border-color: var( --srf-color-ink );
	color: var( --srf-color-on-ink );
}

/* Buttons */
.srf-submit,
.srf-loadmore,
.srf-retry {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	min-height: 44px;
	padding: var( --srf-space-2 ) var( --srf-space-4 );
	border: var( --srf-border-width ) solid var( --srf-color-ink );
	border-radius: var( --srf-radius-pill );
	background: var( --srf-color-ink );
	color: var( --srf-color-on-ink );
	font: inherit;
	font-weight: 700;
	cursor: pointer;
}

.srf-submit:hover,
.srf-loadmore:hover,
.srf-retry:hover {
	background: var( --srf-color-accent-2 );
	border-color: var( --srf-color-accent-2 );
}

.srf-clear-filters {
	display: inline-flex;
	align-items: center;
	min-height: 44px;
	padding: var( --srf-space-2 ) var( --srf-space-3 );
	border: var( --srf-border-width ) solid var( --srf-color-border-2 );
	border-radius: var( --srf-radius-pill );
	background: transparent;
	color: var( --srf-color-ink-2 );
	font: inherit;
	cursor: pointer;
	text-decoration: none;
}

/* With JS active the manual Apply button is unnecessary. */
.srf-js .srf-submit {
	display: none;
}

.srf-active-filters {
	flex: 1 1 100%;
	display: flex;
	flex-wrap: wrap;
	gap: var( --srf-space-1 );
}

/* -------------------------------------------------------------------------- */
/* Results grid + cards                                                       */
/* -------------------------------------------------------------------------- */

.srf-reviews-grid {
	display: grid;
	gap: var( --srf-gap );
	grid-template-columns: repeat( var( --srf-cols ), minmax( 0, 1fr ) );
	/* Cards in a row share the row's height regardless of content length. */
	align-items: stretch;
}

.srf-cols-1 { --srf-cols: 1; }
.srf-cols-2 { --srf-cols: 2; }
.srf-cols-3 { --srf-cols: 3; }
.srf-cols-4 { --srf-cols: 4; }
.srf-cols-5 { --srf-cols: 5; }
.srf-cols-6 { --srf-cols: 6; }

.srf-review-card {
	display: flex;
	flex-direction: column;
	gap: var( --srf-space-2 );
	border: var( --srf-border-width ) solid var( --srf-color-border );
	border-radius: var( --srf-radius-card );
	padding: var( --srf-space-4 );
	background: var( --srf-color-surface );
	height: 100%;
}

.srf-review-card.srf-is-featured {
	border-color: var( --srf-color-border-2 );
}

.srf-review-media img,
.srf-review-photo {
	max-width: 100%;
	width: 64px;
	height: 64px;
	object-fit: cover;
	border-radius: var( --srf-radius-pill );
	margin-bottom: var( --srf-space-2 );
}

.srf-card-top {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: var( --srf-space-2 );
}

.srf-card-tag {
	display: inline-flex;
	align-items: center;
	padding: var( --srf-space-1 ) var( --srf-space-3 );
	border-radius: var( --srf-radius-pill );
	background: var( --srf-color-ink );
	color: var( --srf-color-on-ink );
	font-size: var( --srf-tag-size );
	font-weight: 700;
	letter-spacing: 0.06em;
	text-transform: uppercase;
	line-height: 1.4;
}

.srf-card-meta {
	display: flex;
	align-items: baseline;
	justify-content: space-between;
	gap: var( --srf-space-2 );
	flex-wrap: wrap;
}

.srf-card-meta-left {
	display: inline-flex;
	flex-wrap: wrap;
	align-items: baseline;
	gap: var( --srf-space-2 );
	min-width: 0;
}

.srf-card-source {
	color: var( --srf-color-accent-text );
	font-size: var( --srf-meta-size );
	font-weight: 700;
	letter-spacing: 0.04em;
	text-transform: uppercase;
}

.srf-card-company {
	/* No opacity: fading text silently lowers its contrast (this pair measured
	   2.18:1 at 85%). Hierarchy comes from weight/size, not transparency. */
	color: var( --srf-color-accent-text );
	font-size: var( --srf-meta-size );
	font-weight: 400;
}

.srf-card-date {
	color: var( --srf-color-ink-2 );
	font-size: var( --srf-meta-size );
	white-space: nowrap;
}

.srf-review-rating {
	margin: 0;
}

.srf-stars {
	color: var( --srf-color-star );
	letter-spacing: 2px;
	font-size: 1.05rem;
}

.srf-card-body {
	flex: 1 1 auto;
	font-size: var( --srf-body-size );
	line-height: var( --srf-body-line );
	color: var( --srf-color-ink );
}

.srf-card-body p:last-child {
	margin-bottom: 0;
}

/* Truncation is done server-side from the excerpt_length setting, so every card
   starts at the same height. Without JS the full review is shown (nothing is
   locked behind a script); with JS the excerpt shows until READ expands it. */
.srf-card-excerpt {
	margin: 0;
	display: none;
}

.srf-js .srf-card-excerpt {
	display: block;
}

/*
 * `.srf-is-truncated` is NOT decoration — it is what makes hiding the body safe.
 *
 * The excerpt element is only rendered when the review is actually longer than
 * excerpt_length. A shorter review therefore has no excerpt to stand in for the
 * body and no READ control to reveal it, so hiding its body erases the review:
 * the card renders with a name and a date and nothing else. That is exactly what
 * this rule did before 1.0.11, when it matched every unexpanded card, and it
 * silently blanked every review of excerpt_length words or fewer.
 *
 * Scope any future "collapse the body" rule to this class for the same reason.
 */
.srf-js .srf-review-card.srf-is-truncated:not( .is-expanded ) .srf-card-full {
	display: none;
}

.srf-js .srf-review-card.is-expanded .srf-card-excerpt {
	display: none;
}

.srf-card-footer {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: var( --srf-space-2 );
	margin-top: auto;
	padding-top: var( --srf-space-2 );
}

.srf-card-name {
	font-weight: 800;
	text-transform: uppercase;
	letter-spacing: 0.03em;
	font-size: var( --srf-meta-size );
	color: var( --srf-color-ink );
}

.srf-card-read {
	display: inline-flex;
	align-items: center;
	gap: 0.25em;
	padding: 0;
	border: 0;
	background: none;
	color: var( --srf-color-accent-text );
	font-size: var( --srf-meta-size );
	font-weight: 800;
	letter-spacing: 0.06em;
	text-transform: uppercase;
	cursor: pointer;
	text-decoration: none;
}

.srf-card-read:hover {
	color: var( --srf-color-accent-text-strong );
}

.srf-badge {
	display: inline-flex;
	align-items: center;
	padding: var( --srf-space-1 ) var( --srf-space-2 );
	border-radius: var( --srf-radius-pill );
	font-size: var( --srf-tag-size );
	font-weight: 700;
	line-height: 1.4;
}

.srf-badge-verified {
	background: var( --srf-color-verified-bg );
	color: var( --srf-color-verified-ink );
}

/* -------------------------------------------------------------------------- */
/* States (empty, loading, error, highlight)                                  */
/* -------------------------------------------------------------------------- */

.srf-empty {
	padding: var( --srf-space-4 );
	color: var( --srf-color-muted );
	font-style: italic;
}

.srf-empty .srf-clear-filters {
	margin-top: var( --srf-space-2 );
}

.srf-results {
	position: relative;
	min-height: 2rem;
}

.srf-results.srf-is-loading {
	opacity: 0.6;
	transition: opacity var( --srf-transition );
}

.srf-results.srf-is-loading::after {
	content: "";
	position: absolute;
	top: var( --srf-space-3 );
	right: var( --srf-space-3 );
	width: 1.15rem;
	height: 1.15rem;
	border: 2px solid var( --srf-color-track );
	border-top-color: var( --srf-color-accent );
	border-radius: var( --srf-radius-pill );
	animation: srf-spin 0.7s linear infinite;
}

@keyframes srf-spin {
	to { transform: rotate( 360deg ); }
}

.srf-error {
	padding: var( --srf-space-3 ) var( --srf-space-4 );
	margin-bottom: var( --srf-gap );
	border: var( --srf-border-width ) solid var( --srf-color-error-border );
	background: var( --srf-color-error-bg );
	color: var( --srf-color-error-ink );
	border-radius: var( --srf-radius-card );
}

.srf-error p {
	margin: 0 0 var( --srf-space-2 );
}

.srf-mark {
	background: var( --srf-color-mark-bg );
	color: inherit;
	padding: 0 0.05em;
	border-radius: 2px;
}

/* -------------------------------------------------------------------------- */
/* Pagination (pill language)                                                 */
/* -------------------------------------------------------------------------- */

.srf-pagination {
	margin-top: var( --srf-gap );
}

.srf-pagination-list {
	display: flex;
	flex-wrap: wrap;
	gap: var( --srf-space-1 );
	list-style: none;
	margin: 0;
	padding: 0;
}

.srf-page-link {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	min-width: 44px;
	min-height: 44px;
	padding: var( --srf-space-2 ) var( --srf-space-3 );
	border: var( --srf-border-width ) solid var( --srf-color-border-2 );
	border-radius: var( --srf-radius-pill );
	text-decoration: none;
	color: var( --srf-color-ink );
	background: var( --srf-color-surface-2 );
	font-weight: 700;
	transition: background var( --srf-transition ), color var( --srf-transition ), border-color var( --srf-transition );
}

.srf-page-link:hover {
	border-color: var( --srf-color-ink );
}

.srf-page-link.is-current {
	background: var( --srf-color-ink );
	border-color: var( --srf-color-ink );
	color: var( --srf-color-on-ink );
}

.srf-page-link.is-disabled {
	cursor: default;
	color: var( --srf-color-muted );
	border-color: var( --srf-color-border );
}

.srf-page-ellipsis {
	display: inline-flex;
	align-items: center;
	padding: 0 var( --srf-space-1 );
	color: var( --srf-color-muted );
}

.srf-loadmore-wrap {
	margin-top: var( --srf-gap );
	text-align: center;
}

.srf-loadmore[disabled] {
	opacity: 0.6;
	cursor: default;
}

/* -------------------------------------------------------------------------- */
/* FAQ accordion                                                              */
/* -------------------------------------------------------------------------- */

.srf-faq-list {
	border: var( --srf-border-width ) solid var( --srf-color-border );
	border-radius: var( --srf-radius-card );
	overflow: hidden;
	background: var( --srf-color-surface );
}

.srf-faq-item + .srf-faq-item {
	border-top: var( --srf-border-width ) solid var( --srf-color-border );
}

.srf-faq-question-heading {
	margin: 0;
	font-size: inherit;
	font-weight: inherit;
}

.srf-faq-question {
	display: flex;
	width: 100%;
	align-items: center;
	justify-content: space-between;
	gap: var( --srf-space-4 );
	padding: var( --srf-space-3 ) var( --srf-space-4 );
	background: transparent;
	border: 0;
	cursor: pointer;
	text-align: left;
	font: inherit;
	font-weight: 700;
	color: var( --srf-color-ink );
	line-height: 1.4;
}

.srf-faq-question:hover {
	background: var( --srf-color-surface-2 );
}

.srf-faq-question:focus-visible {
	outline: var( --srf-focus-width ) solid var( --srf-color-focus );
	outline-offset: -2px;
}

.srf-faq-icon {
	flex: 0 0 auto;
	width: 0.7rem;
	height: 0.7rem;
	border-right: 2px solid currentColor;
	border-bottom: 2px solid currentColor;
	transform: rotate( 45deg );
	transition: transform 0.2s ease;
}

.srf-faq-question[aria-expanded="true"] .srf-faq-icon {
	transform: rotate( -135deg );
}

.srf-faq-panel-inner {
	padding: 0 var( --srf-space-4 ) var( --srf-space-4 );
}

.srf-faq-short-answer {
	font-weight: 700;
	margin: 0 0 var( --srf-space-2 );
}

.srf-faq-answer {
	line-height: 1.6;
	color: var( --srf-color-ink );
}

.srf-faq-answer p:last-child {
	margin-bottom: 0;
}

.srf-faq-taxonomies {
	display: flex;
	flex-wrap: wrap;
	gap: var( --srf-space-1 );
	margin: 0 0 var( --srf-space-2 );
}

.srf-tag {
	display: inline-flex;
	align-items: center;
	padding: var( --srf-space-1 ) var( --srf-space-3 );
	border-radius: var( --srf-radius-pill );
	font-size: var( --srf-tag-size );
	background: var( --srf-color-ink );
	color: var( --srf-color-on-ink );
}

.srf-tag-topic {
	background: var( --srf-color-surface-2 );
	color: var( --srf-color-ink-2 );
	border: var( --srf-border-width ) solid var( --srf-color-border-2 );
}

.srf-faq-panel[hidden] {
	display: none;
}

/* -------------------------------------------------------------------------- */
/* Responsive: 4-up desktop, 2-up tablet, 1-up mobile.                        */
/* -------------------------------------------------------------------------- */

@media ( max-width: 1024px ) {
	.srf-cols-3,
	.srf-cols-4,
	.srf-cols-5,
	.srf-cols-6 { --srf-cols: 2; }
}

@media ( max-width: 600px ) {
	.srf-reviews-grid { --srf-cols: 1; }

	.srf-control,
	.srf-control-actions {
		flex: 1 1 100%;
	}

	.srf-control-actions {
		justify-content: flex-start;
	}
}

/* -------------------------------------------------------------------------- */
/* Filter disclosure.                                                         */
/* -------------------------------------------------------------------------- */

/*
 * Keep both breakpoint literals in step with --srf-breakpoint-mobile and
 * Settings::MOBILE_BREAKPOINT; css-tokens.php fails the build if they diverge.
 * `not all and ( max-width: … )` is the exact complement of the mobile query, so
 * the number never has to appear as both 600 and 601.
 */

/* At mobile the disclosure becomes real: the summary is a visible control and
   the panel is hidden unless the <details> is open. Hiding the panel OURSELVES,
   keyed on [open], means the collapse does not depend on how a given engine
   hides a closed <details>'s content — the one part of this that varies between
   Chrome, Firefox and Safari. */
@media ( max-width: 600px ) {
	.srf-filters-summary {
		display: flex;
		align-items: center;
		gap: var( --srf-space-2 );
		min-height: 44px; /* Pointer target size (WCAG 2.5.8). */
		padding: var( --srf-space-3 ) var( --srf-space-4 );
		border: var( --srf-border-width ) solid var( --srf-color-border );
		border-radius: var( --srf-radius-input );
		background: var( --srf-color-surface-2 );
		color: var( --srf-color-ink );
		font-size: var( --srf-body-size );
		font-weight: 700;
		cursor: pointer;
	}

	.srf-filters-panel {
		display: none;
	}

	.srf-filters-disclosure[open] > .srf-filters-panel {
		display: flex;
		margin-top: var( --srf-space-3 );
	}
}

/*
 * Above the breakpoint the summary is hidden but STAYS IN THE DOM, so narrowing
 * the viewport restores a working control without a reload. Same clip technique
 * as .srf-sr-only — never display:none, which would drop it from the
 * accessibility tree.
 *
 * The panel is already `display: flex` in the base layer, which also beats the
 * user-agent rule that hides a closed <details>'s children (author declarations
 * win over user-agent ones on cascade ORIGIN, so no !important is needed — this
 * stylesheet reserves that for the prefers-reduced-motion safety net alone).
 * Chrome 131+ instead wraps the content in a ::details-content pseudo carrying
 * `content-visibility: hidden`, which a rule on the child cannot reach; the
 * second rule below handles that. It is a SEPARATE rule on purpose — a browser
 * that does not know the pseudo-element drops the rule it appears in, so pairing
 * it with the summary selector would silently disable that too.
 *
 * frontend.js also sets `open` above this breakpoint, so whenever JavaScript
 * runs the panel is genuinely open and neither override is load-bearing. They
 * are the no-JS desktop path.
 */
@media not all and ( max-width: 600px ) {
	.srf-filters-summary {
		position: absolute;
		width: 1px;
		height: 1px;
		margin: -1px;
		padding: 0;
		overflow: hidden;
		clip: rect( 0, 0, 0, 0 );
		clip-path: inset( 50% );
		white-space: nowrap;
		border: 0;
	}

	.srf-filters-disclosure::details-content {
		content-visibility: visible;
	}
}

/* -------------------------------------------------------------------------- */
/* Reduced motion.                                                            */
/* -------------------------------------------------------------------------- */

@media ( prefers-reduced-motion: reduce ) {
	.srf-reviews *,
	.srf-faqs * {
		transition: none !important;
		animation: none !important;
	}
}
