/* Horizontal Rotating Photos — About §3 (Figma 11016:4405).

   Geometry is fixed here, not in BB: 448 x 780 cards, a 15px gap (463px pitch) and
   a 32px inset before the first card. The JS owns exactly one thing —
   --tbl-rp-offset on the viewport — so every track copy reads one position and they
   cannot drift apart.

   BB owns section spacing (bb-owns-section-spacing): the frame's 906px container is
   the 780px strip plus row padding, and the padding lives in the builder. */

.tbl-rotating-photos {
	/*
	 * The card scale unit, as a LENGTH rather than a factor. calc() may not add a
	 * length to a number, so a fluid unitless zoom is not expressible and fails
	 * silently; number * length is legal, so `calc(448 * var(--u))` resolves.
	 * Same technique as --tbl-glance-u.
	 *
	 * Curve: 1.0 at >=1600px (Chris's designed 448px card holds on desktop), easing
	 * to 0.58 at 390px, where the card lands at 260px and ~130px of the next card
	 * stays on screen as the cue that the strip continues. At 1024 it computes to
	 * 0.800 => a 358px card. The slope is rounded UP so the line just overshoots 1.0
	 * before 1600 and clamp() pins it exactly from there.
	 */
	--tbl-rp-u: clamp(0.58px, calc(0.034711vw + 0.444628px), 1px);

	--tbl-rp-card-w: calc(448 * var(--tbl-rp-u));
	--tbl-rp-card-h: calc(780 * var(--tbl-rp-u));
	--tbl-rp-gap: calc(15 * var(--tbl-rp-u));
	--tbl-rp-inset: calc(32 * var(--tbl-rp-u));

	--tbl-rp-offset: 0px;

	position: relative;

	/*
	 * The width MUST be definite, and it must not be a percentage.
	 *
	 * `.fl-col-content` is a flex container and `.fl-module` is a shrink-to-fit flex
	 * item, so the column is sized by its content: with `width: 100%` here the
	 * percentage resolved against a parent that was itself asking this module how wide
	 * it wanted to be, and the answer was the whole 13664px track. The column, the
	 * module and this section all inflated to it, and the clipping window ended up
	 * centred at x=6072 — off-screen at every width from 768 up, while 390 was fine
	 * because Beaver Builder stacks to block layout below its breakpoint.
	 *
	 * A definite width stops the content width propagating upward at this box.
	 * --tbl-rp-viewport is the real `documentElement.clientWidth`, written by the JS;
	 * 100vw is only the pre-JS/no-JS fallback and is deliberately not used otherwise,
	 * because it includes the scrollbar.
	 */
	width: var(--tbl-rp-viewport, 100vw);

	/*
	 * Full bleed. The row wrap's own inset is measured rather than assumed — Beaver
	 * Builder contributes 20px per side here, which is 40px of offset, but that is a
	 * row setting and not a constant. Percentage-based bleed (`50% - 50vw`) cannot
	 * work: every percentage against this parent is circular now that the parent is
	 * content-sized.
	 */
	margin-left: calc(-1 * var(--tbl-rp-shift, 0px));

	/*
	 * The right margin is a mirror of the left and is deliberately NOT symmetry for its
	 * own sake. This box is over-constrained — definite width, definite left margin — so
	 * in LTR the right margin is ignored for placement and cannot move anything. What it
	 * does do is shrink the SHRINK-TO-FIT ancestors, which size themselves from width
	 * plus margins: without it the column and module boxes ran from the row's 20px inset
	 * to 1620 on a 1600 viewport, and `documentElement.scrollWidth` reported 1620. No
	 * scrollbar resulted (the theme clips `html`), but the criterion is the number.
	 */
	margin-right: calc(-1 * var(--tbl-rp-shift, 0px));
}

/* -------------------------------------------------------------- the rail ---- */

.tbl-rotating-photos__viewport {
	display: flex;
	gap: var(--tbl-rp-gap);

	/*
	 * The frame's 32px inset before the first card. It is only the RESTING position,
	 * so once the marquee is live the JS folds it into the shared offset instead —
	 * held as padding it would be a 32px blank the strip could never fill, and cards
	 * would vanish 32px short of the screen edge forever.
	 */
	padding-left: var(--tbl-rp-inset);

	/* JS-off default: a natively scrollable strip. The JS opts into the marquee. */
	overflow-x: auto;
	overflow-y: hidden;
}

.tbl-rotating-photos__viewport.is-live {
	padding-left: 0;
	overflow: hidden;
	cursor: grab;
	user-select: none;
	-webkit-user-select: none;
	touch-action: pan-y; /* let the page scroll vertically; we own horizontal */
}

.tbl-rotating-photos__viewport.is-live.is-dragging {
	cursor: grabbing;
}

.tbl-rotating-photos__track {
	display: flex;
	gap: var(--tbl-rp-gap);
	flex: 0 0 auto;
	margin: 0;
	padding: 0;
	list-style: none;
}

/*
 * Without JS the transform never moves, so the duplicate tracks would just read every
 * photo twice. They are hidden until the marquee is live.
 */
.tbl-rotating-photos__track[aria-hidden='true'] {
	display: none;
}

.is-live .tbl-rotating-photos__track {
	transform: translate3d(var(--tbl-rp-offset), 0, 0);
	will-change: transform;
}

.is-live .tbl-rotating-photos__track[aria-hidden='true'] {
	display: flex;
}

/* ----------------------------------------------------------------- cards ---- */

.tbl-rotating-photos__card {
	position: relative;
	flex: 0 0 auto;
	/* Explicit: the 448/15 pitch is load-bearing for the modulo wrap, so it must not
	   depend on the global reset still setting border-box. */
	box-sizing: border-box;
	width: var(--tbl-rp-card-w);
	height: var(--tbl-rp-card-h);
	overflow: hidden;
	margin: 0;
	padding: 0;
	background-color: var(--Neutral-10, #f2f2f2);
}

.tbl-rotating-photos__photo {
	display: block;
	width: 100%;
	height: 100%;
	object-fit: cover;
	object-position: center;
	-webkit-user-drag: none;
	user-select: none;
	-webkit-user-select: none;
}
