/* ============================================================
   WellMade Axis Core - Scroll Progress
   ------------------------------------------------------------
   A page-level reading-progress indicator in two styles:
     - bar    : a thin line on any of the four edges. Top/bottom
                fill left -> right; left/right fill top -> bottom.
                The position alone decides the orientation.
     - circle : a ring in a corner that sweeps as you scroll,
                with an optional live percentage in the middle.

   TWO-LAYER FILL (important):
     .wma-sp__fill        -> the "filler": scales with scroll
                             (scaleX/scaleY bound to the timeline).
                             It is transparent itself.
     .wma-sp__fill-inner  -> the color layer inside it: solid,
                             gradient, or a time-based RGB spectrum.
   Splitting these means the scroll-driven scale and the time-based
   RGB spectrum never fight over the single `animation` slot of one
   element (which was the bug: the spectrum overrode the fill scale).

   Engine: pure CSS scroll-driven animation. The scale is bound to a
   scroll-progress timeline via `animation-timeline`, so it runs on
   the compositor thread (no JS, no scroll listeners). Everything is
   wrapped in @supports, so browsers without scroll-timeline show
   nothing (graceful no-op) instead of a frozen bar. The indicator
   always tracks the whole document scroll.

   Optional neon glow (class + intensity var) and rounded ends.
   Colors: --wma-sp-color / --wma-sp-color2 (GP palette var,
   dark-mode aware, or a fixed custom value).
   ============================================================ */

.wma-sp {
	--wma-sp-size: 3px;
	--wma-sp-color: var(--contrast, #0d0d0d);
	--wma-sp-color2: var(--accent, #888);
	--wma-sp-track: color-mix(in srgb, var(--wma-sp-color) 14%, transparent);
	--wma-sp-radius: 0px;
	--wma-sp-opacity: 1;
	--wma-sp-glow-color: var(--wma-sp-color);
	--wma-sp-glow-blur: 0px;
	--wma-sp-z: 2147483600;

	position: fixed;
	pointer-events: none;
	z-index: var(--wma-sp-z);
	opacity: var(--wma-sp-opacity);
}

/* ============================================================
   STYLE: BAR
   ============================================================ */

/* Track (the element itself) sits on an edge. */
.wma-sp--bar.wma-sp--pos-top,
.wma-sp--bar.wma-sp--pos-bottom {
	left: 0;
	right: 0;
	height: var(--wma-sp-size);
	background: var(--wma-sp-track);
}
.wma-sp--bar.wma-sp--pos-top    { top: 0; }
.wma-sp--bar.wma-sp--pos-bottom { bottom: 0; }

.wma-sp--bar.wma-sp--pos-left,
.wma-sp--bar.wma-sp--pos-right {
	top: 0;
	bottom: 0;
	width: var(--wma-sp-size);
	background: var(--wma-sp-track);
}
.wma-sp--bar.wma-sp--pos-left  { left: 0; }
.wma-sp--bar.wma-sp--pos-right { right: 0; }

/* The filler grows in real width/height (not transform: scaleX), so a
   glow on it stays uniform and never stretches or gets cut at the
   moving edge. It starts at 0 along the scroll axis and the engine
   animates it to 100%. */
.wma-sp--bar .wma-sp__fill {
	display: block;
	border-radius: var(--wma-sp-radius);
}
.wma-sp--bar.wma-sp--pos-top .wma-sp__fill,
.wma-sp--bar.wma-sp--pos-bottom .wma-sp__fill {
	width: 0;
	height: 100%;
}
.wma-sp--bar.wma-sp--pos-left .wma-sp__fill,
.wma-sp--bar.wma-sp--pos-right .wma-sp__fill {
	width: 100%;
	height: 0;
}

/* The color layer inside the filler. Solid by default. No overflow
   clip here for solid/gradient (it would cut the glow); only RGB
   re-adds the clip below, where it is needed for the moving gradient. */
.wma-sp--bar .wma-sp__fill-inner {
	display: block;
	width: 100%;
	height: 100%;
	background: var(--wma-sp-color);
	border-radius: var(--wma-sp-radius);
}

/* Gradient: direction follows orientation. */
.wma-sp--bar.wma-sp--fill-gradient.wma-sp--pos-top .wma-sp__fill-inner,
.wma-sp--bar.wma-sp--fill-gradient.wma-sp--pos-bottom .wma-sp__fill-inner {
	background: linear-gradient(to right, var(--wma-sp-color), var(--wma-sp-color2));
}
.wma-sp--bar.wma-sp--fill-gradient.wma-sp--pos-left .wma-sp__fill-inner,
.wma-sp--bar.wma-sp--fill-gradient.wma-sp--pos-right .wma-sp__fill-inner {
	background: linear-gradient(to bottom, var(--wma-sp-color), var(--wma-sp-color2));
}

/* RGB: a smooth, refined spectrum that drifts on the inner layer
   (time-based, always running). The outer filler still scales with
   scroll, so the bar both fills AND shifts color. Compositor-safe
   (background-position). The palette is a clean, modern spectrum
   (system-style hues), not a harsh primary rainbow. */
.wma-sp--bar.wma-sp--fill-rgb.wma-sp--pos-top .wma-sp__fill-inner,
.wma-sp--bar.wma-sp--fill-rgb.wma-sp--pos-bottom .wma-sp__fill-inner {
	background: linear-gradient(90deg,
		#ff3b30, #ff9500, #ffcc00, #34c759, #007aff, #5856d6, #af52de, #ff3b30);
	background-size: 200% 100%;
	animation: wma-sp-rgb 8s linear infinite;
	overflow: hidden;
}
.wma-sp--bar.wma-sp--fill-rgb.wma-sp--pos-left .wma-sp__fill-inner,
.wma-sp--bar.wma-sp--fill-rgb.wma-sp--pos-right .wma-sp__fill-inner {
	background: linear-gradient(180deg,
		#ff3b30, #ff9500, #ffcc00, #34c759, #007aff, #5856d6, #af52de, #ff3b30);
	background-size: 100% 200%;
	animation: wma-sp-rgb-v 8s linear infinite;
	overflow: hidden;
}
@keyframes wma-sp-rgb   { to { background-position: 200% 0; } }
@keyframes wma-sp-rgb-v { to { background-position: 0 200%; } }

/* ============================================================
   STYLE: CIRCLE - the fill circle's stroke-dashoffset sweeps from
   full (empty) to zero (complete).
   ============================================================ */
.wma-sp--circle {
	width: var(--wma-sp-size);
	height: var(--wma-sp-size);
	display: flex;
	align-items: center;
	justify-content: center;
}
.wma-sp--circle.wma-sp--pos-bottom-right { bottom: 24px; right: 24px; }
.wma-sp--circle.wma-sp--pos-bottom-left  { bottom: 24px; left: 24px; }
.wma-sp--circle.wma-sp--pos-top-right    { top: 24px; right: 24px; }
.wma-sp--circle.wma-sp--pos-top-left     { top: 24px; left: 24px; }

.wma-sp__ring {
	width: 100%;
	height: 100%;
	transform: rotate(-90deg);
	overflow: visible;
}
.wma-sp__track-c {
	fill: none;
	stroke: var(--wma-sp-track);
	stroke-width: 7;
}
.wma-sp__fill-c {
	fill: none;
	stroke: var(--wma-sp-color);
	stroke-width: 7;
	stroke-linecap: butt;
	stroke-dasharray: 289.027;
	stroke-dashoffset: 289.027;
}
.wma-sp--round .wma-sp__fill-c { stroke-linecap: round; }

.wma-sp--circle.wma-sp--fill-gradient .wma-sp__fill-c { stroke: url(#wma-sp-grad); }
.wma-sp--circle.wma-sp--fill-rgb  .wma-sp__fill-c {
	stroke: url(#wma-sp-rgb-grad);
	animation: wma-sp-hue 8s linear infinite;
}
@keyframes wma-sp-hue { to { filter: hue-rotate(360deg); } }

.wma-sp__count {
	position: absolute;
	font-size: calc(var(--wma-sp-size) * 0.26);
	font-weight: 500;
	line-height: 1;
	color: var(--wma-sp-color);
	font-variant-numeric: tabular-nums;
}

/* ============================================================
   SHINE - optional. A subtle highlight that sweeps along the filled
   part of the bar, giving a premium, polished feel. Pure CSS, runs on
   a time-based loop using background-position (compositor-safe). Bar
   only; the circle stays clean. Stopped under reduced-motion.
   ============================================================ */
.wma-sp--shine.wma-sp--bar .wma-sp__fill-inner {
	position: relative;
	overflow: hidden;
}
.wma-sp--shine.wma-sp--bar .wma-sp__fill-inner::after {
	content: "";
	position: absolute;
	inset: 0;
	background: linear-gradient(
		var(--wma-sp-shine-angle, 90deg),
		transparent 0%,
		rgba(255, 255, 255, 0.55) 50%,
		transparent 100%
	);
	background-size: 220% 100%;
	background-repeat: no-repeat;
	mix-blend-mode: screen;
	animation: wma-sp-shine 2.6s ease-in-out infinite;
}
.wma-sp--shine.wma-sp--bar.wma-sp--pos-left .wma-sp__fill-inner::after,
.wma-sp--shine.wma-sp--bar.wma-sp--pos-right .wma-sp__fill-inner::after {
	--wma-sp-shine-angle: 180deg;
	background-size: 100% 220%;
}
@keyframes wma-sp-shine { from { background-position: -60% 0; } to { background-position: 160% 0; } }

/* ============================================================
   GLOW - optional. A soft halo in the bar's own color
   (--wma-sp-glow-color defaults to --wma-sp-color). Because a bar
   sits on a viewport edge, a symmetric glow would spill half off
   screen, so the halo is offset slightly INWARD per position (a top
   bar glows downward, a bottom bar upward, etc). One clean shadow,
   blur driven directly by the chosen intensity, so "Soft" reads soft.
   The color layer grows by width/height, so no scaling distorts it.
   ============================================================ */
.wma-sp--glow.wma-sp--bar.wma-sp--pos-top .wma-sp__fill-inner {
	box-shadow: 0 calc(var(--wma-sp-glow-blur) * 0.4) var(--wma-sp-glow-blur) calc(var(--wma-sp-glow-blur) * -0.25) var(--wma-sp-glow-color);
}
.wma-sp--glow.wma-sp--bar.wma-sp--pos-bottom .wma-sp__fill-inner {
	box-shadow: 0 calc(var(--wma-sp-glow-blur) * -0.4) var(--wma-sp-glow-blur) calc(var(--wma-sp-glow-blur) * -0.25) var(--wma-sp-glow-color);
}
.wma-sp--glow.wma-sp--bar.wma-sp--pos-left .wma-sp__fill-inner {
	box-shadow: calc(var(--wma-sp-glow-blur) * 0.4) 0 var(--wma-sp-glow-blur) calc(var(--wma-sp-glow-blur) * -0.25) var(--wma-sp-glow-color);
}
.wma-sp--glow.wma-sp--bar.wma-sp--pos-right .wma-sp__fill-inner {
	box-shadow: calc(var(--wma-sp-glow-blur) * -0.4) 0 var(--wma-sp-glow-blur) calc(var(--wma-sp-glow-blur) * -0.25) var(--wma-sp-glow-color);
}
.wma-sp--glow.wma-sp--circle .wma-sp__fill-c {
	filter: drop-shadow(0 0 calc(var(--wma-sp-glow-blur) * 0.8) var(--wma-sp-glow-color));
}

/* ============================================================
   THE ENGINE - bind the scale / sweep to a scroll-progress timeline.
   Only inside @supports so unsupported browsers no-op.
   ============================================================ */
@supports (animation-timeline: scroll()) {

	/* Bar fill scale, driven by the document scroll. */
	.wma-sp--bar .wma-sp__fill {
		animation-timeline: scroll(root block);
	}
	.wma-sp--bar.wma-sp--pos-top .wma-sp__fill,
	.wma-sp--bar.wma-sp--pos-bottom .wma-sp__fill {
		animation-name: wma-sp-grow-x;
		animation-timing-function: linear;
		animation-fill-mode: both;
	}
	.wma-sp--bar.wma-sp--pos-left .wma-sp__fill,
	.wma-sp--bar.wma-sp--pos-right .wma-sp__fill {
		animation-name: wma-sp-grow-y;
		animation-timing-function: linear;
		animation-fill-mode: both;
	}

	/* Circle sweep, driven by the document scroll. */
	.wma-sp--circle .wma-sp__fill-c {
		animation: wma-sp-sweep linear both;
		animation-timeline: scroll(root block);
	}

	/* Hide near the top: invisible at rest, fades in once scrolling
	   starts. Always tracks the document scroll. */
	.wma-sp--hide-top {
		animation: wma-sp-reveal steps(1, end) both;
		animation-timeline: scroll(root block);
		animation-range: 0 6%;
	}

	/* Live percentage (circle only), driven by the document scroll. */
	.wma-sp--has-count .wma-sp__count {
		animation-timeline: scroll(root block);
		counter-reset: wma-sp-pct var(--wma-sp-num);
		animation-name: wma-sp-count;
		animation-timing-function: linear;
		animation-fill-mode: both;
	}
	.wma-sp--has-count .wma-sp__count::after {
		content: counter(wma-sp-pct) '%';
	}
}

@keyframes wma-sp-grow-x { from { width: 0; }  to { width: 100%; } }
@keyframes wma-sp-grow-y { from { height: 0; } to { height: 100%; } }
@keyframes wma-sp-sweep  { from { stroke-dashoffset: 289.027; } to { stroke-dashoffset: 0; } }
@keyframes wma-sp-reveal { from { opacity: 0; } to { opacity: 1; } }

@property --wma-sp-num {
	syntax: '<integer>';
	inherits: true;
	initial-value: 0;
}
@keyframes wma-sp-count { from { --wma-sp-num: 0; } to { --wma-sp-num: 100; } }

/* ============================================================
   REDUCED MOTION - keep the positional fill (it reflects position,
   not decoration), but stop time-based motion: RGB spectrum, glow hue,
   numeric counter.
   ============================================================ */
@media (prefers-reduced-motion: reduce) {
	.wma-sp--fill-rgb .wma-sp__fill-inner,
	.wma-sp--circle.wma-sp--fill-rgb .wma-sp__fill-c { animation: none; }
	.wma-sp--shine.wma-sp--bar .wma-sp__fill-inner::after { animation: none; opacity: 0; }
	.wma-sp--has-count .wma-sp__count { animation: none; }
	.wma-sp--has-count .wma-sp__count::after { content: ''; }
}
