/* =========================================================
 * Escape Testimonials — front-end styles
 *
 * Layered on top of the ETI design system. The card silhouette
 * (radius, shadow, hover lift, padding rhythm) mirrors
 * .eti_media-card so testimonials read as a sibling component
 * rather than a foreign addition.
 *
 * Dependencies (CSS custom properties from tokens.css):
 *   --eti-radius-md, --eti-shadow-sm, --eti-shadow-lg,
 *   --eti-shadow-2xl, --eti-transition-base,
 *   --eti-color-bg-elevated, --eti-color-text-*,
 *   --eti-color-border, --eti-color-warning,
 *   --eti-space-1..16, --eti-radius-full
 * ========================================================= */

:root {
	--eti-testimonial-google:        #4285F4;
	--eti-testimonial-facebook:      #1877F2;
	--eti-testimonial-email:         var(--eti-color-forest, #39472F);

	--eti-testimonial-star:          var(--eti-color-warning, #D4A017);
	--eti-testimonial-star-empty:    rgba(0, 0, 0, .12);

	/* The card body clamps at this height; longer reviews show
	   "Read full review" and expand into the modal. Slightly tighter
	   than the original to keep individual cards compact — the
	   masonry layout below handles the row-to-row height variance. */
	--eti-testimonial-clamp:         6rem;
}

/* Cards without a gallery have nothing competing with the text
   for vertical space, so let the clamp run roughly twice as tall
   to make better use of the card. Cards with a gallery keep the
   tighter clamp so the photo and text stay in balance. */
.eti_testimonial:not(:has(.eti_testimonial__gallery)) {
	--eti-testimonial-clamp: 12rem;
}

/* ── Card shell — mirrors .eti_media-card ─────────────────── */
.eti_testimonial {
	display: flex;
	flex-direction: column;
	gap: var(--eti-space-5, 20px);
	padding: var(--eti-space-6, 24px);
	background: var(--eti-color-bg-elevated, #FFFFFF);
	border-radius: var(--eti-radius-md, 12px);
	box-shadow: var(--eti-shadow-sm, 0 1px 2px rgba(0,0,0,.06));
	overflow: hidden;
	position: relative;
	transition: transform var(--eti-transition-base, .18s ease),
	            box-shadow var(--eti-transition-base, .18s ease);
}
.eti_testimonial:hover {
	transform: translateY(-2px);
	box-shadow: var(--eti-shadow-lg, 0 12px 32px rgba(0,0,0,.1));
}

/* When a card is being lazy-load-revealed, override the card's
   default transition (which only covers transform + box-shadow)
   so opacity ALSO animates. Higher specificity (0,2,0) than both
   `.eti_testimonial` and `.eti_reveal` on their own, so this wins
   the cascade. The inline transition-delay set by JS still applies
   to all the longhands listed here, giving the staggered cascade. */
.eti_testimonial.eti_reveal {
	transition:
		opacity   1100ms cubic-bezier(.22, 1, .36, 1),
		transform 1100ms cubic-bezier(.22, 1, .36, 1);
}

/* Source-themed accent on the top edge — the visual cue that
   differentiates Google / Facebook / Email at a glance. */
.eti_testimonial::before {
	content: "";
	position: absolute;
	top: 0;
	left: 0;
	right: 0;
	height: 6px;
	background: var(--eti-color-border, #D4CEC5);
}
.eti_testimonial--google::before {
	background: linear-gradient(90deg, #4285F4 0%, #34A853 33%, #FBBC05 66%, #EA4335 100%);
}
.eti_testimonial--facebook::before { background: var(--eti-testimonial-facebook); }
.eti_testimonial--email::before    { background: var(--eti-testimonial-email); }
.eti_testimonial--delivery::before { background: var(--eti-color-signal-red, #C82127); }

/* ── Header: avatar + name + meta row ─────────────────────── */
.eti_testimonial__head {
	display: flex;
	align-items: center;
	gap: var(--eti-space-3, 12px);
}

.eti_testimonial__avatar-link { display: inline-block; line-height: 0; }

.eti_testimonial__avatar {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 48px;
	height: 48px;
	flex-shrink: 0;
	border-radius: var(--eti-radius-full, 9999px);
	overflow: hidden;
	background: var(--eti-color-bg-muted, #D9E7E8);
	box-shadow: var(--eti-shadow-sm, 0 1px 2px rgba(0,0,0,.08));
}
.eti_testimonial__avatar-img { width: 100%; height: 100%; object-fit: cover; }
.eti_testimonial__avatar-initial {
	font-family: var(--eti-font-display, "Oswald", sans-serif);
	font-weight: 600;
	font-size: 22px;
	color: var(--eti-color-forest, #39472F);
	line-height: 1;
}

.eti_testimonial__identity { flex: 1; min-width: 0; }

.eti_testimonial__name {
	margin: 0;
	font-weight: var(--eti-font-weight-semibold, 600);
	font-size: var(--eti-font-size-base, 1rem);
	color: var(--eti-color-text-primary, #39472F);
	line-height: 1.2;
}
.eti_testimonial__name a { color: inherit; text-decoration: none; }
.eti_testimonial__name a:hover { text-decoration: underline; }

.eti_testimonial__meta {
	margin-top: 4px;
	display: flex;
	align-items: center;
	gap: var(--eti-space-2, 8px);
	font-size: var(--eti-font-size-xs, .75rem);
	color: var(--eti-color-text-muted, #7D7D7D);
	flex-wrap: wrap;
}
.eti_testimonial__date { font-variant-numeric: tabular-nums; }

/* ── Source pill ──────────────────────────────────────────── */
.eti_testimonial__source-link { text-decoration: none; display: inline-flex; }
.eti_testimonial__source {
	display: inline-flex;
	align-items: center;
	gap: 6px;
	padding: 3px 10px 3px 6px;
	font-size: .75rem;
	font-weight: 500;
	letter-spacing: .01em;
	border-radius: var(--eti-radius-full, 9999px);
	background: rgba(0, 0, 0, .04);
	color: var(--eti-color-text-primary, #39472F);
	line-height: 1;
}
.eti_testimonial__source svg { width: 16px; height: 16px; flex-shrink: 0; }
.eti_testimonial__source--google   { background: rgba(66, 133, 244, .08); color: #1A0DAB; }
.eti_testimonial__source--facebook { background: rgba(24, 119, 242, .1);  color: var(--eti-testimonial-facebook); }
.eti_testimonial__source--email    { background: rgba(57, 71, 47, .1);    color: var(--eti-testimonial-email); }

/* ── Stars (used in source corner for Google) ────────────── */
.eti_testimonial__stars  { display: inline-flex; gap: 2px; }
.eti_testimonial__star   {
	display: inline-flex;
	width: 16px;
	height: 16px;
	line-height: 1;
}
.eti_testimonial__star svg { width: 100%; height: 100%; }
.eti_testimonial__star.is-filled { color: var(--eti-testimonial-star); }
.eti_testimonial__star.is-empty  { color: var(--eti-testimonial-star-empty); }

/* ── Source corner ────────────────────────────────────────────
 *
 * Top-right of the card head row. Each provider gets a different
 * cue: Google = star rating, Facebook = recommend chat-bubble,
 * Email = heart. Sits at the end of the flex row so it's pinned
 * right by margin-left:auto.
 * ──────────────────────────────────────────────────────────── */
.eti_testimonial__corner {
	margin-left: auto;
	flex-shrink: 0;
	display: inline-flex;
	align-items: center;
	line-height: 1;
}
.eti_testimonial__corner--email   { color: var(--eti-color-signal-red, #C82127); }
.eti_testimonial__corner svg      { display: block; }
.eti_testimonial__corner--google .eti_testimonial__rating { margin: 0; } /* legacy guard */

/* ── Body ─────────────────────────────────────────────────── */
.eti_testimonial__body {
	position: relative;
	color: var(--eti-color-text-body, #484848);
	font-size: var(--eti-font-size-sm, .9375rem);
	line-height: var(--eti-line-height-snug, 1.55);
}
.eti_testimonial__quote-mark {
	position: absolute;
	top: -4px;
	left: -4px;
	width: 24px;
	height: 24px;
	fill: rgba(0, 0, 0, .06);
	pointer-events: none;
	z-index: 0;
}

.eti_testimonial__body-text {
	position: relative;
	max-height: var(--eti-testimonial-clamp);
	overflow: hidden;
}

/* Tighten the design system's prose rhythm inside cards. The
   default .eti_prose puts ~32px of margin between paragraphs and
   bigger gaps before lists/headings — too generous when the
   body-text is line-clamped to a few lines. Inside the modal
   (where the testimonial is unclamped) the default prose rhythm
   is restored below. */
.eti_testimonial__body-text.eti_prose > :is(p, ul, ol, blockquote, figure, pre, hr) + :is(p, ul, ol, blockquote, figure, pre, hr) {
	margin-top: var(--eti-space-3, 12px);
}
.eti_testimonial__body-text.eti_prose > :is(p, ul, ol, blockquote, figure, pre, hr) + :is(h2, h3, h4, h5, h6) {
	margin-top: var(--eti-space-5, 20px);
}
.eti_testimonial__body-text.eti_prose { max-width: none; } /* remove the 84ch ceiling — cards/modal already cap width */

/* Inline images and figures inside testimonial body text — cap
   them to text-height so accidentally-pasted emoji / icons /
   Gutenberg image blocks don't blow up the layout. Real photos
   should go in the Gallery field; the body is for text. The
   design system's prose has a `.eti_prose figure img { width:
   100% }` rule which is why a figure-wrapped emoji can suddenly
   take over the whole modal — this caps that. */
.eti_testimonial__body-text img,
.eti_testimonial__body-text figure {
	max-height: 1.6em;
	max-width: 100%;
	width: auto;
	height: auto;
	display: inline-block;
	vertical-align: middle;
	margin: 0;
	padding: 0;
}
.eti_testimonial__body-text figure img {
	max-height: 1.6em;
	width: auto;
}

/* Fade-out at the clamp boundary. Hidden when JS confirms the
   content fits (.is-not-clamped) or when the card has been
   expanded into the modal. */
.eti_testimonial__body-text::after {
	content: "";
	position: absolute;
	left: 0;
	right: 0;
	bottom: 0;
	height: 2.4em;
	background: linear-gradient(to bottom, rgba(255,255,255,0), var(--eti-color-bg-elevated, #FFFFFF) 92%);
	pointer-events: none;
}
.eti_testimonial.is-not-clamped .eti_testimonial__body-text {
	max-height: none;
}
.eti_testimonial.is-not-clamped .eti_testimonial__body-text::after {
	display: none;
}

/* ── Expand button — small wood-coloured pill ─────────────────
 *
 * Layered onto .eti_btn .eti_btn--xs in the markup so we inherit
 * the design system's button rhythm (radius, lift on hover, focus
 * ring). Wood isn't one of the stock variants, so we set the
 * --eti-btn-* custom properties here to theme it without forking
 * the base button rules.
 * ──────────────────────────────────────────────────────────── */
.eti_testimonial__expand {
	align-self: flex-start;
	--eti-btn-bg:        var(--eti-color-wood, #7B644D);
	--eti-btn-bg-hover:  #5F4D3A;
	--eti-btn-fg:        var(--eti-color-white, #FFFFFF);
	--eti-btn-fg-hover:  var(--eti-color-white, #FFFFFF);
	--eti-btn-border:    transparent;
	background-color: var(--eti-btn-bg);
	color: var(--eti-btn-fg);
}
.eti_testimonial__expand:hover {
	background-color: var(--eti-btn-bg-hover);
	color: var(--eti-btn-fg-hover);
}
.eti_testimonial__expand[hidden] { display: none; }

/* If the design system isn't loaded (no .eti_btn base), provide a
   minimal fallback so the button still reads as a button. */
.eti_testimonial__expand:not(.eti_btn) {
	display: inline-flex;
	align-items: center;
	gap: 6px;
	padding: 6px 14px;
	border: 0;
	border-radius: var(--eti-radius-full, 9999px);
	font: inherit;
	font-size: var(--eti-font-size-xs, .75rem);
	font-weight: 500;
	cursor: pointer;
	transition: background-color var(--eti-transition-base, .18s ease);
}

/* ── Gallery (customer photos) ────────────────────────────────
 *
 * Sized by count so a single image doesn't dominate the card the
 * way a square thumbnail would, but multiple images still tile
 * cleanly. Inside the modal these caps are lifted (see modal
 * overrides below) so the user can see the photos at a useful size.
 * ──────────────────────────────────────────────────────────── */
.eti_testimonial__gallery {
	display: grid;
	grid-template-columns: repeat(3, 1fr);
	gap: var(--eti-space-2, 8px);
	margin-top: var(--eti-space-3, 12px);
}

/* Single image — landscape thumb, capped at 260px wide so it sits
   on the card like an attached polaroid rather than a poster. */
.eti_testimonial__gallery[data-count="1"] {
	display: block;
}
.eti_testimonial__gallery[data-count="1"] .eti_testimonial__gallery-item {
	display: block;
	width: min(75%, 260px);
	aspect-ratio: 4 / 3;
}

/* Two images — side-by-side, slightly tall, still landscape-ish. */
.eti_testimonial__gallery[data-count="2"] {
	grid-template-columns: 1fr 1fr;
}
.eti_testimonial__gallery[data-count="2"] .eti_testimonial__gallery-item {
	aspect-ratio: 4 / 3;
}

.eti_testimonial__gallery-item {
	display: block;
	position: relative;
	aspect-ratio: 1 / 1;
	overflow: hidden;
	border-radius: var(--eti-radius-sm, 6px);
	background: var(--eti-color-bg-muted, #f0f0f0);
	transition: transform var(--eti-transition-fast, .15s ease),
	            box-shadow var(--eti-transition-fast, .15s ease);
	text-decoration: none;
}
.eti_testimonial__gallery-item:hover {
	transform: scale(1.02);
	box-shadow: var(--eti-shadow-sm, 0 1px 4px rgba(0,0,0,.08));
}
.eti_testimonial__gallery-img {
	width: 100%;
	height: 100%;
	object-fit: cover;
	display: block;
}
.eti_testimonial__gallery-caption {
	position: absolute;
	bottom: 0;
	left: 0;
	right: 0;
	padding: 6px 10px;
	font-size: .75rem;
	color: #fff;
	background: linear-gradient(to top, rgba(0, 0, 0, .7), transparent);
	opacity: 0;
	transition: opacity var(--eti-transition-fast, .15s ease);
}
.eti_testimonial__gallery-item:hover .eti_testimonial__gallery-caption,
.eti_testimonial__gallery-item:focus .eti_testimonial__gallery-caption {
	opacity: 1;
}

/* ── Delivery Day card ─────────────────────────────────────
 *
 * Photo-first layout. The hero image fills the card at a fixed
 * 4:3 aspect ratio; a compact byline (avatar + name + date) sits
 * below. The full gallery is rendered hidden so the modal expand
 * flow can clone + convert it into the slider, same as any other
 * card. Clicking the hero opens that modal.
 * ──────────────────────────────────────────────────────────── */

.eti_testimonial--delivery {
	padding: 0;
	overflow: hidden;
}

.eti_testimonial--delivery .eti_testimonial__hero-link {
	position: relative;
	display: block;
	aspect-ratio: 4 / 3;
	overflow: hidden;
	cursor: zoom-in;
	background: var(--eti-color-bg-muted, #f0f0f0);
}
.eti_testimonial--delivery .eti_testimonial__hero-img {
	width: 100%;
	height: 100%;
	max-width: 100%;
	object-fit: cover;
	display: block;
	transition: transform var(--eti-transition-base, .3s ease);
}
.eti_testimonial--delivery .eti_testimonial__hero-link:hover .eti_testimonial__hero-img {
	transform: scale(1.04);
}

/* "Delivery Day" pill — top-left of the hero so the bottom edge
   stays clear for the byline overlay below. Solid signal-red so
   the celebratory cue reads even over busy photos; soft shadow
   lifts it off the image. */
.eti_testimonial__hero-badge {
	position: absolute;
	top: var(--eti-space-3, 12px);
	left: var(--eti-space-3, 12px);
	display: inline-flex;
	align-items: center;
	padding: 5px 12px;
	background: var(--eti-color-signal-red, #C82127);
	color: var(--eti-color-white, #FFFFFF);
	font-size: var(--eti-font-size-xs, .75rem);
	font-weight: var(--eti-font-weight-semibold, 600);
	letter-spacing: .01em;
	border-radius: var(--eti-radius-full, 9999px);
	box-shadow: 0 2px 10px rgba(0, 0, 0, .25);
	z-index: 2;
}

/* Photo-count chip in the top-right when there's more than one
   image — hints "click for the full set". */
.eti_testimonial__hero-count {
	position: absolute;
	top: var(--eti-space-3, 12px);
	right: var(--eti-space-3, 12px);
	min-width: 32px;
	height: 28px;
	padding: 0 10px;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	background: rgba(0, 0, 0, .55);
	color: var(--eti-color-white, #FFFFFF);
	font-size: var(--eti-font-size-xs, .75rem);
	font-weight: var(--eti-font-weight-semibold, 600);
	border-radius: var(--eti-radius-full, 9999px);
	backdrop-filter: blur(6px);
	-webkit-backdrop-filter: blur(6px);
	z-index: 2;
}

/* Byline overlay — forest-green semi-transparent strip pinned to
   the bottom of the hero. Seals the gap a separate footer left
   below the photo, ties the avatar/name visually to the image. */
.eti_testimonial__hero-byline {
	position: absolute;
	bottom: 0;
	left: 0;
	right: 0;
	z-index: 2;
	display: flex;
	align-items: center;
	gap: var(--eti-space-3, 12px);
	padding: var(--eti-space-3, 12px) var(--eti-space-4, 16px);
	color: var(--eti-color-white, #FFFFFF);
	background: rgba(57, 71, 47, .85); /* forest fallback */
	background: color-mix( in srgb, var(--eti-color-forest, #39472F) 85%, transparent );
	backdrop-filter: blur(8px);
	-webkit-backdrop-filter: blur(8px);
}
.eti_testimonial__hero-byline .eti_testimonial__avatar {
	width: 36px;
	height: 36px;
	background: rgba(255, 255, 255, .18);
	box-shadow: none;
	flex-shrink: 0;
}
.eti_testimonial__hero-byline .eti_testimonial__avatar-initial {
	color: var(--eti-color-white, #FFFFFF);
	font-size: 16px;
}
.eti_testimonial__hero-byline .eti_testimonial__identity {
	display: flex;
	flex-direction: column;
	min-width: 0;
	line-height: 1.2;
}
.eti_testimonial__hero-byline .eti_testimonial__name {
	color: var(--eti-color-white, #FFFFFF);
	font-weight: var(--eti-font-weight-semibold, 600);
	white-space: nowrap;
	overflow: hidden;
	text-overflow: ellipsis;
}
.eti_testimonial__hero-byline .eti_testimonial__date,
.eti_testimonial__hero-byline .eti_testimonial__byline-meta {
	margin-top: 2px;
	color: rgba(255, 255, 255, .75);
	font-size: var(--eti-font-size-xs, .75rem);
}
.eti_testimonial__hero-byline .eti_testimonial__byline-meta {
	display: inline-flex;
	align-items: center;
	gap: 8px;
	flex-wrap: wrap;
}
.eti_testimonial__location {
	display: inline-flex;
	align-items: center;
	gap: 3px;
	white-space: nowrap;
}
.eti_testimonial__location::before {
	content: "·";
	margin-right: 6px;
	opacity: .6;
}
.eti_testimonial__location svg {
	width: 12px;
	height: 12px;
}

/* In modal context (cloned card), the byline goes light-on-dark
   → dark-on-light. The location pin should follow. */
.eti_testimonial-modal .eti_testimonial__hero-byline .eti_testimonial__byline-meta {
	color: var(--eti-color-text-muted, #7D7D7D);
}

/* Hide the gallery in card view — it exists only as the source
   for the modal slider. */
.eti_testimonial--delivery .eti_testimonial__gallery {
	display: none;
}

/* ── Modal: chrome, layout, in-modal slider ──────────────────
 *
 * No header bar — the cloned card's avatar / name / source pill /
 * date already serves as the top of the modal. Close button is
 * an absolute-positioned overlay in the top-right.
 * ──────────────────────────────────────────────────────────── */

.eti_testimonial-modal__close {
	position: absolute;
	top: var(--eti-space-3, 12px);
	right: var(--eti-space-3, 12px);
	z-index: 2;
	width: 36px;
	height: 36px;
	padding: 0;
	border: 0;
	border-radius: var(--eti-radius-full, 9999px);
	background: rgba(255, 255, 255, .9);
	color: var(--eti-color-text-primary, #39472F);
	cursor: pointer;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	box-shadow: var(--eti-shadow-sm);
	transition: background-color var(--eti-transition-fast, .15s ease),
	            color var(--eti-transition-fast, .15s ease);
}
.eti_testimonial-modal__close:hover {
	background: var(--eti-color-text-primary, #39472F);
	color: var(--eti-color-white, #FFFFFF);
}
.eti_testimonial-modal__close svg { width: 16px; height: 16px; }

/* Cloned card needs space at the top so the close button doesn't
   clip the avatar, plus the usual unclamp + flatten styling.
 *
 * Bottom padding is zeroed so the last child (the image slot,
 * or the body text on photo-free reviews) sits flush against
 * the modal's rounded bottom edge — eliminates the empty-white
 * strip at the bottom corners that appeared when the card's
 * default padding made the modal taller than its content. */
.eti_testimonial-modal .eti_modal__body { padding: 0; }
.eti_testimonial-modal .eti_testimonial {
	box-shadow: none;
	border-radius: 0;
	padding: var(--eti-space-7, 28px) var(--eti-space-7, 28px) 0;
}
.eti_testimonial-modal .eti_testimonial::before { display: none; }
.eti_testimonial-modal .eti_testimonial:hover { transform: none; }

.eti_testimonial-modal .eti_testimonial__body-text { max-height: none; overflow: visible; }
.eti_testimonial-modal .eti_testimonial__body-text::after { display: none; }
.eti_testimonial-modal .eti_testimonial__expand { display: none; }

/* Inside the modal, the slider (rendered from the previously-hidden
   gallery) takes over as the primary visual. The hero-link wrapper
   stays in the DOM because the byline lives inside it now, but we
   strip its hero behaviours so it just acts as a container for the
   un-overlaid byline. */
.eti_testimonial-modal .eti_testimonial--delivery {
	padding: var(--eti-space-7, 28px);
}
.eti_testimonial-modal .eti_testimonial--delivery .eti_testimonial__hero-link {
	display: block;
	aspect-ratio: auto;
	cursor: default;
	background: transparent;
	overflow: visible;
	pointer-events: none; /* nothing to click in modal context */
}
.eti_testimonial-modal .eti_testimonial--delivery .eti_testimonial__hero-img,
.eti_testimonial-modal .eti_testimonial--delivery .eti_testimonial__hero-badge,
.eti_testimonial-modal .eti_testimonial--delivery .eti_testimonial__hero-count {
	display: none;
}
.eti_testimonial-modal .eti_testimonial--delivery .eti_testimonial__hero-byline {
	position: static;
	padding: 0;
	color: var(--eti-color-text-primary, #39472F);
	background: transparent;
	backdrop-filter: none;
	-webkit-backdrop-filter: none;
}

/* Tighten the space between the byline and the image in the
   delivery modal — defaults are tuned for the regular (quote-
   first) modal where there's body text between the header and
   the slider. Delivery cards skip the body text, so the default
   gap reads as a bigger void than it should. */
.eti_testimonial-modal .eti_testimonial--delivery .eti_testimonial-modal__slider,
.eti_testimonial-modal .eti_testimonial--delivery .eti_testimonial-modal__solo {
	margin-top: var(--eti-space-3, 12px);
}
.eti_testimonial-modal .eti_testimonial--delivery .eti_testimonial__hero-byline .eti_testimonial__avatar {
	background: var(--eti-color-bg-muted, #D9E7E8);
}
.eti_testimonial-modal .eti_testimonial--delivery .eti_testimonial__hero-byline .eti_testimonial__avatar-initial {
	color: var(--eti-color-forest, #39472F);
}
.eti_testimonial-modal .eti_testimonial--delivery .eti_testimonial__hero-byline .eti_testimonial__name {
	color: var(--eti-color-text-primary, #39472F);
}
.eti_testimonial-modal .eti_testimonial--delivery .eti_testimonial__hero-byline .eti_testimonial__date {
	color: var(--eti-color-text-muted, #7D7D7D);
}

/* Restore full prose rhythm in the modal — generous gaps between
   blocks since there's no clamp competing for vertical space. */
.eti_testimonial-modal .eti_testimonial__body-text.eti_prose > :is(p, ul, ol, blockquote, figure, pre, hr) + :is(p, ul, ol, blockquote, figure, pre, hr) {
	margin-top: var(--eti-space-5, 20px);
}
.eti_testimonial-modal .eti_testimonial__body-text.eti_prose > :is(p, ul, ol, blockquote, figure, pre, hr) + :is(h2, h3, h4, h5, h6) {
	margin-top: var(--eti-space-8, 32px);
}

/* Make the modal dialog box the positioning context for the close
   button. Without this, position:absolute on the close button
   anchors to the <dialog> element itself (which fills the viewport
   in :modal mode) and the button ends up in the page corner instead
   of the modal corner. Same fix for the share modal below.
 *
 * Also cap the dialog using `dvh` so it never extends past the
 * actual visible viewport on mobile. The DS default uses `vh` —
 * which on iOS Safari counts the address-bar space — so a long
 * form would push the bottom of the dialog (and its scrollbar)
 * below the visible area, making the submit button unreachable.
 * `dvh` excludes the chrome so the body's overflow-y: auto
 * (already on .eti_modal__body) actually scrolls within the
 * visible region. The vh declaration is the fallback for the
 * (now rare) browsers without dvh support. */
.eti_testimonial-modal .eti_modal__dialog,
.eti_share-modal      .eti_modal__dialog {
	position: relative;
	max-height: calc(100vh  - var(--eti-space-8, 32px));
	max-height: calc(100dvh - var(--eti-space-8, 32px));
}

/* Belt-and-braces — the DS gives us flex:1 + overflow-y:auto on
   the body, but our overrides reset padding on it for the
   testimonial modal and we want to be sure scrolling still
   works in both. min-height:0 is the flex-child trick that lets
   the body actually shrink below its intrinsic content height
   so overflow-y can kick in. */
.eti_testimonial-modal .eti_modal__body,
.eti_share-modal      .eti_modal__body {
	overflow-y: auto;
	-webkit-overflow-scrolling: touch;
	flex: 1 1 auto;
	min-height: 0;
}

/* The modal dialog box is wider for testimonials with photos so
   the slider has room to breathe. */
.eti_testimonial-modal .eti_modal__dialog {
	width: min(820px, calc(100vw - var(--eti-space-8, 32px)));
}

/* Portrait variant — applied by JS when the first image's
   natural height > natural width. Just narrows the dialog so
   a tall image doesn't sit awkwardly inside a wide modal with
   big empty side margins. Image height is left to flow naturally. */
.eti_testimonial-modal--portrait .eti_modal__dialog {
	width: min(560px, calc(100vw - var(--eti-space-8, 32px)));
}

/* Image slots — fluid by design.
 *
 * Customer submissions vary wildly in dimensions — wide landscape
 * shots, tall portraits, square phone screenshots — so the slot
 * sizes itself to whatever image it holds, capped only by a
 * max-height to keep absurdly tall portraits from dominating the
 * modal.
 *
 * `border-radius` sits on the IMAGE itself rather than its
 * container. Why: the container is a transparent flex centring
 * wrapper that hugs the image's natural size, so a `border-
 * radius` on the container only shows if (a) the image fills it
 * exactly AND (b) overflow:hidden clips the image. The image
 * approach is robust to any image dimensions — the rounded
 * corners are intrinsic to the image and survive every aspect
 * ratio without us having to second-guess what fills what.
 *
 * `dvh` (with vh fallback) handles iOS address-bar resize so
 * the cap reflects the actual visible viewport height, not the
 * browser's nominal one. */
.eti_testimonial-modal__solo,
.eti_testimonial-modal__slider .eti_slider__slide {
	margin: 0;
	display: flex;
	align-items: center;
	justify-content: center;
	background: transparent;
}
.eti_testimonial-modal__solo {
	margin-top: var(--eti-space-4, 16px);
}
.eti_testimonial-modal__slider {
	margin-top: var(--eti-space-4, 16px);
}

.eti_testimonial-modal__solo img,
.eti_testimonial-modal__slider .eti_slider__img {
	display: block;
	width: auto;
	height: auto;
	max-width: 100%;
	max-height: 70vh;
	max-height: 70dvh;
	object-fit: contain;
	border-radius: var(--eti-radius-sm, 6px);
}

/* ── Share modal — heading, two platform CTAs, divider, form ── */
.eti_share-modal__close {
	position: absolute;
	top: var(--eti-space-3, 12px);
	right: var(--eti-space-3, 12px);
	z-index: 2;
	width: 36px;
	height: 36px;
	padding: 0;
	border: 0;
	border-radius: var(--eti-radius-full, 9999px);
	background: rgba(255, 255, 255, .9);
	color: var(--eti-color-text-primary, #39472F);
	cursor: pointer;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	box-shadow: var(--eti-shadow-sm);
	transition: background-color var(--eti-transition-fast, .15s ease),
	            color var(--eti-transition-fast, .15s ease);
}
.eti_share-modal__close:hover {
	background: var(--eti-color-text-primary, #39472F);
	color: var(--eti-color-white, #FFFFFF);
}
.eti_share-modal__close svg { width: 16px; height: 16px; }

.eti_share-modal .eti_modal__dialog {
	width: min(640px, calc(100vw - var(--eti-space-8, 32px)));
}

.eti_share-modal__body {
	padding: var(--eti-space-7, 28px) var(--eti-space-7, 28px) var(--eti-space-6, 24px);
}

.eti_share-modal__head {
	margin-bottom: var(--eti-space-5, 20px);
	padding-right: var(--eti-space-8, 32px); /* keep clear of close button */
}
.eti_share-modal__heading {
	font-size: var(--eti-font-size-xl, 1.25rem);
	font-weight: var(--eti-font-weight-semibold, 600);
	color: var(--eti-color-text-primary, #39472F);
	line-height: 1.3;
	margin: 0 0 6px;
}
.eti_share-modal__lead {
	margin: 0;
	color: var(--eti-color-text-muted, #7D7D7D);
	font-size: var(--eti-font-size-sm, .9rem);
	line-height: 1.5;
}

.eti_share-modal__platforms {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
	gap: var(--eti-space-3, 12px);
	margin-bottom: var(--eti-space-5, 20px);
}
.eti_share-modal__platform {
	display: flex;
	align-items: center;
	gap: var(--eti-space-3, 12px);
	padding: var(--eti-space-3, 12px) var(--eti-space-4, 16px);
	border: 1px solid var(--eti-color-border, #D4CEC5);
	border-radius: var(--eti-radius-md, 12px);
	color: var(--eti-color-text-primary, #39472F);
	font-weight: var(--eti-font-weight-medium, 500);
	text-decoration: none;
	transition: transform var(--eti-transition-base, .18s ease),
	            border-color var(--eti-transition-base, .18s ease),
	            box-shadow var(--eti-transition-base, .18s ease);
}
.eti_share-modal__platform:hover {
	transform: translateY(-1px);
	box-shadow: var(--eti-shadow-sm);
}
.eti_share-modal__platform--google:hover   { border-color: #4285F4; }
.eti_share-modal__platform--facebook:hover { border-color: var(--eti-testimonial-facebook, #1877F2); }
.eti_share-modal__platform--facebook .eti_share-modal__platform-icon { color: var(--eti-testimonial-facebook, #1877F2); }
.eti_share-modal__platform-icon svg { width: 100%; height: 100%; max-width: 24px; max-height: 24px; }
.eti_share-modal__platform-icon {
	width: 32px;
	height: 32px;
	flex-shrink: 0;
	display: inline-flex;
	align-items: center;
	justify-content: center;
}
.eti_share-modal__platform-icon svg { width: 24px; height: 24px; }

/* "or write directly" rule */
.eti_share-modal__or {
	display: flex;
	align-items: center;
	gap: var(--eti-space-3, 12px);
	margin: var(--eti-space-5, 20px) 0;
	color: var(--eti-color-text-muted, #7D7D7D);
	font-size: var(--eti-font-size-xs, .8rem);
	text-transform: uppercase;
	letter-spacing: .08em;
}
.eti_share-modal__or::before,
.eti_share-modal__or::after {
	content: "";
	flex: 1;
	height: 1px;
	background: var(--eti-color-border, #D4CEC5);
}
.eti_share-modal__or span { white-space: nowrap; }

/* The form lives inside the modal body — no extra card wrapper. */
.eti_share-modal__body .eti_testimonial-form { gap: var(--eti-space-4, 16px); }

/* ── Masonry wrapper (shortcode + archive) ────────────────────
 *
 * Flex-based masonry. The grid is a flex row of N column
 * wrappers; cards live inside their assigned column. JS
 * (testimonials.js → initMasonry) distributes cards to
 * columns by shortest-first on initial render and on each
 * lazy-load append, so existing cards never shuffle when
 * new ones arrive.
 *
 * Modifier classes pin the desktop column count to a
 * specific value: --cols-1, --cols-2, --cols-4. Default
 * scales 1 → 2 → 3 across breakpoints. The current
 * column count is exposed in `--eti-grid-cols` for the JS
 * to read at any breakpoint.
 * ──────────────────────────────────────────────────────────── */
.eti_testimonials-grid {
	--eti-grid-cols: 1;
	display: flex;
	gap: var(--eti-space-6, 24px);
	align-items: flex-start;
}
.eti_testimonials-grid__col {
	flex: 1 1 0;
	min-width: 0;
	display: flex;
	flex-direction: column;
	gap: var(--eti-space-6, 24px);
}

/* Rebalance "juggle" — when JS is about to re-pour the columns
   on filter change, we briefly dim the grid so the DOM shuffle
   reads as a single intentional animation rather than a flash
   of cards reappearing in new positions. */
.eti_testimonials-grid {
	transition: opacity .18s ease;
}
.eti_testimonials-grid.is-rebalancing {
	opacity: .35;
}
@media (prefers-reduced-motion: reduce) {
	.eti_testimonials-grid { transition: none; }
	.eti_testimonials-grid.is-rebalancing { opacity: 1; }
}

@media (min-width: 700px) {
	.eti_testimonials-grid               { --eti-grid-cols: 2; }
	.eti_testimonials-grid--cols-1       { --eti-grid-cols: 1; }
}
@media (min-width: 1024px) {
	.eti_testimonials-grid               { --eti-grid-cols: 3; }
	.eti_testimonials-grid--cols-1       { --eti-grid-cols: 1; }
	.eti_testimonials-grid--cols-2       { --eti-grid-cols: 2; }
	.eti_testimonials-grid--cols-4       { --eti-grid-cols: 4; }
}

/* ── Star rating (partial-fill) ───────────────────────────────
 *
 * Two stacked rows of identical 5-star polygons. The bg row sits
 * in normal flow and defines the parent's width; the fill row
 * absolute-positions over it, clipped via `width: var(--eti-rating-fill)`
 * (e.g. 94% for a 4.7).
 *
 * Hardening notes:
 *   - Star size is a custom property so the parent can lock its
 *     own width to (5 * size + 4 gaps), guaranteeing the percentage
 *     fill calculates against a known box.
 *   - flex-shrink: 0 on the SVGs so a narrow flex parent (e.g. the
 *     page-header__actions row) can't squish them.
 *   - Inline width/height attrs in the SVG markup mean if any of
 *     the CSS doesn't apply, stars still render at a sensible size.
 * ──────────────────────────────────────────────────────────── */
.eti_rating-stars {
	--eti-star-size: 24px;
	--eti-star-gap:  2px;

	position: relative;
	display: inline-block;
	width:  calc( var(--eti-star-size) * 5 + var(--eti-star-gap) * 4 );
	height: var(--eti-star-size);
	line-height: 1;
}
.eti_rating-stars__bg,
.eti_rating-stars__fill {
	position: absolute;
	top: 0;
	left: 0;
	height: 100%;
	display: flex;
	align-items: center;
	gap: var(--eti-star-gap);
}
.eti_rating-stars__bg  { width: 100%; }
.eti_rating-stars__fill {
	width: var(--eti-rating-fill, 0%);
	overflow: hidden;
	pointer-events: none;
}
.eti_rating-stars__bg svg,
.eti_rating-stars__fill svg {
	width:  var(--eti-star-size);
	height: var(--eti-star-size);
	flex-shrink: 0;
	display: block;
}
.eti_rating-stars__bg svg   { fill: rgba(255, 255, 255, .25); }
.eti_rating-stars__fill svg { fill: var(--eti-testimonial-star, var(--eti-color-warning, #D4A017)); }

/* ── Rating badge in the page header ─────────────────────────
 *
 * Featured "marker" — big number on the left, stars + Google
 * source line on the right. Subtle white-tinted background
 * lifts it off the slate fill so the metric reads as the
 * highlight of the header.
 * ──────────────────────────────────────────────────────────── */
.eti_testimonials-rating-badge {
	display: inline-flex;
	align-items: center;
	gap: var(--eti-space-5, 20px);
	padding: var(--eti-space-4, 16px) var(--eti-space-6, 24px);
	background: rgba(255, 255, 255, .08);
	border: 1px solid rgba(255, 255, 255, .18);
	border-radius: var(--eti-radius-lg, 16px);
	color: var(--eti-color-white, #FFFFFF);
}
.eti_testimonials-rating-badge__number {
	font-size: clamp( 2.5rem, 5vw, 3.25rem );
	font-weight: var(--eti-font-weight-semibold, 600);
	line-height: 1;
	letter-spacing: -0.02em;
	color: var(--eti-color-white, #FFFFFF);
}
.eti_testimonials-rating-badge__detail {
	display: flex;
	flex-direction: column;
	align-items: flex-start;
	gap: 6px;
}
.eti_testimonials-rating-badge__meta {
	display: inline-flex;
	align-items: center;
	gap: 6px;
	font-size: var(--eti-font-size-sm, .875rem);
	color: rgba(255, 255, 255, .85);
	white-space: nowrap;
}
.eti_testimonials-rating-badge__meta svg {
	width: 14px;
	height: 14px;
	flex-shrink: 0;
}

/* Inside the slate header, the design system caps the title at
   24ch which forces "Real reviews from real Escape owners" onto
   two lines on desktop. Loosen the cap for our header so titles
   in this length range stay on one line on wider screens, while
   the clamp() font sizing still keeps shorter viewports tidy. */
.eti_page-header--slate .eti_page-header__title {
	max-width: 42ch;
}

/* ── Toolbar (filter pills + share button) ────────────────── */
.eti_testimonials-toolbar {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: var(--eti-space-2, 8px) var(--eti-space-3, 12px);
	margin-bottom: var(--eti-space-3, 12px);
}
.eti_testimonials-toolbar__share {
	margin-left: auto;
}
/* Match the filter pill dimensions exactly so the two controls
   line up as siblings rather than the share button towering over
   the filter row. Doubled class for specificity over .eti_btn. */
.eti_testimonials-toolbar .eti_testimonials-toolbar__share.eti_btn {
	padding: 7px 14px;
	font-size: var(--eti-font-size-sm, .875rem);
	font-weight: var(--eti-font-weight-medium, 500);
	gap: 6px;
	line-height: 1.2;
	border-radius: var(--eti-radius-full, 9999px);
}
.eti_testimonials-toolbar__share .eti_btn__icon {
	width: 16px;
	height: 16px;
}

/* ── Submission form (used inside the share modal and via the
 *    [eti_testimonials_form] shortcode) ──────────────────── */
.eti_testimonial-form { display: flex; flex-direction: column; gap: var(--eti-space-5, 20px); }
.eti_testimonial-form__heading {
	font-size: var(--eti-font-size-lg, 1.125rem);
	font-weight: var(--eti-font-weight-semibold, 600);
	color: var(--eti-color-text-primary, #39472F);
	line-height: 1.3;
	margin: 0;
}

.eti_testimonial-form__row {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
	gap: var(--eti-space-4, 16px);
}

.eti_testimonial-form__field {
	display: flex;
	flex-direction: column;
	gap: 6px;
}
.eti_testimonial-form__label {
	font-size: var(--eti-font-size-sm, .875rem);
	font-weight: var(--eti-font-weight-medium, 500);
	color: var(--eti-color-text-primary, #39472F);
}
.eti_testimonial-form__hint {
	font-size: var(--eti-font-size-xs, .75rem);
	color: var(--eti-color-text-muted, #7D7D7D);
}
.eti_testimonial-form input[type="text"],
.eti_testimonial-form input[type="email"],
.eti_testimonial-form textarea {
	padding: 10px 12px;
	background: var(--eti-color-bg-page, #FAFAFA);
	border: 1px solid var(--eti-color-border, #D4CEC5);
	border-radius: var(--eti-radius-sm, 6px);
	font-family: inherit;
	font-size: var(--eti-font-size-base, 1rem);
	color: var(--eti-color-text-primary, #39472F);
	transition: border-color var(--eti-transition-fast, .15s ease);
}
.eti_testimonial-form input:focus,
.eti_testimonial-form textarea:focus {
	outline: none;
	border-color: var(--eti-color-forest, #39472F);
}
.eti_testimonial-form textarea { resize: vertical; min-height: 120px; }

/* Star rating — natural left-to-right order. JS toggles
   .is-active on each label as the user hovers / clicks; CSS
   only handles the resting and active appearance. */
.eti_testimonial-form__rating-field { border: 0; padding: 0; margin: 0; }
.eti_testimonial-form__rating {
	display: inline-flex;
	gap: 4px;
	margin-top: 6px;
}
.eti_testimonial-form__rating-star {
	display: inline-flex;
	cursor: pointer;
	line-height: 1;
}
.eti_testimonial-form__rating-star input {
	position: absolute;
	opacity: 0;
	pointer-events: none;
}
.eti_testimonial-form__rating-icon {
	width: 32px;
	height: 32px;
	fill: rgba(0, 0, 0, .15);
	transition: fill var(--eti-transition-fast, .15s ease),
	            transform var(--eti-transition-fast, .1s ease);
}
.eti_testimonial-form__rating-star.is-active .eti_testimonial-form__rating-icon {
	fill: var(--eti-testimonial-star, #D4A017);
}
.eti_testimonial-form__rating-star:active .eti_testimonial-form__rating-icon { transform: scale(.92); }
.eti_testimonial-form__rating-star input:focus-visible + .eti_testimonial-form__rating-icon {
	outline: 2px solid var(--eti-color-brand-accent, #C82127);
	outline-offset: 3px;
	border-radius: 2px;
}

.eti_testimonial-form__hp { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; }

.eti_testimonial-form__notice {
	padding: var(--eti-space-3, 12px) var(--eti-space-4, 16px);
	border-radius: var(--eti-radius-sm, 6px);
	font-size: var(--eti-font-size-sm, .9rem);
}
.eti_testimonial-form__notice--success {
	background: #E5F1E2;
	color: var(--eti-color-forest, #39472F);
	border: 1px solid #B7D4AE;
}
.eti_testimonial-form__notice--error {
	background: #FCE9EA;
	color: #8C181C;
	border: 1px solid #F0B6B9;
}

.eti_testimonial-form__submit { align-self: flex-start; }

/* ── Filter row ───────────────────────────────────────────────
 *
 * Each platform button keeps its brand colour identity in both
 * resting and active states — inactive shows a tinted background
 * so the source is recognisable at a glance, active flips to the
 * solid brand colour with white text.
 * ──────────────────────────────────────────────────────────── */
.eti_testimonials-filter {
	display: inline-flex;
	flex-wrap: wrap;
	gap: var(--eti-space-2, 8px);
}
.eti_testimonials-filter__btn {
	display: inline-flex;
	align-items: center;
	gap: 6px;
	padding: 7px 14px;
	background: var(--eti-color-cream-soft, #F5EFE4);
	border: 1px solid var(--eti-color-border, #D4CEC5);
	border-radius: var(--eti-radius-full, 9999px);
	font: inherit;
	font-size: var(--eti-font-size-sm, .875rem);
	font-weight: var(--eti-font-weight-medium, 500);
	color: var(--eti-color-text-body, #484848);
	cursor: pointer;
	transition: background-color var(--eti-transition-fast, .15s ease),
	            color var(--eti-transition-fast, .15s ease),
	            border-color var(--eti-transition-fast, .15s ease);
}
.eti_testimonials-filter__btn:focus-visible {
	outline: 2px solid var(--eti-color-brand-accent, #C82127);
	outline-offset: 3px;
}
.eti_testimonials-filter__btn-icon {
	display: inline-flex;
	width: 16px;
	height: 16px;
	flex-shrink: 0;
}
.eti_testimonials-filter__btn-icon svg { width: 100%; height: 100%; }

/* Inactive state for every platform pill: clean transparent
   background, neutral border, brand-colour icon. The icon
   carries the platform identity — no need to tint the chip.
   Active state flips to the brand colour fill. */

.eti_testimonials-filter__btn--all:hover {
	border-color: var(--eti-color-forest, #39472F);
	color: var(--eti-color-forest, #39472F);
}
.eti_testimonials-filter__btn--all.is-active {
	background: var(--eti-color-forest, #39472F);
	border-color: var(--eti-color-forest, #39472F);
	color: var(--eti-color-white, #FFFFFF);
}

.eti_testimonials-filter__btn--google:hover {
	border-color: #4285F4;
	color: var(--eti-color-text-primary, #39472F);
}
.eti_testimonials-filter__btn--google.is-active {
	background: var(--eti-color-bg-elevated, #FFFFFF);
	border-color: #4285F4;
	color: var(--eti-color-text-primary, #39472F);
	box-shadow: 0 0 0 1px #4285F4 inset;
}

.eti_testimonials-filter__btn--facebook { color: var(--eti-testimonial-facebook, #1877F2); }
.eti_testimonials-filter__btn--facebook:hover {
	border-color: var(--eti-testimonial-facebook, #1877F2);
}
.eti_testimonials-filter__btn--facebook.is-active {
	background: var(--eti-testimonial-facebook, #1877F2);
	border-color: var(--eti-testimonial-facebook, #1877F2);
	color: var(--eti-color-white, #FFFFFF);
}

.eti_testimonials-filter__btn--email { color: var(--eti-testimonial-email, #39472F); }
.eti_testimonials-filter__btn--email:hover {
	border-color: var(--eti-testimonial-email, #39472F);
}
.eti_testimonials-filter__btn--email.is-active {
	background: var(--eti-testimonial-email, #39472F);
	border-color: var(--eti-testimonial-email, #39472F);
	color: var(--eti-color-white, #FFFFFF);
}

.eti_testimonials-filter__btn--delivery { color: var(--eti-color-signal-red, #C82127); }
.eti_testimonials-filter__btn--delivery:hover {
	border-color: var(--eti-color-signal-red, #C82127);
}
.eti_testimonials-filter__btn--delivery.is-active {
	background: var(--eti-color-signal-red, #C82127);
	border-color: var(--eti-color-signal-red, #C82127);
	color: var(--eti-color-white, #FFFFFF);
}

/* ── Filter dropdown (DS .eti_dropdown component) ─────────────
 *
 * Built on top of the design system's .eti_dropdown so we get
 * open/close, outside-click, escape, and auto-flip for free
 * via data-eti="dropdown". We only add what the DS doesn't:
 *   - the pill-shaped toggle that mirrors the active-pill
 *     treatment for the currently selected source
 *   - per-source icon tinting on each menu row so the source
 *     identity reads at a glance against the slate menu bg
 *
 * Three toolbar states, driven by JS collision detection (see
 * evaluateFilterDisplay in testimonials.js):
 *   1. default        — pills visible, dropdown hidden
 *   2. .is-collapsed  — pills hidden, dropdown visible
 *   3. .is-mini       — also drops the share button label so
 *                       the share button becomes its envelope
 *                       icon only, lining up beside the
 *                       dropdown toggle as a circular icon btn
 */
.eti_testimonials-filter--menu { display: none; }

.eti_testimonials-toolbar.is-collapsed .eti_testimonials-filter--pills { display: none; }
.eti_testimonials-toolbar.is-collapsed .eti_testimonials-filter--menu  { display: inline-flex; }

/* Toggle button — pill-shaped, carries a source modifier so the
   closed state reads "Google is selected" before the user opens
   it. We override the .eti_btn--outline base so the toggle
   matches the filter pills next to it instead of the larger
   default button height. */
.eti_testimonials-filter__toggle.eti_btn {
	gap: 8px;
	padding: 7px 12px 7px 12px;
	background: var(--eti-color-cream-soft, #F5EFE4);
	border: 1px solid var(--eti-color-border, #D4CEC5);
	border-radius: var(--eti-radius-full, 9999px);
	font-size: var(--eti-font-size-sm, .875rem);
	font-weight: var(--eti-font-weight-medium, 500);
	line-height: 1.2;
	color: var(--eti-color-text-body, #484848);
}
.eti_testimonials-filter__toggle.eti_btn:hover {
	border-color: var(--eti-color-forest, #39472F);
}
.eti_testimonials-filter__toggle-icon {
	display: inline-flex;
	width: 16px;
	height: 16px;
	flex-shrink: 0;
}
.eti_testimonials-filter__toggle-icon svg { width: 100%; height: 100%; }
.eti_testimonials-filter__toggle-label { white-space: nowrap; }
.eti_testimonials-filter__toggle-chevron {
	width: 10px;
	height: 7px;
	flex-shrink: 0;
	margin-left: 2px;
	transition: transform var(--eti-transition-fast, .15s ease);
}
.eti_dropdown.is-open .eti_testimonials-filter__toggle-chevron {
	transform: rotate(180deg);
}

/* Toggle source colours — mirror the active-pill treatment.
   Google keeps the multi-colour logo on a white background
   (filling it would clash with the logo); the others get the
   brand-fill treatment. */
.eti_testimonials-filter__toggle--all.eti_btn { color: var(--eti-color-text-primary, #39472F); }
.eti_testimonials-filter__toggle--google.eti_btn {
	background: var(--eti-color-bg-elevated, #FFFFFF);
	border-color: #4285F4;
	color: var(--eti-color-text-primary, #39472F);
	box-shadow: 0 0 0 1px #4285F4 inset;
}
.eti_testimonials-filter__toggle--facebook.eti_btn {
	background: var(--eti-testimonial-facebook, #1877F2);
	border-color: var(--eti-testimonial-facebook, #1877F2);
	color: var(--eti-color-white, #FFFFFF);
}
.eti_testimonials-filter__toggle--email.eti_btn {
	background: var(--eti-testimonial-email, #39472F);
	border-color: var(--eti-testimonial-email, #39472F);
	color: var(--eti-color-white, #FFFFFF);
}
.eti_testimonials-filter__toggle--delivery.eti_btn {
	background: var(--eti-color-signal-red, #C82127);
	border-color: var(--eti-color-signal-red, #C82127);
	color: var(--eti-color-white, #FFFFFF);
}

/* Menu panel — override the DS's slate background for our use.
   The slate-on-cream-page contrast was too dark; a white panel
   with cream-soft hover reads as a natural extension of the
   filter row's pill aesthetic. We keep the DS structure +
   open/close behaviour, just swap the visual treatment. */
.eti_testimonials-filter--menu .eti_dropdown__menu {
	background: var(--eti-color-bg-elevated, #FFFFFF);
	border: 1px solid var(--eti-color-border, #D4CEC5);
	box-shadow: var(--eti-shadow-md, 0 8px 24px rgba(0, 0, 0, .08));
	padding: 6px;
}

.eti_testimonials-filter__option.eti_dropdown__item {
	display: flex;
	align-items: center;
	gap: 10px;
	padding: 8px 14px 8px 10px;
	background: transparent;
	border: 0;
	width: 100%;
	text-align: left;
	cursor: pointer;
	font-family: inherit;
	color: var(--eti-color-text-body, #484848);
}
.eti_testimonials-filter__option.eti_dropdown__item:hover {
	background: var(--eti-color-cream-soft, #F5EFE4);
	color: var(--eti-color-text-primary, #39472F);
}
.eti_testimonials-filter__option.eti_dropdown__item.current-menu-item,
.eti_testimonials-filter__option.eti_dropdown__item.current-menu-item:hover {
	background: var(--eti-color-cream-soft, #F5EFE4);
	color: var(--eti-color-text-primary, #39472F);
	font-weight: var(--eti-font-weight-semibold, 600);
}
.eti_testimonials-filter__option-icon {
	display: inline-flex;
	width: 18px;
	height: 18px;
	flex-shrink: 0;
}
.eti_testimonials-filter__option-icon svg {
	width: 100%;
	height: 100%;
	display: block;
}
/* Per-source colour for the icon — the SVGs use currentColor so
   they pick this up. Text stays neutral on the white panel; the
   icon carries the brand identity at a glance. */
.eti_testimonials-filter__option--all      .eti_testimonials-filter__option-icon { color: var(--eti-color-text-primary, #39472F); }
.eti_testimonials-filter__option--facebook .eti_testimonials-filter__option-icon { color: var(--eti-testimonial-facebook, #1877F2); }
.eti_testimonials-filter__option--email    .eti_testimonials-filter__option-icon { color: var(--eti-testimonial-email, #39472F); }
.eti_testimonials-filter__option--delivery .eti_testimonials-filter__option-icon { color: var(--eti-color-signal-red, #C82127); }

/* Share button — icon-only fallback when the toolbar runs out of
   room even with the dropdown collapsed. Becomes a circular icon
   button matching the filter toggle's height, with the textual
   label hidden but kept accessible (screen-reader-friendly). */
.eti_testimonials-toolbar.is-mini .eti_testimonials-toolbar__share .eti_testimonials-toolbar__share-label {
	position: absolute;
	width: 1px;
	height: 1px;
	padding: 0;
	margin: -1px;
	overflow: hidden;
	clip: rect(0, 0, 0, 0);
	white-space: nowrap;
	border: 0;
}
.eti_testimonials-toolbar.is-mini .eti_testimonials-toolbar__share.eti_btn {
	padding: 0;
	width: 36px;
	height: 36px;
	border-radius: var(--eti-radius-full, 9999px);
	gap: 0;
	justify-content: center;
}
.eti_testimonials-toolbar.is-mini .eti_testimonials-toolbar__share .eti_btn__icon {
	width: 18px;
	height: 18px;
}

/* Visibility toggling — masonry reflows automatically because we
   set display:none rather than visibility:hidden. */
.eti_testimonials-grid.is-filtered-google    .eti_testimonial:not([data-provider="google"])    { display: none; }
.eti_testimonials-grid.is-filtered-facebook  .eti_testimonial:not([data-provider="facebook"])  { display: none; }
.eti_testimonials-grid.is-filtered-email     .eti_testimonial:not([data-provider="email"])     { display: none; }
.eti_testimonials-grid.is-filtered-delivery  .eti_testimonial:not([data-provider="delivery"])  { display: none; }

.eti_testimonials-grid__empty {
	text-align: center;
	color: var(--eti-color-text-muted, #7D7D7D);
	font-size: var(--eti-font-size-sm, .9rem);
	padding: var(--eti-space-8, 32px) 0;
}

/* ── Placement showcase ([eti_placement] shortcode) ─────────
 *
 * Hand-rolled slider — translateX on the track. Each slide is a
 * two-column grid (content + photo) on tablet+, stacked on mobile.
 * Long quotes clamp; "Read full review" reuses the testimonial
 * expand modal via a hidden card embedded in each slide.
 * ──────────────────────────────────────────────────────────── */

.eti_placement-showcase {
	/* Background colour comes from the inline style set by the
	   shortcode. Default to sand if the variable is missing for
	   any reason (e.g. shortcode HTML edited by hand). */
	position: relative;
	background: var(--eti-placement-bg, var(--eti-color-sand, #D4CEC5));
	border-radius: var(--eti-radius-lg, 16px);
	padding: var(--eti-space-9, 36px) var(--eti-space-10, 40px);
	overflow: hidden;
}

/* Title uses the design system's .eti_h1 — keep the local class
   so we can still tune spacing without overriding the type ramp. */
.eti_placement-showcase__title {
	margin: 0 0 var(--eti-space-7, 28px);
}

.eti_placement-showcase__viewport {
	overflow: hidden;
	width: 100%;
}

.eti_placement-showcase__track {
	display: flex;
	transition: transform 420ms cubic-bezier(.22, 1, .36, 1);
	will-change: transform;
}

@media (prefers-reduced-motion: reduce) {
	.eti_placement-showcase__track { transition: none; }
}

.eti_placement-showcase__slide {
	flex: 0 0 100%;
	min-width: 0;
	display: grid;
	/* minmax(0, 1fr) lets the column shrink below the intrinsic
	   image width — without the explicit `0` minimum, an <img> in
	   the column forces the track wider than the viewport and the
	   image appears cropped on the right edge of the section. */
	grid-template-columns: minmax(0, 1fr);
	gap: var(--eti-space-7, 28px);
	align-items: stretch;
}

@media (min-width: 768px) {
	.eti_placement-showcase__slide {
		grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
		gap: var(--eti-space-10, 40px);
		min-height: 360px;
	}
}

/* ── Left column: quote + byline + nav ──────────────────── */
.eti_placement-showcase__content {
	display: flex;
	flex-direction: column;
	justify-content: space-between;
	gap: var(--eti-space-6, 24px);
	min-width: 0;
}

.eti_placement-showcase__quote {
	margin: 0;
	font-size: clamp(1rem, 1.4vw, 1.125rem);
	line-height: 1.6;
	color: var(--eti-color-text-body, #484848);

	/* Clamp visible lines so the showcase keeps a consistent
	   silhouette across testimonials of different lengths. The
	   "Read full review" button below, revealed by JS only when
	   content actually overflows, opens the modal. */
	display: -webkit-box;
	-webkit-line-clamp: 8;
	line-clamp: 8;
	-webkit-box-orient: vertical;
	overflow: hidden;
}

.eti_placement-showcase__quote::before,
.eti_placement-showcase__quote::after {
	font-size: 1.4em;
	line-height: 0;
	color: var(--eti-color-text-muted, #7D7D7D);
}
.eti_placement-showcase__quote::before { content: "\201C"; margin-right: 4px; }
.eti_placement-showcase__quote::after  { content: "\201D"; margin-left: 4px; }

.eti_placement-showcase__expand {
	align-self: flex-start;
	display: inline-flex;
	align-items: center;
	gap: 6px;
	padding: 0;
	background: transparent;
	border: 0;
	font: inherit;
	font-size: var(--eti-font-size-sm, .875rem);
	font-weight: var(--eti-font-weight-medium, 500);
	color: var(--eti-color-brand-secondary, var(--eti-color-slate, #4B6568));
	cursor: pointer;
	margin-top: -8px; /* tuck closer to the clamped quote */
}
.eti_placement-showcase__expand[hidden] { display: none; }
.eti_placement-showcase__expand span { text-decoration: underline; text-underline-offset: 3px; }
.eti_placement-showcase__expand:hover span { text-decoration: none; }
.eti_placement-showcase__expand svg {
	width: 14px;
	height: 14px;
	transition: transform var(--eti-transition-fast, .15s ease);
}
.eti_placement-showcase__expand:hover svg { transform: translateX(2px); }

.eti_placement-showcase__footer {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: var(--eti-space-4, 16px);
	flex-wrap: wrap;
}

.eti_placement-showcase__byline {
	display: inline-flex;
	align-items: center;
	gap: var(--eti-space-3, 12px);
	min-width: 0;
}
.eti_placement-showcase__avatar {
	width: 48px;
	height: 48px;
	flex-shrink: 0;
	border-radius: var(--eti-radius-full, 9999px);
	overflow: hidden;
	background: var(--eti-color-bg-muted, #D9E7E8);
}
.eti_placement-showcase__avatar-img {
	width: 100%;
	height: 100%;
	object-fit: cover;
	display: block;
}
.eti_placement-showcase__name {
	font-weight: var(--eti-font-weight-semibold, 600);
	color: var(--eti-color-text-primary, #39472F);
	white-space: nowrap;
	overflow: hidden;
	text-overflow: ellipsis;
}

.eti_placement-showcase__nav {
	display: inline-flex;
	gap: 8px;
	flex-shrink: 0;
}
.eti_placement-showcase__arrow {
	width: 40px;
	height: 40px;
	padding: 0;
	background: transparent;
	border: 1px solid var(--eti-color-forest, #39472F);
	border-radius: var(--eti-radius-full, 9999px);
	color: var(--eti-color-forest, #39472F);
	cursor: pointer;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	transition: background-color var(--eti-transition-fast, .15s ease),
	            color var(--eti-transition-fast, .15s ease);
}
.eti_placement-showcase__arrow:hover {
	background: var(--eti-color-forest, #39472F);
	color: var(--eti-color-white, #FFFFFF);
}
.eti_placement-showcase__arrow:focus-visible {
	outline: 2px solid var(--eti-color-brand-accent, #C82127);
	outline-offset: 3px;
}
.eti_placement-showcase__arrow svg {
	width: 16px;
	height: 16px;
}

/* ── Right column: photo ────────────────────────────────── */
.eti_placement-showcase__photo {
	background: var(--eti-color-bg-muted, #D9E7E8);
	border-radius: var(--eti-radius-md, 12px);
	overflow: hidden;
	aspect-ratio: 4 / 3;
	min-width: 0; /* belt-and-braces with the grid's minmax(0, 1fr) */
}
@media (min-width: 768px) {
	.eti_placement-showcase__photo {
		aspect-ratio: auto;
		height: 100%;
		min-height: 320px;
	}
}
.eti_placement-showcase__photo img {
	width: 100%;
	height: 100%;
	max-width: 100%;
	object-fit: cover;
	display: block;
}

/* Hidden cards exist purely as the source for the modal clone. */
.eti_placement-showcase__hidden-card { display: none !important; }

/* ── Load more (lazy-load with IntersectionObserver) ─────── */
.eti_testimonials-loadmore {
	display: flex;
	align-items: center;
	justify-content: center;
	min-height: 56px;
	margin-top: var(--eti-space-8, 32px);
}
.eti_testimonials-loadmore.is-done { display: none; }

/* The button is the spinner. While `.is-loading` is on the
   button, the label visually disappears (visibility:hidden so the
   button keeps its width — no jiggle) and the spinner appears
   absolutely centered inside the button bounds. */
.eti_testimonials-loadmore__btn {
	position: relative;
}
.eti_testimonials-loadmore__btn:disabled {
	opacity: 1;            /* override default disabled fade — spinner reads as "busy" */
	cursor: progress;
}
.eti_testimonials-loadmore__spinner {
	display: none;
	width: 16px;
	height: 16px;
	border: 2px solid currentColor;
	border-top-color: transparent;
	border-radius: 50%;
	animation: eti-testimonials-spin 720ms linear infinite;
}
.eti_testimonials-loadmore__btn.is-loading .eti_testimonials-loadmore__btn-label {
	visibility: hidden;
}
.eti_testimonials-loadmore__btn.is-loading .eti_testimonials-loadmore__spinner {
	display: inline-block;
	position: absolute;
	top: 50%;
	left: 50%;
	transform: translate(-50%, -50%);
}
@keyframes eti-testimonials-spin {
	to { transform: translate(-50%, -50%) rotate(360deg); }
}
@media (prefers-reduced-motion: reduce) {
	.eti_testimonials-loadmore__spinner { animation-duration: 1.6s; }
}

/* ── Small-screen tweaks ──────────────────────────────────── */
@media (max-width: 640px) {
	.eti_testimonial { padding: var(--eti-space-5, 20px); }
	.eti_testimonial__avatar { width: 40px; height: 40px; }
	.eti_testimonial__star { width: 16px; height: 16px; }
}
