/**
 * Tier G — horizontal scroll panel: the native fallback. Spec 38 FR-38-8 / §10.
 *
 * THE DEFAULT STATE HERE IS THE FALLBACK, NOT THE EFFECT. That inversion is
 * deliberate and is what makes the feature fail open:
 *
 *   · no JS            — the row is swipeable, every panel reachable
 *   · JS, below 768px  — same (the effect module registers no handler there)
 *   · reduced motion   — same (§10 says SIMPLIFY: "content reachable, nothing
 *                        moves by itself")
 *   · JS + ≥768px + motion allowed — the pinned scroll effect takes over, and
 *                        the override at the bottom stands the native scroller
 *                        down so the two never fight
 *
 * Without this file the panels are laid out in a `width: max-content` row with
 * no scroll container, so on a phone everything past the first panel is simply
 * unreachable — content the visitor cannot get to at all. That is a defect, not
 * a degraded experience, which is why the fallback lives in CSS rather than in
 * the effect module: the module never runs under reduced motion, so a fallback
 * implemented there could never apply in the case that needs it most.
 *
 * Conditionally enqueued by SGS_Motion_Registry only on pages that actually
 * carry a horizontal-panel effect — Tier G ships zero bytes otherwise (§4.4).
 *
 * @package SGS\Blocks
 */

[data-sgs-fx~="horizontal-panel"] {
	overflow-x: auto;
	overflow-y: hidden;
	scroll-snap-type: x mandatory;
	/* Momentum scrolling on iOS; harmless elsewhere. */
	-webkit-overflow-scrolling: touch;
}

/*
 * The flex row is the marked element's CONTENT WRAPPER, not the marked element.
 *
 * Verified against the real rendered DOM (do not "simplify" this away):
 *   <section data-sgs-fx="horizontal-panel">
 *     <div class="sgs-container__inner" data-sgs-fx-track>   <- marked
 *       <div class="wp-block-sgs-container">                 <- the flex row
 *         <section> panel … </section>
 *
 * `__inner` wraps the block's InnerBlocks content wrapper, so it always has
 * exactly ONE child. Making `__inner` itself the flex row produced a row with a
 * single item that shrank to its content — measured 96px against a 1200px
 * container, so nothing overflowed, travel distance computed as zero, and the
 * pin never engaged. Both class names here are framework-owned and structurally
 * guaranteed for sgs/container, so this is a deterministic path, not a
 * positional guess.
 */
[data-sgs-fx~="horizontal-panel"] > [data-sgs-fx-track] > .wp-block-sgs-container {
	display: flex;
	width: max-content;
}

[data-sgs-fx~="horizontal-panel"] > [data-sgs-fx-track] > .wp-block-sgs-container > * {
	scroll-snap-align: start;

	/*
	 * PANEL WIDTH IS A DEFAULT, NOT DECORATION — without it the effect cannot
	 * work at all.
	 *
	 * Flex items shrink to their content, so four panels holding a heading and a
	 * line of text measured 378px total against a 1200px container: the row never
	 * overflowed, so travel distance was zero and the pinned translate had
	 * nothing to travel. A client inserting the variation and typing normal
	 * content would hit exactly that and conclude the feature is broken.
	 *
	 * `flex-basis` in viewport units makes each panel a screenful by default, so
	 * a row of N panels is intrinsically N screens wide and always overflows.
	 * `flex-shrink: 0` stops flex collapsing them back. Clamped so a very wide
	 * monitor does not produce absurdly wide panels, and `--sgs-fx-panel-width`
	 * lets a client override per instance without touching CSS.
	 */
	flex: 0 0 var( --sgs-fx-panel-width, clamp( 280px, 80vw, 1100px ) );

	/* A flex item's default min-width:auto refuses to shrink below its content,
	   which on a narrow viewport pushes panels wider than the screen. */
	min-width: 0;
}

/*
 * Hand over to the JS effect ONLY where it actually runs: JS confirmed
 * (`.sgs-js` on <html>, set by animation-observer.js), viewport ≥768px, and
 * motion not reduced. These are exactly the conditions the effect module's own
 * `gsap.matchMedia('(min-width: 768px)')` gate uses, inside `withMotionAllowed`.
 * Keeping the two in step matters: if this override applied where the module
 * does NOT run, the native scroller would be switched off with nothing
 * replacing it and the content would be stranded.
 */
@media ( min-width: 768px ) and ( prefers-reduced-motion: no-preference ) {
	.sgs-js [data-sgs-fx~="horizontal-panel"]:not( [data-sgs-fx-horizontal-panel-breakpoint="desktop"] ) {
		/*
		 * ⛔ D456 — THIS COMPUTES TO `hidden`, NOT `clip`, AND THAT IS LOAD-BEARING.
		 * DO NOT "fix" it to clip on both axes.
		 *
		 * The base rule above sets `overflow-y: hidden`. Per the CSS Overflow
		 * spec's mixed-value normalisation — verified empirically on Chromium,
		 * Firefox AND WebKit, not assumed — `overflow-x: clip` paired with a
		 * non-clip `overflow-y` computes to `overflow-x: hidden`.
		 *
		 * `hidden` is a real scroll container; `clip` is not. That difference is
		 * currently the ONLY thing making this effect keyboard-accessible: it
		 * lets each browser's native "scroll the focused element into view"
		 * fire on `host.scrollLeft`, pulling an off-screen panel into view when
		 * a visitor tabs to a control inside it. Measured live: `scrollLeft`
		 * moves 0 → ~1670 the instant an off-screen panel-3 control is focused,
		 * both before any scroll and mid-pin, and decays cleanly back to 0 as
		 * the scrub continues — the end-of-pin state is byte-identical to a run
		 * where nothing was ever focused, so there is no lasting desync.
		 *
		 * Making this genuinely clip on both axes would silently delete that
		 * mitigation and reintroduce a WCAG 2.4.11 failure (focus landing
		 * outside the visible region) with nothing to catch it. The sibling
		 * effects needed explicit JS reveals for their version of this problem
		 * (D453); this one gets it from the browser, by accident, and the
		 * accident is now deliberate.
		 *
		 * Regression cover: `scripts/motion-qa/probe-horizontal-panel-focus.mjs`,
		 * proven non-vacuous — forcing genuine clip on both axes makes it report
		 * `FAIL — UNRECOVERED DEFECT`.
		 */
		overflow-x: clip;
		scroll-snap-type: none;
	}
}

/*
 * The pin breakpoint (`data-sgs-fx-horizontal-panel-breakpoint`, read by the module as the same three widths): the
 * tablet default and `mobile` hand over from 768px (the rule above; `mobile` also below it), `desktop` from 1024px.
 * Each rule applies only where the module runs, so the native scroller is never switched off with nothing replacing
 * it. The overflow-x note (D456) above applies to all three.
 */
@media ( min-width: 1024px ) and ( prefers-reduced-motion: no-preference ) {
	.sgs-js [data-sgs-fx~="horizontal-panel"][data-sgs-fx-horizontal-panel-breakpoint="desktop"] {
		overflow-x: clip;
		scroll-snap-type: none;
	}
}

@media ( max-width: 767.98px ) and ( prefers-reduced-motion: no-preference ) {
	.sgs-js [data-sgs-fx~="horizontal-panel"][data-sgs-fx-horizontal-panel-breakpoint="mobile"] {
		overflow-x: clip;
		scroll-snap-type: none;
	}
}

/*
 * Below the pin breakpoint the default is the snap row above. `below-mode="static"` stacks the panels instead: the
 * host stops scrolling and the row becomes a column. Reduced motion above the breakpoint keeps the snap row.
 */
@media ( max-width: 767.98px ) {
	[data-sgs-fx~="horizontal-panel"][data-sgs-fx-horizontal-panel-below-mode="static"]:not( [data-sgs-fx-horizontal-panel-breakpoint="mobile"] ) {
		overflow: visible;
		scroll-snap-type: none;
	}

	[data-sgs-fx~="horizontal-panel"][data-sgs-fx-horizontal-panel-below-mode="static"]:not( [data-sgs-fx-horizontal-panel-breakpoint="mobile"] ) > [data-sgs-fx-track],
	[data-sgs-fx~="horizontal-panel"][data-sgs-fx-horizontal-panel-below-mode="static"]:not( [data-sgs-fx-horizontal-panel-breakpoint="mobile"] ) > [data-sgs-fx-track] > .wp-block-sgs-container {
		display: flex;
		flex-direction: column;
		width: auto;
	}

	[data-sgs-fx~="horizontal-panel"][data-sgs-fx-horizontal-panel-below-mode="static"]:not( [data-sgs-fx-horizontal-panel-breakpoint="mobile"] ) > [data-sgs-fx-track] > *,
	[data-sgs-fx~="horizontal-panel"][data-sgs-fx-horizontal-panel-below-mode="static"]:not( [data-sgs-fx-horizontal-panel-breakpoint="mobile"] ) > [data-sgs-fx-track] > .wp-block-sgs-container > * {
		flex: 0 1 auto;
		width: 100%;
	}
}

@media ( min-width: 768px ) and ( max-width: 1023.98px ) {
	[data-sgs-fx~="horizontal-panel"][data-sgs-fx-horizontal-panel-below-mode="static"][data-sgs-fx-horizontal-panel-breakpoint="desktop"] {
		overflow: visible;
		scroll-snap-type: none;
	}

	[data-sgs-fx~="horizontal-panel"][data-sgs-fx-horizontal-panel-below-mode="static"][data-sgs-fx-horizontal-panel-breakpoint="desktop"] > [data-sgs-fx-track],
	[data-sgs-fx~="horizontal-panel"][data-sgs-fx-horizontal-panel-below-mode="static"][data-sgs-fx-horizontal-panel-breakpoint="desktop"] > [data-sgs-fx-track] > .wp-block-sgs-container {
		display: flex;
		flex-direction: column;
		width: auto;
	}

	[data-sgs-fx~="horizontal-panel"][data-sgs-fx-horizontal-panel-below-mode="static"][data-sgs-fx-horizontal-panel-breakpoint="desktop"] > [data-sgs-fx-track] > *,
	[data-sgs-fx~="horizontal-panel"][data-sgs-fx-horizontal-panel-below-mode="static"][data-sgs-fx-horizontal-panel-breakpoint="desktop"] > [data-sgs-fx-track] > .wp-block-sgs-container > * {
		flex: 0 1 auto;
		width: 100%;
	}
}

/*
 * Proximity focus (FR-38A-39) and the active panel (FR-38A-38). The module marks each panel `data-sgs-fx-panel`
 * while it runs and writes `--sgs-focus-s` and `--sgs-focus-op` on it; with the parameter on, the panel applies them
 * through the same `scale` and `opacity` properties `motion.css` composes (a panel that holds its own scale or
 * opacity channel, `data-sgs-mc`, takes the composed rule there instead, so the focus value multiplies with its
 * other motion rather than replacing it). With the parameter off nothing is written and nothing applies. The stored
 * focus and edge values are inputs on their own per-device properties (`--sgs-horizontal-panel-focus-scale`,
 * `-edge-scale`, `-focus-opacity`, `-edge-opacity`, set on the section by the emitter), which the module reads; the two
 * outputs applied here are only ever written by the module, so an output never overwrites a stored input.
 *
 * `--sgs-fx-active` is 1 on the active panel and 0 elsewhere, inherited by its parts, so a part restyles through
 * the active state with no script of its own: `color: color-mix( in srgb, var( --accent ) calc( var( --sgs-fx-active ) * 100% ), grey )`.
 */
@property --sgs-fx-active { syntax: '<number>'; inherits: true; initial-value: 0; }

[data-sgs-fx-horizontal-panel-proximity-focus="true"] [data-sgs-fx-panel]:not( [data-sgs-mc~="scale"] ) {
	scale: var( --sgs-focus-s );
}

[data-sgs-fx-horizontal-panel-proximity-focus="true"] [data-sgs-fx-panel]:not( [data-sgs-mc~="opacity"] ) {
	opacity: var( --sgs-focus-op );
}

[data-sgs-fx-panel-active] {
	--sgs-fx-active: 1;
}

/* Per-device off switch (Spec 38A FR-38A-23). When this effect is off at the current tier (data-sgs-fx-off-<tier> names it, or data-sgs-fx-disable-<tier> turns every effect off), the element returns to the native swipeable row, the default state of this file. .sgs-js plus the two attributes is (0,3,0), equal to the .sgs-js overflow-x: clip rules above, and this block is later. The mobile gate excludes an element whose below-mode is static, so a tier configured to stack still stacks. */
@media (max-width: 767.98px) {
	.sgs-js [data-sgs-fx~="horizontal-panel"][data-sgs-fx-off-mobile~="horizontal-panel"]:not( [data-sgs-fx-horizontal-panel-below-mode="static"]:not( [data-sgs-fx-horizontal-panel-breakpoint="mobile"] ) ),
	.sgs-js [data-sgs-fx~="horizontal-panel"][data-sgs-fx-disable-mobile]:not( [data-sgs-fx-horizontal-panel-below-mode="static"]:not( [data-sgs-fx-horizontal-panel-breakpoint="mobile"] ) ) {
		overflow-x: auto;
		overflow-y: hidden;
		scroll-snap-type: x mandatory;
	}
	[data-sgs-fx~="horizontal-panel"][data-sgs-fx-off-mobile~="horizontal-panel"] [data-sgs-fx-panel]:not([data-sgs-mc~="scale"]),
	[data-sgs-fx~="horizontal-panel"][data-sgs-fx-disable-mobile] [data-sgs-fx-panel]:not([data-sgs-mc~="scale"]) {
		scale: none;
	}
	[data-sgs-fx~="horizontal-panel"][data-sgs-fx-off-mobile~="horizontal-panel"] [data-sgs-fx-panel]:not([data-sgs-mc~="opacity"]),
	[data-sgs-fx~="horizontal-panel"][data-sgs-fx-disable-mobile] [data-sgs-fx-panel]:not([data-sgs-mc~="opacity"]) {
		opacity: 1;
	}
}
@media (min-width: 768px) and (max-width: 1023.98px) {
	.sgs-js [data-sgs-fx~="horizontal-panel"][data-sgs-fx-off-tablet~="horizontal-panel"],
	.sgs-js [data-sgs-fx~="horizontal-panel"][data-sgs-fx-disable-tablet] {
		overflow-x: auto;
		overflow-y: hidden;
		scroll-snap-type: x mandatory;
	}
	[data-sgs-fx~="horizontal-panel"][data-sgs-fx-off-tablet~="horizontal-panel"] [data-sgs-fx-panel]:not([data-sgs-mc~="scale"]),
	[data-sgs-fx~="horizontal-panel"][data-sgs-fx-disable-tablet] [data-sgs-fx-panel]:not([data-sgs-mc~="scale"]) {
		scale: none;
	}
	[data-sgs-fx~="horizontal-panel"][data-sgs-fx-off-tablet~="horizontal-panel"] [data-sgs-fx-panel]:not([data-sgs-mc~="opacity"]),
	[data-sgs-fx~="horizontal-panel"][data-sgs-fx-disable-tablet] [data-sgs-fx-panel]:not([data-sgs-mc~="opacity"]) {
		opacity: 1;
	}
}
