/* Slideshow (§2, Figma node 10355:3519) — full-bleed Swiper slideshow with a
   static stepped "comparison" label overlay. See slideshow-SPEC.md for
   measured behavior (primary.studio framer-897vo5) and geometry source. */

.tb-slideshow {
	/* No outer padding/min-height/width — BB row settings own section
	   spacing (Full Width row, zero padding, per the bb-owns-section-spacing
	   convention). Height is intrinsic to the slideshow content, so the
	   module owns it via the section_height_vh design knob. */
	position: relative;
	display: block;
	height: calc(var(--tb-slideshow-height, 90) * 1svh);
	/* Guard: in an unconfigured (shrink-to-fit) BB column the Swiper flex
	   wrapper's circular intrinsic sizing can blow the column to the browser
	   layout cap (~2^25px, seen live 2026-07-10 QA). A viewport-definite
	   max keeps the section sane regardless of row settings. */
	max-width: 100vw;
	overflow: hidden;
	background: var(--Neutral-100);

	& .tb-slideshow__swiper {
		position: relative;
		width: 100%;
		height: 100%;
	}

	/* Blur dissolve (Ben's pick 2026-07-10, fade lab #4 — supersedes the
	   SPEC's measured leftward slide): Swiper `fade` owns opacity and stamps
	   its inline transition-duration on each slide, which also drives the
	   filter/transform transitions below — so the blur/scale always matches
	   the module's Transition Speed setting. easeOutExpo feel kept via the
	   timing function. Non-active slides sit blurred at opacity 0.

	   Blur states are scoped to .swiper-initialized so slides render crisp
	   wherever Swiper doesn't boot — the BB editor (init guard skips it)
	   and no-JS visitors. */
	& .swiper-slide {
		position: relative;
		width: 100%;
		height: 100%;
		overflow: hidden;
		transition-property: opacity, filter, transform;
		transition-timing-function: cubic-bezier(0.16, 1, 0.3, 1);
	}

	& .tb-slideshow__swiper.swiper-initialized .swiper-slide {
		filter: blur(14px);
		transform: scale(1.04);
	}

	& .tb-slideshow__swiper.swiper-initialized .swiper-slide.swiper-slide-active {
		filter: blur(0);
		transform: scale(1);
	}

	& .tb-slideshow__slide-link {
		display: block;
		width: 100%;
		height: 100%;
	}

	& .tb-slideshow__slide-image {
		display: block;
		width: 100%;
		height: 100%;
		object-fit: cover;
		object-position: center;
	}

	/* No dots, no visible arrows, no drag cursor on desktop (SPEC
	   "Controls"); native touch swipe stays enabled on touch devices. */
	& .swiper-button-prev,
	& .swiper-button-next,
	& .swiper-pagination {
		display: none;
	}

	& .tb-slideshow__swiper.swiper {
		cursor: default;
	}

	/* Static "Comparison" overlay — 3 stepped label bars, pinned bottom-left,
	   above the slides. Does NOT change per slide (SPEC "Overlay bars").
	   Full width so the bars' percentage widths resolve against the section. */
	& .tb-slideshow__labels {
		position: absolute;
		z-index: 2;
		left: 0;
		bottom: 0;
		width: 100%;
		display: flex;
		flex-flow: column nowrap;
		align-items: flex-start;
	}

	/* Bar widths are PERCENTAGE TIERS copied off primary.studio (Playwright
	   sweep 2026-07-10, 11 viewports): mobile <810 = 40/70/100, tablet
	   810–1199 = 20/40/80, desktop ≥1200 = Figma's exact proportions
	   (285/568/960 @1600). min-width keeps a long label from clipping if a
	   tier runs narrower than its content. */
	& .tb-slideshow__label-bar {
		display: flex;
		align-items: center;
		justify-content: flex-end;
		gap: 10px;
		min-height: 40px;
		min-width: max-content;
		max-width: 100%;
		white-space: nowrap;
		padding: 0 24px 0 16px;
		background: var(--Neutral-0);
		color: var(--Neutral-100);
		font-family: var(--body-font);
		font-size: 12px;
		line-height: 13.2px;
		letter-spacing: 0.05em;
		text-transform: uppercase;

		@media (max-width:767px) {
			& {
			padding: 0 12px 0 16px;
			}
		}
	}

	/* First bar only: its text/arrow sit on the site's 1400px content line at
	   viewports wider than 1400px (16px floor below that keeps the old gutter).
	   The bar background still fills the padding and the wrapper stays left:0,
	   so backgrounds remain full-bleed — only bar 1's text moves inward. Bars
	   2/3 keep flex-end so their text reaches the end of their ribbons. */
	& .tb-slideshow__label-bar--1 {
		width: 40%;
		justify-content: flex-start;
		padding-left: max((100vw - 1400px) / 2, 16px);
	}
	& .tb-slideshow__label-bar--2 { width: 70%; }
	& .tb-slideshow__label-bar--3 { width: 100%; }

	/* Footer submit arrow SVG reused at ribbon scale; currentColor inherits
	   the bar's --Neutral-100 (black). */
	& .tb-slideshow__label-arrow {
		flex: 0 0 auto;
		display: block;
		width: 10px;
		height: auto;
	}

	& .tb-slideshow__label-text {
		flex: 0 1 auto;
	}
}

/* Pastel #67 — below 576 the mobile tier's 40/70/100 steps unevenly (30, 30,
   but off a 40 base, so the first ribbon reads short and the gaps between the
   three right-hand edges are not equal). Thirds make the three edges evenly
   spaced. The base rule's `min-width: max-content` still wins wherever a label
   is longer than its third, which is exactly the "as evenly as the text
   allows" caveat. */
@media (max-width: 575.98px) {
	.tb-slideshow .tb-slideshow__label-bar--1 { width: 33.333%; }
	.tb-slideshow .tb-slideshow__label-bar--2 { width: 66.667%; }
	.tb-slideshow .tb-slideshow__label-bar--3 { width: 100%; }
}

/* Tablet tier (810–1199, primary.studio breakpoints): 20 / 40 / 80. */
@media (min-width:810px) {
	.tb-slideshow .tb-slideshow__label-bar--1 { width: 20%; }
	.tb-slideshow .tb-slideshow__label-bar--2 { width: 40%; }
	.tb-slideshow .tb-slideshow__label-bar--3 { width: 80%; }
}

/* Desktop tier (≥1200): Figma 10355:3561 end-state proportions — 285/568/960
   @1600 as percentages so they scale with the viewport like primary's
   (13/30/60 with their shorter labels; Chris's run longer). Bar bg stays
   --Neutral-0: the comp's #fafafa has no token (wireframe drift, same call
   as the footer's unbound hex). */
@media (min-width:1200px) {
	.tb-slideshow .tb-slideshow__label-bar--1 {
		width: 17.8125%;
	}

	.tb-slideshow .tb-slideshow__label-bar--2 {
		width: 38%;
	}

	.tb-slideshow .tb-slideshow__label-bar--3 {
		width: 60%;
	}
}

/* Mobile height (≤767px) — 50vh default per primary.studio, own design
   knob (--tb-slideshow-height-mobile). Bar widths are handled by the
   percentage tiers above (base = mobile 40/70/100). */
@media (max-width:767px) {
	.tb-slideshow {
		height: calc(var(--tb-slideshow-height-mobile, 50) * 1svh);
	}

	/* Pastel #129 (Chris) — reverts the flat left-align of #54. Chris wants the
	   staggered read back: line 1 left, line 2 centred, line 3 right. That only
	   works if each label fits inside its own ribbon, so the type steps down
	   here — at 12px `min-width: max-content` blew past every tier and the
	   three ends landed at unrelated x positions, which is what #54 was
	   working around. */
	.tb-slideshow .tb-slideshow__label-bar {
		font-size: 10px;
		line-height: 11px;
		gap: 8px;
	}

	.tb-slideshow .tb-slideshow__label-bar--1 { justify-content: flex-start; }
	.tb-slideshow .tb-slideshow__label-bar--3 { justify-content: flex-end; }

	/* Pastel #147 (Chris) — #129's `justify-content: center` centred line 2 inside
	   its own 66.667% ribbon, which put it ~51px left of screen centre. Centring it
	   on the SCREEN is not reachable while the ribbon stays anchored at x:0: the
	   content would have to run past the ribbon's right edge. So the ribbon itself
	   becomes the centred object — shrink-wrapped and margin-auto'd — which is also
	   the truest read of the left/centre/right stagger #129 asked for. Padding goes
	   symmetric here (14/14 keeps the ribbon the same total width as 16/12) because
	   the asymmetry existed to align bars 1 and 3 to the gutter, and a floating pill
	   has no gutter to align to. */
	.tb-slideshow .tb-slideshow__label-bar--2 {
		position: relative;
		justify-content: center;
		width: max-content;
		max-width: 100%;
		margin-inline: auto;
		padding-inline: 14px;
	}

	/* Pastel #153 (Chris) — #147's floating pill left a slice of the slide
	   photo visible between x:0 and the ribbon's left edge. The ribbon itself
	   cannot start at 0 and still keep its text on the screen's centre line
	   (the width would have to be `50% + half the text`, which CSS can't
	   express), so the fill is a pseudo-element hung off the ribbon's left
	   edge instead. `right: 100%` keeps it glued to that edge at every
	   viewport, and `.tb-slideshow`'s own `overflow: hidden` clips the excess.
	   It is deliberately NOT mirrored on the right: bar 3 still has to read as
	   the widest step, so the ribbon's right edge stays short of the gutter. */
	.tb-slideshow .tb-slideshow__label-bar--2::before {
		content: '';
		position: absolute;
		top: 0;
		bottom: 0;
		right: 100%;
		width: 100vw;
		background: var(--Neutral-0);

		/* Pastel #157 (Chris) -- "the white bar here is missing, then after a
		   second it fills in." #153's fill is hung off the ribbon and so was
		   NOT part of the JS width collapse: while the bars waited to reveal,
		   this slab painted a white block from x:0 to the collapsed ribbon
		   while the ribbon itself was 0 wide, then the ribbon grew into it.
		   The fill now wipes with the bar -- same duration and easing as the
		   JS width tween -- so the row reads as one gesture. The collapsed
		   state is class-gated, so no-JS and reduced-motion (neither of which
		   collapses the bars) still paint it immediately. */
		transform-origin: right center;
		transition: transform 1200ms cubic-bezier(0.16, 1, 0.3, 1);
	}

	.tb-slideshow .tb-slideshow__labels.is-bars-collapsed .tb-slideshow__label-bar--2::before {
		transform: scaleX(0);
		transition: none;
	}
}
