/* ============================================================================
 * BRIEFLY — TESTIMONIAL SHAPE PACK. Five structurally distinct shapes.
 *
 * ── THE DEFECT THIS ANSWERS ─────────────────────────────────────────────────
 * 23 testimonial/review renderers across 22 themes emit 75 <div>, 37 <p>,
 * 12 <span> — and ONE <blockquote>. Zero <cite>, zero <figure>, zero
 * <figcaption>, zero <q>. Every quote in the suite is an unattributed div.
 *
 * Structurally it is the same story as the heroes: one two-column card grid
 * with an italic quote, repeated 23 times with a different class prefix. The
 * shape does not change when the content changes — three quotes get a grid
 * built for six, forty get the same grid, and a review section for a law firm
 * looks identical to one for a pet groomer.
 *
 * ── THE SEMANTIC HALF IS THE BIGGER WIN ─────────────────────────────────────
 * A quote in a <div> is a paragraph that happens to have quotation marks. A
 * quote in <figure><blockquote>…<figcaption>…<cite> is a quotation WITH AN
 * ATTRIBUTED SOURCE, which is what a screen reader announces, what a browser
 * reader mode extracts, and what a reviewer sees when they open the inspector.
 * It costs nothing and it is the difference between markup that was authored
 * and markup that was assembled.
 * ========================================================================== */

/* ── SHARED QUOTE GROUND ─────────────────────────────────────────────────── */

.bfy-quotes { padding: var(--bfy-sect, clamp(3rem, 5vw, 4.5rem)) var(--bfy-gut, clamp(1.5rem, 4vw, 3rem)); box-sizing: border-box; }
.bfy-quotes__inner { max-width: var(--bfy-head-measure-wide, 1160px); margin: 0 auto; }

/* <figure> carries default margins in every browser; the shape sets spacing. */
.bfy-quote { margin: 0; min-width: 0; }
.bfy-quote blockquote { margin: 0; }

.bfy-quote__text {
	margin: 0;
	font-family: var(--bfy-quote-font, inherit);
	font-size: var(--bfy-quote-size, clamp(1rem, 1.2vw, 1.08rem));
	line-height: var(--bfy-quote-lh, 1.6);
	color: var(--bfy-quote-ink, var(--wp--preset--color--foreground, #16181D));
	text-wrap: pretty;
}

.bfy-quote__cap {
	display: flex;
	align-items: center;
	gap: 0.7rem;
	margin-top: var(--bfy-quote-cap-mt, 1.1rem);
}
.bfy-quote__name {
	font-size: var(--bfy-quote-name-size, 0.9rem);
	font-weight: 600;
	color: var(--bfy-quote-ink, var(--wp--preset--color--foreground, #16181D));
}
/* <cite> is italic by default in every UA, which fights an already-italic
   quote and reads as emphasis rather than attribution. */
.bfy-quote__src {
	display: block;
	font-style: normal;
	font-size: var(--bfy-quote-src-size, 0.82rem);
	color: var(--bfy-quote-src-ink, var(--wp--preset--color--foreground, #55606B));
}
.bfy-quote__avatar {
	flex: 0 0 auto;
	width: var(--bfy-quote-avatar, 44px);
	height: var(--bfy-quote-avatar, 44px);
	border-radius: 50%;
	overflow: hidden;
	background: var(--bfy-quote-avatar-bg, rgba(18, 24, 28, 0.06));
}
.bfy-quote__avatar img { width: 100%; height: 100%; object-fit: cover; display: block; }

/* Rating. Its own ink token, NOT the raw brand accent: the remaining contrast
   failures in this suite are dominated by accent-as-small-text — star rows,
   "01" numerals, footer links — scoring 2.9-3.4 against their canvas. A five
   glyph row at 0.9rem is exactly that case, so it gets a colour chosen to
   carry at small size rather than one chosen to look like the brand. */
.bfy-quote__rating {
	display: block;
	margin-bottom: 0.7rem;
	font-size: var(--bfy-rating-size, 0.9rem);
	letter-spacing: 0.12em;
	color: var(--bfy-rating-ink, var(--wp--preset--color--foreground, #16181D));
}


/* ── 1. GRID ─────────────────────────────────────────────────────────────────
 * The shape that already exists, kept — because a card grid IS the right answer
 * when there are six-plus short quotes and no single one deserves the stage.
 * Retained, tokenised, and given real semantics rather than replaced.
 *
 * Track count comes from a custom property so render-guards.css can collapse it
 * and the :has() balance rule can stop one card being orphaned on a last row.
 * -------------------------------------------------------------------------- */

.bfy-quotes--grid .bfy-quotes__list {
	display: grid;
	grid-template-columns: var(--bfy-quotes-cols, repeat(auto-fit, minmax(min(100%, 300px), 1fr)));
	gap: var(--bfy-quotes-gap, clamp(1rem, 2vw, 1.5rem));
}
.bfy-quotes--grid .bfy-quote {
	padding: var(--bfy-quote-pad, clamp(1.25rem, 2.2vw, 1.75rem));
	background: var(--bfy-quote-bg, var(--wp--preset--color--background-alt, #FFFFFF));
	border: 1px solid var(--bfy-quote-border, rgba(18, 24, 28, 0.10));
	border-radius: var(--bfy-quote-radius, 14px);
	display: flex;
	flex-direction: column;
}
/* Caption pinned to the bottom so names line up across cards of unequal length.
   Ragged attribution lines are the specific detail that makes a card grid look
   generated — every card is a different height and nothing aligns. */
.bfy-quotes--grid .bfy-quote__cap { margin-top: auto; padding-top: 1.1rem; }


/* ── 2. SPOTLIGHT ────────────────────────────────────────────────────────────
 * One quote, given the whole section, with the portrait bleeding past the
 * container edge.
 *
 * DELIBERATELY NOT A ROTATOR. Every instinct says "carousel of quotes" here,
 * and this project has already learned that lesson: the Hub's JS sliders were
 * repeatedly reported broken, and the Firstborn before/after was rebuilt as a
 * CSS-only wipe on the principle that AN EFFECT WITH NOTHING TO INITIALISE
 * CANNOT FAIL. A rotator also hides four of five quotes from anyone who does
 * not wait, and from every crawler.
 *
 * So this shape shows ONE quote and the registry restricts it to content with
 * one or two. Volume goes to the grid, the rail or the wall — which is the
 * entire point of having five shapes.
 * -------------------------------------------------------------------------- */

.bfy-quotes--spotlight .bfy-quotes__inner {
	display: grid;
	grid-template-columns: var(--bfy-spot-cols, minmax(0, 1fr) minmax(0, 0.72fr));
	gap: var(--bfy-spot-gap, clamp(1.5rem, 4vw, 3.5rem));
	align-items: center;
}
.bfy-quotes--spotlight .bfy-quote__text {
	font-size: var(--bfy-spot-size, clamp(1.4rem, 2.8vw, 2.1rem));
	line-height: 1.3;
	letter-spacing: -0.01em;
	text-wrap: balance;
}
/* The opening mark is set as a large glyph behind the text rather than inline,
   so the quote's first line still starts on the measure instead of being
   pushed in by punctuation. */
.bfy-quotes--spotlight .bfy-quote { position: relative; }
.bfy-quotes--spotlight .bfy-quote::before {
	content: "\201C";
	position: absolute;
	top: var(--bfy-spot-mark-y, -0.45em);
	left: var(--bfy-spot-mark-x, -0.18em);
	font-size: var(--bfy-spot-mark, 7rem);
	line-height: 1;
	color: var(--bfy-spot-mark-ink, rgba(18, 24, 28, 0.07));
	pointer-events: none;
}
.bfy-quotes--spotlight .bfy-quote > * { position: relative; }
.bfy-quotes--spotlight .bfy-quotes__portrait {
	aspect-ratio: var(--bfy-spot-ratio, 3 / 4);
	overflow: hidden;
	border-radius: var(--bfy-quote-radius, 14px);
	/* Runs past the container edge. The asymmetry is the signature. */
	margin-right: var(--bfy-spot-bleed, -6%);
}
.bfy-quotes--spotlight .bfy-quotes__portrait img { width: 100%; height: 100%; object-fit: cover; display: block; }
.bfy-quotes--spotlight .bfy-quote__cap { margin-top: 1.75rem; }


/* ── 3. RAIL ─────────────────────────────────────────────────────────────────
 * A horizontal scroll-snap strip of avatar + quote pairs.
 *
 * Solves the problem the card grid cannot: it does not care whether there are
 * five quotes or fifty, so it never orphans one on a last row and never needs a
 * balance rule. It also reads as a continuing set rather than a complete one,
 * which is the honest impression when a business has more reviews than fit.
 * -------------------------------------------------------------------------- */

.bfy-quotes--rail .bfy-quotes__list {
	display: grid;
	grid-auto-flow: column;
	grid-auto-columns: var(--bfy-rail-w, clamp(260px, 32vw, 360px));
	gap: var(--bfy-quotes-gap, clamp(1rem, 2vw, 1.5rem));
	overflow-x: auto;
	scroll-snap-type: x mandatory;
	scroll-padding-left: var(--bfy-gut, clamp(1.5rem, 4vw, 3rem));
	padding-bottom: 0.5rem;
	margin-right: var(--bfy-rail-bleed, calc(50% - 50vw));
	padding-right: var(--bfy-gut, clamp(1.5rem, 4vw, 3rem));
	scrollbar-width: thin;
	overscroll-behavior-x: contain;
}
.bfy-quotes--rail .bfy-quote {
	scroll-snap-align: start;
	padding: var(--bfy-quote-pad, clamp(1.25rem, 2.2vw, 1.75rem));
	background: var(--bfy-quote-bg, var(--wp--preset--color--background-alt, #FFFFFF));
	border: 1px solid var(--bfy-quote-border, rgba(18, 24, 28, 0.10));
	border-radius: var(--bfy-quote-radius, 14px);
	display: flex;
	flex-direction: column;
}
.bfy-quotes--rail .bfy-quote__cap { margin-top: auto; padding-top: 1.1rem; }
.bfy-quotes--rail .bfy-quotes__list:focus-visible {
	outline: 3px solid var(--wp--preset--color--primary, currentColor);
	outline-offset: 4px;
}


/* ── 4. MARGINALIA ───────────────────────────────────────────────────────────
 * Quotes set in the outer margin beside running copy, the way a printed page
 * carries a pull-quote — not stacked in cards below a heading.
 *
 * This is the shape that makes a page look TYPESET. It is also the only one
 * here that integrates social proof INTO an argument rather than parking it in
 * its own band, which is what a real editorial designer does and what no page
 * builder default has ever done.
 *
 * Built on grid-template-areas — of which the shipped suite contains zero.
 * -------------------------------------------------------------------------- */

.bfy-quotes--marginalia .bfy-quotes__inner {
	display: grid;
	grid-template-columns: var(--bfy-marg-cols, minmax(0, 1fr) minmax(0, 0.62fr));
	column-gap: var(--bfy-marg-gap, clamp(2rem, 5vw, 4rem));
	row-gap: var(--bfy-marg-row, clamp(1.5rem, 3vw, 2.5rem));
	grid-template-areas:
		"lede  aside"
		"body  aside";
	align-items: start;
	max-width: var(--bfy-marg-w, 1080px);
}
.bfy-quotes--marginalia .bfy-quotes__lede  { grid-area: lede; margin: 0; }
.bfy-quotes--marginalia .bfy-quotes__body  { grid-area: body; margin: 0; max-width: 62ch; }
.bfy-quotes--marginalia .bfy-quotes__aside { grid-area: aside; display: grid; gap: var(--bfy-marg-row, clamp(1.5rem, 3vw, 2.5rem)); }

/* A hairline on the inner edge, not a card. The rule is what makes it read as
   margin notes rather than as a sidebar of boxes. */
.bfy-quotes--marginalia .bfy-quote {
	padding-left: var(--bfy-marg-pad, 1.25rem);
	border-left: 2px solid var(--bfy-marg-rule, var(--wp--preset--color--primary, #0F4C5C));
}
.bfy-quotes--marginalia .bfy-quote__text {
	font-size: var(--bfy-marg-size, clamp(1.06rem, 1.4vw, 1.25rem));
	line-height: 1.45;
	text-wrap: balance;
}
.bfy-quotes--marginalia .bfy-quote__cap { margin-top: 0.85rem; }


/* ── 5. WALL ─────────────────────────────────────────────────────────────────
 * Dense multi-column masonry of short quotes at mixed sizes. For volume, where
 * the ARGUMENT is "there are a lot of these".
 *
 * CSS columns rather than a grid, deliberately: a masonry grid needs either JS
 * or `grid-template-rows: masonry`, which is not shipping broadly yet. Columns
 * flow top-to-bottom per column, which reorders reading — acceptable here and
 * ONLY here, because each quote is independent and none refers to another.
 * That is a content property, not a styling one, so the registry restricts this
 * shape to standalone quotes.
 * -------------------------------------------------------------------------- */

.bfy-quotes--wall .bfy-quotes__list {
	column-count: var(--bfy-wall-cols, 3);
	column-gap: var(--bfy-quotes-gap, clamp(1rem, 2vw, 1.5rem));
}
.bfy-quotes--wall .bfy-quote {
	break-inside: avoid;
	/* Older engines honour page-break-inside where break-inside is ignored;
	   without it a quote splits across a column boundary mid-sentence. */
	page-break-inside: avoid;
	margin-bottom: var(--bfy-quotes-gap, clamp(1rem, 2vw, 1.5rem));
	padding: var(--bfy-wall-pad, 1.15rem 1.35rem);
	background: var(--bfy-quote-bg, var(--wp--preset--color--background-alt, #FFFFFF));
	border: 1px solid var(--bfy-quote-border, rgba(18, 24, 28, 0.10));
	border-radius: var(--bfy-quote-radius, 14px);
	display: inline-block;
	width: 100%;
	box-sizing: border-box;
}
/* Mixed weight across the wall, so it reads as a collection rather than a table.
   Applied by position, not by content, so it never depends on quote length. */
.bfy-quotes--wall .bfy-quote:nth-child(4n + 1) .bfy-quote__text { font-size: var(--bfy-wall-lg, 1.14rem); }
.bfy-quotes--wall .bfy-quote:nth-child(6n + 3) .bfy-quote__text { font-size: var(--bfy-wall-lg, 1.14rem); }


/* ── RESPONSIVE ──────────────────────────────────────────────────────────────
 * 760px, matching .ewpk-grid, so a page never reflows at two different widths.
 * As with the heroes, the multi-track shapes UNDO their structure rather than
 * compress it — a -6% portrait bleed on a phone is a photograph hanging off the
 * screen, and a three-column wall is three unreadable ribbons.
 * -------------------------------------------------------------------------- */

@media (max-width: 1024px) {
	.bfy-quotes--wall .bfy-quotes__list { column-count: var(--bfy-wall-cols-md, 2); }
}

@media (max-width: 760px) {
	.bfy-quotes--spotlight .bfy-quotes__inner { grid-template-columns: 1fr; }
	.bfy-quotes--spotlight .bfy-quotes__portrait { margin-right: 0; aspect-ratio: 4 / 3; order: -1; }
	.bfy-quotes--spotlight .bfy-quote::before { font-size: 4.5rem; top: -0.35em; left: -0.05em; }

	.bfy-quotes--marginalia .bfy-quotes__inner {
		grid-template-columns: 1fr;
		grid-template-areas: "lede" "body" "aside";
	}

	.bfy-quotes--wall .bfy-quotes__list { column-count: 1; }
}


/* ── QUALITY FLOOR ───────────────────────────────────────────────────────── */

@media (prefers-reduced-motion: reduce) {
	.bfy-quotes__list { scroll-behavior: auto; }
	.bfy-quotes, .bfy-quotes * { animation: none !important; transition: none !important; }
}

@media (forced-colors: active) {
	.bfy-quote { border-color: CanvasText; }
	.bfy-quotes--marginalia .bfy-quote { border-left-color: CanvasText; }
	.bfy-quotes--spotlight .bfy-quote::before { color: GrayText; }
}

/* Reader mode and print both want the quote, not the furniture. */
@media print {
	.bfy-quotes--rail .bfy-quotes__list { display: block; overflow: visible; }
	.bfy-quotes--wall .bfy-quotes__list { column-count: 1; }
	.bfy-quotes--spotlight .bfy-quote::before { display: none; }
}
