/*! remarqueeble v0.6.0 | (c) 2026 Rémino Rem <https://remino.net/> | ISC Licence */
//#region src/lib/remarqueeble.ts
var DEFAULT_DIRECTION = "left";
var DEFAULT_BEHAVIOR = "scroll";
var DEFAULT_ANIMATE = "always";
var DEFAULT_SCROLL_AMOUNT = 6;
var DEFAULT_SCROLL_AMOUNT_LENGTH = `${DEFAULT_SCROLL_AMOUNT}px`;
var DEFAULT_SCROLL_DELAY = 85;
var MIN_SCROLL_DELAY = 60;
var DEFAULT_VERTICAL_HEIGHT = "200px";
var DEFAULT_HOST_WIDTH = "calc(100% - (var(--attr-hspace, 0px) * 2))";
var ATTR_DIRECTION = "direction";
var ATTR_BEHAVIOR = "behavior";
var ATTR_ANIMATE = "animate";
var ATTR_SCROLL_AMOUNT = "scrollamount";
var ATTR_SCROLL_DELAY = "scrolldelay";
var ATTR_TRUE_SPEED = "truespeed";
var ATTR_LOOP = "loop";
var ATTR_BG_COLOR = "bgcolor";
var ATTR_WIDTH = "width";
var ATTR_HEIGHT = "height";
var ATTR_HSPACE = "hspace";
var ATTR_VSPACE = "vspace";
var CSS_VAR_WIDTH = "--attr-width";
var CSS_VAR_HEIGHT = "--attr-height";
var CSS_VAR_HSPACE = "--attr-hspace";
var CSS_VAR_VSPACE = "--attr-vspace";
var CSS_VAR_BG_COLOR = "--attr-bgcolor";
var CSS_VAR_ANIMATION_DURATION = "--animation-duration";
var CSS_VAR_ANIMATION_DIRECTION = "--animation-direction";
var CSS_VAR_ANIMATION_ITERATION_COUNT = "--animation-iteration-count";
var CSS_VAR_ANIMATION_PLAY_STATE = "--animation-play-state";
var CSS_VAR_ANIMATION_TIMING_FUNCTION = "--animation-timing-function";
var CSS_VAR_TRANSLATE_X_END = "--translate-x-end";
var CSS_VAR_TRANSLATE_X_START = "--translate-x-start";
var CSS_VAR_TRANSLATE_Y_END = "--translate-y-end";
var CSS_VAR_TRANSLATE_Y_START = "--translate-y-start";
var HTMLElementBase = globalThis.HTMLElement ?? class {};
var parsePresentationalDimension = (value) => {
	if (value === null) return null;
	const trimmed = value.trim();
	if (trimmed === "") return null;
	if (/^[+-]?(?:\d+|\d*\.\d+)$/.test(trimmed)) return `${trimmed}px`;
	return globalThis.CSS?.supports("width", trimmed) ? trimmed : null;
};
var parseScrollAmount = (value) => {
	if (value === null) return null;
	const trimmed = value.trim();
	if (trimmed === "") return null;
	if (/^[+-]?(?:\d+|\d*\.\d+)$/.test(trimmed)) return Number(trimmed) >= 0 ? `${trimmed}px` : null;
	return globalThis.CSS?.supports("width", trimmed) ? trimmed : null;
};
var parseLegacyColor = (value) => {
	if (value === null) return null;
	const trimmed = value.trim();
	if (trimmed === "") return null;
	return globalThis.CSS?.supports("background-color", trimmed) ? trimmed : null;
};
var ATTRIBUTE_HINTS = [
	{
		attribute: ATTR_WIDTH,
		cssVar: CSS_VAR_WIDTH,
		parser: parsePresentationalDimension
	},
	{
		attribute: ATTR_HEIGHT,
		cssVar: CSS_VAR_HEIGHT,
		parser: parsePresentationalDimension,
		fallback(element) {
			return element.isVerticalDirection && !element.hasAttribute(ATTR_HEIGHT) ? DEFAULT_VERTICAL_HEIGHT : null;
		}
	},
	{
		attribute: ATTR_HSPACE,
		cssVar: CSS_VAR_HSPACE,
		parser: parsePresentationalDimension
	},
	{
		attribute: ATTR_VSPACE,
		cssVar: CSS_VAR_VSPACE,
		parser: parsePresentationalDimension
	},
	{
		attribute: ATTR_BG_COLOR,
		cssVar: CSS_VAR_BG_COLOR,
		parser: parseLegacyColor
	}
];
var RemarqueebleElement = class extends HTMLElementBase {
	static observedAttributes = [
		ATTR_DIRECTION,
		ATTR_BEHAVIOR,
		ATTR_ANIMATE,
		ATTR_SCROLL_AMOUNT,
		ATTR_SCROLL_DELAY,
		ATTR_TRUE_SPEED,
		ATTR_LOOP,
		ATTR_BG_COLOR,
		ATTR_WIDTH,
		ATTR_HEIGHT,
		ATTR_HSPACE,
		ATTR_VSPACE
	];
	track;
	scrollAmountProbe;
	running = false;
	constructor() {
		super();
		const shadowRoot = this.attachShadow({ mode: "open" });
		shadowRoot.innerHTML = `
			<style>
				:host {
					display: inline-block;
					text-align: initial;
					overflow: hidden !important;
					white-space: nowrap;
					width: var(${CSS_VAR_WIDTH}, ${DEFAULT_HOST_WIDTH});
					height: var(${CSS_VAR_HEIGHT}, auto);
					margin-inline: var(${CSS_VAR_HSPACE}, 0px);
					margin-block: var(${CSS_VAR_VSPACE}, 0px);
					background-color: var(${CSS_VAR_BG_COLOR}, transparent);
					box-sizing: border-box;
				}

				:host([direction="up"]),
				:host([direction="down"]) {
					white-space: normal;
				}

				.track {
					animation: remarqueeble-motion
						var(${CSS_VAR_ANIMATION_DURATION}, 10s)
						var(${CSS_VAR_ANIMATION_TIMING_FUNCTION}, linear)
						var(${CSS_VAR_ANIMATION_ITERATION_COUNT}, infinite)
						var(${CSS_VAR_ANIMATION_DIRECTION}, normal)
						both;
					animation-play-state: var(${CSS_VAR_ANIMATION_PLAY_STATE}, running);
					display: inline-block;
					will-change: transform;
				}

				.scrollamount-probe {
					block-size: 0;
					display: block;
					inline-size: ${DEFAULT_SCROLL_AMOUNT_LENGTH};
					overflow: hidden;
					pointer-events: none;
					position: absolute;
					visibility: hidden;
				}

				@keyframes remarqueeble-motion {
					from {
						transform: translate(
							var(${CSS_VAR_TRANSLATE_X_START}, 100%),
							var(${CSS_VAR_TRANSLATE_Y_START}, 0px)
						);
					}

					to {
						transform: translate(
							var(${CSS_VAR_TRANSLATE_X_END}, -100%),
							var(${CSS_VAR_TRANSLATE_Y_END}, 0px)
						);
					}
				}
			</style>

			<span class="track"><slot></slot></span>
			<span class="scrollamount-probe" aria-hidden="true"></span>
		`;
		const track = shadowRoot.querySelector(".track");
		if (!track) throw new Error("Remarqueeble track element was not created.");
		const scrollAmountProbe = shadowRoot.querySelector(".scrollamount-probe");
		if (!scrollAmountProbe) throw new Error("Remarqueeble scrollamount probe was not created.");
		this.track = track;
		this.scrollAmountProbe = scrollAmountProbe;
		this.track.addEventListener("animationend", () => this.handleAnimationEnd());
	}
	connectedCallback() {
		this.running = true;
		this.syncPresentationalHints();
		requestAnimationFrame(() => {
			if (!this.isConnected || !this.running) return;
			this.reset();
		});
	}
	disconnectedCallback() {
		this.running = false;
	}
	attributeChangedCallback(_name, oldValue, newValue) {
		if (oldValue === newValue) return;
		this.syncPresentationalHints();
		if (this.isConnected) this.reset();
	}
	get direction() {
		return this.getAttribute(ATTR_DIRECTION) || DEFAULT_DIRECTION;
	}
	get behavior() {
		return this.getAttribute(ATTR_BEHAVIOR) || DEFAULT_BEHAVIOR;
	}
	get scrollAmount() {
		const value = parseScrollAmount(this.getAttribute(ATTR_SCROLL_AMOUNT)) ?? DEFAULT_SCROLL_AMOUNT_LENGTH;
		this.scrollAmountProbe.style.inlineSize = value;
		const measured = this.scrollAmountProbe.getBoundingClientRect().width;
		return Number.isFinite(measured) && measured >= 0 ? measured : DEFAULT_SCROLL_AMOUNT;
	}
	get scrollDelay() {
		const raw = this.getAttribute(ATTR_SCROLL_DELAY);
		const value = raw === null || raw.trim() === "" ? NaN : Number(raw);
		const delay = Number.isFinite(value) && value >= 0 ? value : DEFAULT_SCROLL_DELAY;
		if (this.hasAttribute(ATTR_TRUE_SPEED)) return delay;
		return Math.max(delay, MIN_SCROLL_DELAY);
	}
	get loop() {
		const value = this.getAttribute(ATTR_LOOP);
		return value === null ? -1 : Number(value);
	}
	get directionSign() {
		return this.direction === "right" || this.direction === "down" ? 1 : -1;
	}
	get isVerticalDirection() {
		return this.direction === "up" || this.direction === "down";
	}
	start() {
		if (this.running) return;
		this.running = true;
		this.reset();
		this.syncAnimationPlayState();
	}
	stop() {
		this.running = false;
		this.syncAnimationPlayState();
	}
	syncPresentationalHints() {
		for (const hint of ATTRIBUTE_HINTS) this.syncVar(hint);
		this.syncAnimationPlayState();
	}
	syncVar(hint) {
		const raw = this.getAttribute(hint.attribute);
		const value = hint.parser(raw);
		const fallback = hint.fallback ? hint.fallback(this) : null;
		if (value == null) {
			if (fallback == null) this.style.removeProperty(hint.cssVar);
			else this.style.setProperty(hint.cssVar, fallback);
			return;
		}
		this.style.setProperty(hint.cssVar, value);
	}
	reset() {
		const hostSize = this.getHostSize();
		const trackSize = this.getTrackSize();
		this.syncAnimation(hostSize, trackSize);
	}
	getHostSize() {
		return this.isVerticalDirection ? this.clientHeight : this.clientWidth;
	}
	getTrackSize() {
		return this.isVerticalDirection ? this.track.offsetHeight : this.track.offsetWidth;
	}
	getStartPosition(hostSize, trackSize) {
		return this.directionSign < 0 ? hostSize : -trackSize;
	}
	getFlushEndPosition(hostSize, trackSize) {
		return this.directionSign < 0 ? 0 : hostSize - trackSize;
	}
	getOffEndPosition(hostSize, trackSize) {
		return this.directionSign < 0 ? -trackSize : hostSize;
	}
	getSlideEndPosition(hostSize, trackSize) {
		return this.directionSign < 0 ? 0 : hostSize - trackSize;
	}
	getAlternateStartPosition(hostSize, trackSize) {
		return this.directionSign < 0 ? hostSize - trackSize : 0;
	}
	syncAnimationPlayState() {
		this.style.setProperty(CSS_VAR_ANIMATION_PLAY_STATE, this.running ? "running" : "paused");
	}
	syncAnimation(hostSize, trackSize) {
		if (!this.shouldAnimate(hostSize, trackSize) || this.scrollAmount === 0) {
			this.syncStaticAnimation();
			return;
		}
		const startPosition = this.behavior === "alternate" ? this.getAlternateStartPosition(hostSize, trackSize) : this.getStartPosition(hostSize, trackSize);
		const endPosition = this.behavior === "slide" ? this.getSlideEndPosition(hostSize, trackSize) : this.behavior === "alternate" ? this.getFlushEndPosition(hostSize, trackSize) : this.getOffEndPosition(hostSize, trackSize);
		const distance = Math.abs(endPosition - startPosition);
		const steps = Math.max(1, Math.ceil(distance / Math.max(1, this.scrollAmount)));
		const duration = Math.max(1, steps * this.scrollDelay);
		const iterationCount = this.getCssIterationCount();
		this.track.style.removeProperty("transform");
		this.style.setProperty(CSS_VAR_ANIMATION_DURATION, `${duration}ms`);
		this.style.setProperty(CSS_VAR_ANIMATION_DIRECTION, this.behavior === "alternate" ? "alternate" : "normal");
		this.style.setProperty(CSS_VAR_ANIMATION_ITERATION_COUNT, iterationCount);
		this.style.setProperty(CSS_VAR_ANIMATION_TIMING_FUNCTION, `steps(${steps}, end)`);
		if (this.isVerticalDirection) {
			this.style.setProperty(CSS_VAR_TRANSLATE_X_START, "0px");
			this.style.setProperty(CSS_VAR_TRANSLATE_X_END, "0px");
			this.style.setProperty(CSS_VAR_TRANSLATE_Y_START, `${startPosition}px`);
			this.style.setProperty(CSS_VAR_TRANSLATE_Y_END, `${endPosition}px`);
		} else {
			this.style.setProperty(CSS_VAR_TRANSLATE_X_START, `${startPosition}px`);
			this.style.setProperty(CSS_VAR_TRANSLATE_X_END, `${endPosition}px`);
			this.style.setProperty(CSS_VAR_TRANSLATE_Y_START, "0px");
			this.style.setProperty(CSS_VAR_TRANSLATE_Y_END, "0px");
		}
		this.restartAnimation();
	}
	shouldAnimate(hostSize, trackSize) {
		if (this.animationMode === "never") return false;
		if (this.animationMode === "overflow") return trackSize > hostSize;
		return true;
	}
	get animationMode() {
		const value = this.getAttribute(ATTR_ANIMATE);
		if (value === "overflow" || value === "never") return value;
		return DEFAULT_ANIMATE;
	}
	syncStaticAnimation() {
		this.style.setProperty(CSS_VAR_ANIMATION_DURATION, "0ms");
		this.style.setProperty(CSS_VAR_ANIMATION_DIRECTION, "normal");
		this.style.setProperty(CSS_VAR_ANIMATION_ITERATION_COUNT, "1");
		this.style.setProperty(CSS_VAR_ANIMATION_TIMING_FUNCTION, "linear");
		this.style.setProperty(CSS_VAR_TRANSLATE_X_START, "0px");
		this.style.setProperty(CSS_VAR_TRANSLATE_X_END, "0px");
		this.style.setProperty(CSS_VAR_TRANSLATE_Y_START, "0px");
		this.style.setProperty(CSS_VAR_TRANSLATE_Y_END, "0px");
		this.track.style.animationName = "none";
		this.track.style.transform = "translate(0px, 0px)";
	}
	getCssIterationCount() {
		if (this.behavior === "slide" && !this.hasAttribute(ATTR_LOOP)) return "1";
		if (!this.hasAttribute(ATTR_LOOP)) return "infinite";
		if (Number.isFinite(this.loop) && this.loop > 0) return String(this.loop);
		return "infinite";
	}
	handleAnimationEnd() {
		if (!this.hasFiniteAnimation()) return;
		this.running = false;
		this.syncAnimationPlayState();
	}
	restartAnimation() {
		this.track.style.animationName = "none";
		this.track.offsetWidth;
		this.track.style.removeProperty("animation-name");
	}
	hasFiniteAnimation() {
		if (this.behavior === "slide" && !this.hasAttribute(ATTR_LOOP)) return true;
		return this.hasAttribute(ATTR_LOOP) && Number.isFinite(this.loop) && this.loop > 0;
	}
};
var ReMarqueeElement = class extends RemarqueebleElement {};
var ReMarqueeBleElement = class extends RemarqueebleElement {};
var defineRemarqueebleElements = () => {
	if (typeof customElements === "undefined") return;
	if (!customElements.get("re-marquee")) customElements.define("re-marquee", ReMarqueeElement);
	if (!customElements.get("re-marquee-ble")) customElements.define("re-marquee-ble", ReMarqueeBleElement);
};
//#endregion
//#region src/lib/auto.ts
defineRemarqueebleElements();
//#endregion
