/*
 * Homepage-specific layout (Phase 3C — docs/HOMEPAGE-IMPLEMENTATION.md).
 * Every product rail reuses .bholats-product-grid / .bholats-card /
 * .bholats-category-card / .bholats-brand-card / .bholats-feature-card as-is
 * — this file only covers section-level layout that doesn't belong in the
 * general component library (it's specific to how the homepage assembles
 * those components, not a new reusable primitive).
 */

/* --- Homepage Hero (promo carousel) ---
   docs/HOMEPAGE-HERO-CAROUSEL-MERGE.md. The promotional carousel below is
   now the homepage hero — the previous text hero ("Complete IT Solutions
   Under One Roof" + body + CTAs, in its own .bholats-hero section with a
   layered-gradient background) has been removed entirely, not hidden. Its
   CTA buttons were moved (not duplicated) into .bholats-home-promo__actions
   below; its heading text lives on only as a visually-hidden <h1> (markup,
   not CSS — see template-parts/home/promo-banners.php) so the page still
   has exactly one real H1 without a visible text banner reappearing above
   the carousel.

   The extra top padding this section used to carry at wider viewports
   (docs/HOMEPAGE-IMPROVEMENT-PHASE-1.md) matched the old TEXT hero's own
   "confident opening statement" breathing room — sized for a large heading
   + body + CTA block, not for an image carousel. Once the carousel became
   the full-bleed hero, that same gap just read as dead whitespace above it
   (measured live: 120px at 1440px, 56px at 390px, before .bholats-main's
   own sitewide top padding is even added). Zeroed out here instead of
   left in place: .bholats-main's own padding-top (base.css, applies above
   every page's content, not hero-specific) already supplies a small,
   consistent, intentional-looking gap on its own — nothing further is
   needed above a full-width image. padding-bottom is untouched (still the
   .bholats-section default), so spacing below the carousel/CTA row, before
   Shop by Category, is unaffected. */
.bholats-home-promo {
	padding-top: 0;
}

/* --- Promo Banner Carousel ---
   Two client-supplied service banners (docs/HOMEPAGE-PROMO-CAROUSEL.md),
   the homepage hero itself, first thing below the header.

   Full-bleed (docs/HOMEPAGE-IMPROVEMENT-PHASE-1.md), reversing the earlier
   "contained card" decision on explicit client request: .bholats-promo-
   carousel is now a sibling of .bholats-container in the markup (see
   template-parts/home/promo-banners.php), not nested inside it — the same
   structural pattern .bholats-brand-marquee already uses further down this
   file. That alone was NOT enough to reach the client's actual requirement
   though: .bholats-main itself (base.css, the <main> landmark every
   homepage section lives inside, "page-shell only, not a component") has
   its own `max-width: var(--container-max); margin: 0 auto; padding: ...`
   — a second, outer constraint .bholats-brand-marquee has always lived
   inside too (confirmed live: that marquee is edge-to-edge relative to
   .bholats-container's own padding, but still bounded by .bholats-main's
   max-width, not truly touching the browser viewport edge). The client's
   requirement here is stricter — genuinely flush with the browser window —
   so the carousel additionally needs to break out of .bholats-main itself.
   Moving the template call outside <main> in front-page.php was ruled out:
   that would pull the homepage's actual hero content out of the page's
   main-content landmark, a real accessibility/semantic regression for a
   layout-only requirement. The standard, non-fragile CSS answer for
   "full-bleed content inside a semantically-necessary constrained
   ancestor" is the calc(50% - 50vw) breakout below — width:100vw would
   overflow by the scrollbar's own width in browsers where vw includes it;
   overflow-x: hidden on this element only (not body-wide) is the
   accepted, standard pairing for that specific sub-pixel/scrollbar case,
   not a fix concealing an unrelated structural bug.

   Radius and shadow were removed from the viewport for this: rounded
   corners or a floating-card shadow on an element that touches both
   viewport edges would show as a visible gap/glitch right at the edge
   rather than read as deliberate, so a flat, borderless treatment is the
   correct look for a genuinely edge-to-edge hero image, not an oversight.

   One slide visible at a time via absolute positioning + opacity crossfade;
   assets/js/promo-banner-carousel.js toggles --active plus aria-hidden/
   inert/tabindex on the inactive slides. aspect-ratio on the viewport
   reserves the exact space up front (the real 1600x533 supplied artwork
   ratio, both banners share it) so there's no layout shift while the first
   slide's image loads, and — since the container's own box ratio always
   exactly matches the image's native ratio, at any viewport width — the
   existing `object-fit: cover` below never actually needs to crop anything;
   cover only crops when the container's ratio differs from the image's. */

.bholats-promo-carousel {
	position: relative;
	width: 100vw;
	margin-left: calc(50% - 50vw);
	margin-right: calc(50% - 50vw);
	overflow-x: hidden;
}

.bholats-promo-carousel__viewport {
	position: relative;
	aspect-ratio: 1600 / 533;
	overflow: hidden;
	background: var(--color-surface-sunken);
}

/* Dedicated mobile artwork (docs/HOMEPAGE-IMPROVEMENT-PHASE-1.md) is a
   taller, separately-composed 1448×1086 (4:3) image, not a crop of the
   desktop banner — see promo-banners.php's <picture>/<source> and
   homepage-config.php's image_mobile. The viewport's own aspect-ratio has
   to switch to match it below 768px (the theme's existing mobile/tablet
   boundary), otherwise the container would keep forcing the desktop 3:1
   box and object-fit: cover would crop the taller mobile art down to a
   thin strip again — exactly what this artwork exists to avoid. 768px and
   up is untouched, so desktop/tablet keep the exact approved 3:1 hero. */
@media (max-width: 767px) {
	.bholats-promo-carousel__viewport {
		aspect-ratio: 1448 / 1086;
	}
}

.bholats-promo-carousel__slide {
	position: absolute;
	inset: 0;
	opacity: 0;
	pointer-events: none;
	transition: opacity var(--duration-slow) var(--ease-standard);
}

.bholats-promo-carousel__slide--active {
	opacity: 1;
	pointer-events: auto;
}

.bholats-promo-carousel__link {
	display: block;
	width: 100%;
	height: 100%;
}

/* <picture> defaults to display:inline, sized to its <img>'s own rendered
   size — without this it wouldn't stretch to fill .__link/.__slide the way
   the old bare <img> did, and the 100%/cover rule below would have nothing
   correctly-sized to fill. */
.bholats-promo-carousel__slide picture {
	display: block;
	width: 100%;
	height: 100%;
}

.bholats-promo-carousel__slide img {
	display: block;
	width: 100%;
	height: 100%;
	object-fit: cover;
}

/* Circular, floating over the image — overrides two .bholats-btn/--icon
   defaults that don't suit that context: the square radius (buttons.css)
   and the hover lift's translateY(-1px) (base .bholats-btn:hover), which
   would otherwise replace this button's own translateY(-50%) vertical-
   centering transform rather than combine with it, knocking it off-center
   on hover. Background/border hover feedback from .bholats-btn--icon:hover
   is untouched. Same specificity as those buttons.css rules (one class
   each); this file loads after buttons.css in the enqueue chain, so source
   order alone would already decide it, but the override is written
   explicitly here so it doesn't silently depend on load order. */
.bholats-promo-carousel__arrow {
	position: absolute;
	top: 50%;
	transform: translateY(-50%);
	z-index: var(--z-raised);
	border-radius: var(--radius-full);
}

.bholats-promo-carousel__arrow:hover {
	transform: translateY(-50%);
}

.bholats-promo-carousel__arrow--prev { left: var(--space-3); }
.bholats-promo-carousel__arrow--next { right: var(--space-3); }

/* Mobile-only vertical reposition (docs/HOMEPAGE-IMPROVEMENT-PHASE-1.md):
   below 768px the arrows sit on the taller dedicated mobile artwork, where
   a true 50% vertical center lands squarely on the body-copy line on both
   banners. 75% was chosen from the actual pixel content of both mobile
   images, not guessed: both banners share the same layout grid, and both
   have a genuinely empty band between their headline/body/badge block and
   the bottom trust-icon strip — measured at ~70%-80% of the image height
   on both. The 44px control is itself taller than that gap (~15% of image
   height vs. a ~10% gap), so some overlap into one edge or the other is
   unavoidable at this control size; 75% is the gap's own midpoint, which
   splits that unavoidable overlap evenly rather than biasing into either
   the badge above or the icon strip below, and was confirmed against real
   screenshots of both slides (not just this math) before picking it over
   the other candidates tested (62/68/72/74/76/80%). On the right, this
   same height lands on plain shirt/desk background on both banners, clear
   of each one's headline, body copy, badge, face, and "BHOLAT'S IT WORLD"
   mark. Desktop/tablet (768px+) keep the original top: 50% untouched. */
@media (max-width: 767px) {
	.bholats-promo-carousel__arrow {
		top: 75%;
	}
}

.bholats-promo-carousel__dots {
	display: flex;
	justify-content: center;
	gap: var(--space-2);
	margin-top: var(--space-4);
}

.bholats-promo-carousel__dot {
	width: 10px;
	height: 10px;
	padding: 0;
	border: 0;
	border-radius: var(--radius-full);
	background: var(--color-brand-blue);
	opacity: 0.35;
	transform: scale(0.85);
	transition: opacity var(--duration-base) var(--ease-standard), transform var(--duration-base) var(--ease-standard);
	cursor: pointer;
}

.bholats-promo-carousel__dot--active {
	opacity: 1;
	transform: scale(1);
}

@media (prefers-reduced-motion: reduce) {
	.bholats-promo-carousel__slide,
	.bholats-promo-carousel__dot {
		transition: none;
	}
}

/* --- Hero CTA row (moved from the old .bholats-hero__actions, not
   duplicated — same .bholats-btn markup, same destinations) ---
   Sits directly under the carousel, inside the same section/container so
   it reads as part of one hero unit rather than a separate block. */
.bholats-home-promo__actions {
	display: flex;
	flex-wrap: wrap;
	gap: var(--space-3);
	margin-top: var(--space-6);
}

/* --- Shop by Category --- */

.bholats-home-category-grid {
	display: grid;
	grid-template-columns: repeat(2, 1fr);
	gap: var(--space-4);
}

@media (min-width: 480px) {
	.bholats-home-category-grid { grid-template-columns: repeat(3, 1fr); }
}

@media (min-width: 768px) {
	.bholats-home-category-grid { grid-template-columns: repeat(5, 1fr); }
}

/* >=1024px switches from a fixed column count to a wrapping flex row: CSS
   Grid has no native way to center a ragged last row (repeat(N, 1fr) either
   stretches a short final row into oversized cards, or leaves it left-aligned
   with a gap) — Flexbox's per-line justify-content does. A fixed flex-basis
   (not a percentage) means the number of cards per row is whatever actually
   fits, so this adapts automatically as top-level categories are added or
   removed — nothing here needs to change. flex-shrink is intentionally 0: a
   slight under-fill on the last partial row should stay each card's normal
   size and simply center with visible slack, not shrink to disguise it.
   Breakpoint moved down from 1280px to 1024px, and card size raised from an
   initial 150px to 175px, together as one change: the previous version had
   this rule start at 1280px while the grid-of-5 rule below still governed
   1024px, and 1024px's grid-derived card happened to be LARGER (173px) than
   1280px+'s fixed 150px card — the section visibly shrank as the viewport
   grew from 1024 to 1280px, which reads as a bug, not a responsive choice.
   Starting the SAME 175px card at 1024px instead removes that inversion
   entirely: card size never decreases anywhere in the 1024px-and-up range,
   only the column count increases as more width becomes available.

   175px itself was chosen by rendering the real 12-category set with real
   category photography at 150/175/185/195/205px against this section's
   actual available content width at each target viewport — the width inside
   .bholats-container's own 32px inline padding, not that container's own
   (larger) border-box width, which a first pass at this measurement
   conflated: 1440px and 1366px share 1224px of available width (the
   container hits its own max-width by 1366px already), 1280px has 1184px,
   1024px has 928px. 175px is the largest of the tested sizes that lands a
   clean, centered 6+6 split at ALL THREE of 1440/1366/1280px with no
   column-count change between them — 185px looks equally good at 1440/1366
   but drops to only 5 per row at 1280px specifically (a reflow right at a
   boundary two of this project's named target widths sit on either side of),
   and 195px/205px fit only 5 per row everywhere, three rows for 12 items.
   At 1024px, 175px cards land 4+4+4 — three even rows, not a sparse
   trailing one — and are still sized identically to 1280px+, never smaller.
   .bholats-category-card__media/img are untouched — their sizing is already
   a percentage of the card's own content width (cards.css), so they scale up
   proportionally for free; the card-size increase alone was enough to make
   the category photography read as prominent, without needing to touch that
   82% figure or the card's padding. */
@media (min-width: 1024px) {
	.bholats-home-category-grid {
		display: flex;
		flex-wrap: wrap;
		justify-content: center;
	}

	.bholats-home-category-grid > .bholats-category-card {
		flex: 0 0 175px;
	}
}

/* --- Featured Brands: logo marquee ---
   Replaces the earlier static text-card grid (Phase 3C). Full-bleed —
   .bholats-brand-marquee is a sibling of .bholats-container inside the
   <section>, not nested in it, so it spans edge-to-edge while the heading/
   note above stay aligned to the normal container width. Section feels
   flatter/lighter than the card grids above it on purpose: no card
   surface/border/shadow per item, just logos directly on a plain
   background (--color-surface, per the brief's "white or very light
   neutral background"). */

.bholats-home-brands__note {
	color: var(--color-text-secondary);
	margin: calc(var(--space-6) * -1) 0 var(--space-6);
}

.bholats-brand-marquee {
	background: var(--color-surface);
	padding-block: var(--space-6);
}

.bholats-brand-marquee__viewport {
	overflow: hidden;
	/* Soft fade at both edges so the strip reads as continuous motion
	   rather than a hard-clipped window — pure CSS mask, no extra markup. */
	-webkit-mask-image: linear-gradient(to right, transparent, black 6%, black 94%, transparent);
	mask-image: linear-gradient(to right, transparent, black 6%, black 94%, transparent);
}

.bholats-brand-marquee__track {
	display: flex;
	width: max-content;
	animation: bholats-brand-marquee-scroll 40s linear infinite;
}

.bholats-brand-marquee:hover .bholats-brand-marquee__track,
.bholats-brand-marquee:focus-within .bholats-brand-marquee__track {
	animation-play-state: paused;
}

/* Two identical <ul> sets sit side by side (track width = 200% of one set).
   Animating exactly -50% moves the whole track by precisely one set's
   width, so the moment the loop restarts at 0%, set two is already sitting
   exactly where set one started — no jump, no gap, regardless of actual
   rendered width at any breakpoint/font size. */
@keyframes bholats-brand-marquee-scroll {
	from { transform: translateX(0); }
	to { transform: translateX(-50%); }
}

.bholats-brand-marquee__set {
	display: flex;
	align-items: center;
	list-style: none;
	margin: 0;
	padding: 0;
	flex-shrink: 0;
}

.bholats-brand-marquee__item {
	display: flex;
	align-items: center;
	justify-content: center;
	height: 56px;
	padding-inline: var(--space-8);
	opacity: 0.72;
	transition: opacity var(--duration-base) var(--ease-standard);
}

.bholats-brand-marquee:hover .bholats-brand-marquee__item,
.bholats-brand-marquee:focus-within .bholats-brand-marquee__item {
	opacity: 1;
}

/* Real logo path — height normalised, width intrinsic (never stretched/
   distorted), grayscale by default to keep 34 different brands visually
   consistent as one calm strip (brief: "monochrome... acceptable if it
   improves consistency"), full colour on hover/focus to reward a closer
   look. Same treatment .bholats-brand-card__logo already uses elsewhere
   (cards.css) — reused here for visual consistency, not reinvented.
   max-width 280px comfortably covers ~28 of the 34 real logos at their
   natural aspect ratio without ever engaging (measured against every
   installed file's real intrinsic ratio before picking this number) — it
   exists only as a backstop against a hypothetical future asset with an
   extreme ratio, not as the thing doing the sizing work day to day. */
.bholats-brand-marquee__logo {
	height: 100%;
	width: auto;
	max-width: 280px;
	object-fit: contain;
	filter: grayscale(1);
	transition: filter var(--duration-base) var(--ease-standard);
}

/* A handful of brands' own real logos are genuinely, unusually wide
   wordmarks (measured: Mercusys 10.1:1, SanDisk 9.9:1, Gigabyte 7.6:1,
   ESET 6.9:1, Hikvision 6.8:1, Samsung 5.6:1 — all clear outliers against
   the rest of the set, which clusters under 5:1). Capping them at the
   general 280px would letterbox them noticeably shorter than every other
   logo (contain still prevents distortion, but shrinks them to fit), so
   they get one shared, wider allowance instead — a single exception tier,
   not a bespoke value per brand. */
.bholats-brand-marquee__logo--wide {
	max-width: 380px;
}

.bholats-brand-marquee:hover .bholats-brand-marquee__logo,
.bholats-brand-marquee:focus-within .bholats-brand-marquee__logo {
	filter: grayscale(0);
}

/* Epson/Linksys/SanDisk/AMD: each brand's own official file is a plain
   white mark meant for a dark header — confirmed by inspecting each file's
   actual fill colour, not assumed. invert() flips white->near-black purely
   as a display filter so it's visible against this marquee's light
   background; the source files are untouched. These are already
   effectively monochrome, so grayscale() has no visible effect on them —
   invert() alone covers both the resting and hover state. */
.bholats-brand-marquee__logo--invert {
	filter: invert(1);
}

.bholats-brand-marquee:hover .bholats-brand-marquee__logo--invert,
.bholats-brand-marquee:focus-within .bholats-brand-marquee__logo--invert {
	filter: invert(1);
}

/* Placeholder path — Acer and MSI only (no official source could be
   obtained for either — see assets/images/brands/README.md). Deliberately
   plain/neutral rather than styled to imitate any brand's real visual
   identity. Sized close to the item's own height (56px) so it doesn't read
   as visually smaller than the real logo images sitting next to it in the
   strip — a fixed small font-size here was the direct cause of the
   "Acer/MSI look tiny" report, since every real logo fills close to the
   full item height but text was rendering at a fraction of it. */
.bholats-brand-marquee__wordmark {
	font-family: var(--font-display);
	font-size: var(--text-h1);
	font-weight: var(--font-weight-semibold);
	color: var(--color-text-secondary);
	white-space: nowrap;
}

@media (prefers-reduced-motion: reduce) {
	/* overflow:hidden and the edge fade-mask exist only to make the
	   scrolling state look seamless — with the track wrapped to multiple
	   static rows below, hidden overflow would clip every row past the
	   first (a real bug, caught in local screenshot QA: most brands were
	   silently invisible, not just static) and the fade would hide real
	   edge content instead of masking motion. Both are switched off here. */
	.bholats-brand-marquee__viewport {
		overflow: visible;
		-webkit-mask-image: none;
		mask-image: none;
	}
	.bholats-brand-marquee__track {
		animation: none;
		transform: none;
		width: 100%;
	}
	/* Only the real, labelled set stays — showing the decorative duplicate
	   as a second static copy of the same 36 names would just be visual
	   noise once nothing is scrolling. */
	.bholats-brand-marquee__set[aria-hidden="true"] { display: none; }
	/* .track's own flex-wrap only wraps ITS direct children (the two <ul>
	   sets) — the 36 <li> items live one level deeper, inside .set, so the
	   wrap has to be declared here to actually break them into rows. */
	.bholats-brand-marquee__set {
		flex-wrap: wrap;
		justify-content: center;
		width: 100%;
	}
	.bholats-brand-marquee__item { opacity: 1; }
	.bholats-brand-marquee__logo { filter: grayscale(0); }
}

@media (max-width: 767px) {
	.bholats-brand-marquee__item { padding-inline: var(--space-5); height: 44px; }
	.bholats-brand-marquee__logo { max-width: 200px; }
	.bholats-brand-marquee__logo--wide { max-width: 260px; }
	.bholats-brand-marquee__wordmark { font-size: var(--text-h3); }
}

/* --- Business CTA band --- */

.bholats-home-business__band {
	display: flex;
	flex-direction: column;
	gap: var(--space-4);
	padding: var(--space-6);
	background: var(--color-brand-ink);
	border-radius: var(--radius-lg);
	color: var(--color-text-on-brand);
}

.bholats-home-business__copy h2 { color: var(--color-text-on-brand); margin: 0 0 var(--space-2); }
.bholats-home-business__copy p { margin: 0 0 var(--space-1); }
.bholats-home-business__copy .bholats-text-sm { color: rgba(255, 255, 255, 0.85); }
.bholats-home-business__copy .bholats-helper-text { color: rgba(255, 255, 255, 0.6); }

@media (min-width: 768px) {
	.bholats-home-business__band {
		flex-direction: row;
		align-items: center;
		justify-content: space-between;
		padding: var(--space-8);
	}
	.bholats-home-business__copy { max-width: 60ch; }
}

/* --- Trust strip --- */

.bholats-home-trust { background: var(--color-surface-sunken); }

.bholats-home-trust-grid {
	display: grid;
	grid-template-columns: repeat(2, 1fr);
	gap: var(--space-4);
}

@media (min-width: 768px) {
	.bholats-home-trust-grid { grid-template-columns: repeat(4, 1fr); }
}

/* Phase 3C/3K both added a desktop-only override here to handle sparse
   rails (2-item Featured Laptops/Computers, an orphaned trailing card in
   Current Deals/Recently Added), first via auto-fit/minmax (which stretched
   cards to fill the row) then via flex+justify-content:center (which
   centered the row instead — reads inconsistently against every section
   heading in this file, which is left-aligned, and against the
   grid-start behaviour every archive/catalogue grid now correctly uses).
   Removed in Phase 3K.1: .bholats-product-grid's own base rule
   (product-card.css) is a plain `display:grid; grid-template-columns:
   repeat(N,1fr)` with a FIXED column count per breakpoint — a sparse rail's
   cards simply occupy their normal track width in columns 1, 2, … from the
   left, with unused trailing columns staying empty, exactly like every
   other product grid on the site. No override is needed. See
   docs/SPARSE-PRODUCT-GRID-BEHAVIOUR.md. */

/* --- Google Reviews ---
   Final homepage trust section, after Trust and before the footer (see the
   Google Reviews placement audit). Plain --color-surface background
   (matching Featured Brands) deliberately contrasts with the sunken Trust
   strip immediately above it, so the two read as distinct sections without
   needing a heavier visual divider than the shared border-top rule below
   already provides. Cards are static — no third motion source alongside
   the hero carousel and brand marquee. */

.bholats-home-reviews__header {
	display: flex;
	flex-direction: column;
	align-items: flex-start;
	gap: var(--space-5);
	margin-bottom: var(--space-8);
}

@media (min-width: 768px) {
	.bholats-home-reviews__header {
		flex-direction: row;
		align-items: center;
		justify-content: space-between;
	}
}

.bholats-home-reviews__eyebrow {
	font-size: var(--text-xs);
	font-weight: var(--font-weight-semibold);
	text-transform: uppercase;
	letter-spacing: var(--tracking-wide);
	color: var(--color-text-secondary);
	margin: 0 0 var(--space-2);
}

.bholats-home-reviews__intro .bholats-h2 { margin: 0 0 var(--space-2); }
.bholats-home-reviews__subtext { margin: 0; color: var(--color-text-secondary); max-width: 52ch; }

/* Aggregate score badge — the single highest-impact element in the section
   (real "4.9 / 175 Google reviews" figures), kept visually distinct from
   the three review cards below rather than competing with them. */
.bholats-home-reviews__aggregate {
	display: flex;
	align-items: center;
	gap: var(--space-3);
	padding: var(--space-4) var(--space-5);
	background: var(--color-surface-sunken);
	border-radius: var(--radius-lg);
	flex-shrink: 0;
}

.bholats-home-reviews__aggregate > svg { width: 28px; height: 28px; flex-shrink: 0; }

.bholats-home-reviews__aggregate-figures {
	display: flex;
	flex-direction: column;
	gap: var(--space-1);
}

.bholats-home-reviews__score {
	font-family: var(--font-display);
	font-size: var(--text-h2);
	font-weight: var(--font-weight-bold);
	line-height: 1;
	color: var(--color-text-primary);
}

.bholats-home-reviews-grid {
	display: grid;
	grid-template-columns: 1fr;
	gap: var(--space-5);
	list-style: none;
	margin: 0;
	padding: 0;
}

/* No 2-column step: unlike the product rails elsewhere on this homepage,
   this grid always holds exactly 3 curated reviews, never a variable
   count — a 2-column breakpoint would always orphan the 3rd card alone in
   its own row (confirmed in local screenshot QA), not just "sometimes" the
   way a sparse product rail might. Single column runs all the way to the
   1024px 3-column jump instead. */
@media (min-width: 1024px) {
	.bholats-home-reviews-grid { grid-template-columns: repeat(3, 1fr); }
}

.bholats-review-card {
	display: flex;
	flex-direction: column;
	height: 100%;
	padding: var(--space-6);
	margin: 0;
}

.bholats-review-card__text {
	flex: 1 0 auto;
	margin: var(--space-4) 0 var(--space-5);
}

.bholats-review-card__text p {
	margin: 0;
	color: var(--color-text-primary);
	line-height: var(--leading-relaxed);
}

/* Genuine review text is quoted, not paraphrased marketing copy — real
   quotation marks (not decorative oversized glyphs) frame it as exactly
   that. */
.bholats-review-card__text p::before { content: "\201C"; }
.bholats-review-card__text p::after { content: "\201D"; }

.bholats-review-card__footer {
	display: flex;
	align-items: center;
	gap: var(--space-3);
	margin: 0;
	padding-top: var(--space-4);
	border-top: var(--border-default);
}

.bholats-review-card__avatar {
	display: flex;
	align-items: center;
	justify-content: center;
	width: 40px;
	height: 40px;
	flex-shrink: 0;
	border-radius: var(--radius-full);
	background: var(--color-brand-blue);
	color: var(--color-text-on-brand);
	font-family: var(--font-display);
	font-weight: var(--font-weight-semibold);
	font-size: var(--text-sm);
}

.bholats-review-card__meta {
	display: flex;
	flex-direction: column;
	gap: 2px;
	min-width: 0;
}

.bholats-review-card__name {
	font-weight: var(--font-weight-semibold);
	color: var(--color-text-primary);
	font-size: var(--text-sm);
}

.bholats-review-card__source {
	display: inline-flex;
	align-items: center;
	gap: var(--space-1);
	font-size: var(--text-xs);
	color: var(--color-text-secondary);
}

.bholats-review-card__source svg { width: 14px; height: 14px; flex-shrink: 0; }

.bholats-home-reviews__cta { margin-top: var(--space-8); text-align: center; }

/* --- Shared section spacing --- */

.bholats-home-section + .bholats-home-section { border-top: var(--border-default); }
