/* Sketch Suite — Preloader
   Full-screen pale wash, big 0–100% counter, progress bar along the bottom.

   The overlay is display:none by default and only revealed by html.skpl-on, which
   an inline head script adds. That ordering is deliberate: with JS disabled the
   class never lands, so the overlay never shows and can't trap anyone. */

.skpl {
	/* The /services hero wash, borrowed so the loading screen and the first
	   interior page a visitor lands on are the same surface. Kept in step with
	   modules/services-hero-list (--skshl-wash, defaults #ffffff → #dce9f7 at
	   340°), which in turn mirrors the project template's hero gradient. Unlike
	   the hero there is no mask here — the loader fills the whole viewport. */
	--skpl-grad-from: #ffffff;
	--skpl-grad-to: #dce9f7;
	--skpl-grad-angle: 340deg;
	/* Ink for a light ground — the about-hero/services palette. */
	--skpl-ink: #101326;
	--skpl-line: rgba(16, 19, 38, 0.10);
	/* The bar and the counter share one inset so they align to the same left
	   edge and float clear of the viewport corners — a bar pinned flush to the
	   bottom edge reads as browser chrome rather than as part of the page. */
	--skpl-inset-x: 5%;
	--skpl-inset-y: 5%;
	--skpl-bar-h: 6px;
	--skpl-bar-gap: 28px;    /* clearance between the counter and the bar */
	display: none;
}

html.skpl-on .skpl {
	position: fixed;
	inset: 0;
	z-index: 2147483000;      /* above sticky headers, chat widgets, cookie bars */
	display: block;
	background-color: var(--skpl-grad-from);
	background-image: linear-gradient(
		var(--skpl-grad-angle),
		var(--skpl-grad-from) 0%,
		var(--skpl-grad-to) 100%
	);
	/* The fill is opaque, so the blur only reads during the lift — see below. */
	-webkit-backdrop-filter: blur(30px) saturate(140%);
	backdrop-filter: blur(30px) saturate(140%);
	color: var(--skpl-ink);
	font-family: var(--sk-font, "Saans", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif);
	opacity: 1;
	transition:
		opacity 0.55s cubic-bezier(0.4, 0, 0.2, 1),
		-webkit-backdrop-filter 0.55s cubic-bezier(0.4, 0, 0.2, 1),
		backdrop-filter 0.55s cubic-bezier(0.4, 0, 0.2, 1);
}

/* Lift: the wash fades and the glass behind it clears at the same time, so the
   hero resolves into focus rather than the overlay simply vanishing. */
html.skpl-on .skpl.is-done {
	opacity: 0;
	pointer-events: none;
	-webkit-backdrop-filter: blur(0) saturate(100%);
	backdrop-filter: blur(0) saturate(100%);
}

/* Scroll lock while the loader is up. */
html.skpl-lock,
html.skpl-lock body {
	overflow: hidden !important;
}

/* Counter sits in the bottom-left, riding directly above the bar and flush to
   its left end. */
.skpl__inner {
	position: absolute;
	left: var(--skpl-inset-x);
	bottom: calc(var(--skpl-inset-y) + var(--skpl-bar-h) + var(--skpl-bar-gap));
	display: flex;
	flex-direction: column;
	align-items: flex-start;
	gap: 6px;
	transition: opacity 0.4s ease, transform 0.55s cubic-bezier(0.4, 0, 0.2, 1);
}

.skpl.is-done .skpl__inner {
	opacity: 0;
	transform: translateY(10px);
}

.skpl__count {
	display: flex;
	align-items: baseline;
	font-size: clamp(84px, 17vw, 260px);
	/* 400 is as light as this reads well at — Saans goes down to 300, loaded at
	   wght@400..700, and the typeface has no thinner cut. */
	font-weight: 400;
	line-height: 0.82;
	letter-spacing: -0.055em;
}

/* Tabular figures so the digits don't jitter as they count. No reserved width —
   that leaves the % stranded away from a two-digit number; the one-off nudge
   when it reaches 100 is far less noticeable than a permanent gap. */
.skpl__num {
	font-variant-numeric: tabular-nums;
	font-feature-settings: "tnum" 1;
}

.skpl__pct {
	font-size: 0.34em;
	font-weight: 400;
	letter-spacing: -0.02em;
	opacity: 0.5;
}

.skpl__caption {
	margin: 0;
	padding-left: 0.15em;
	font-size: clamp(11px, 1vw, 13px);
	font-weight: 500;
	letter-spacing: 0.18em;
	text-transform: uppercase;
	opacity: 0.6;
}

/* Bar floating above the bottom edge, inset from both sides — directly under
   the counter, which shares its left edge. `width` is deliberately left alone:
   setting it alongside left/right would win over the right inset and stretch
   the track back to full bleed. */
.skpl__track {
	position: absolute;
	left: var(--skpl-inset-x);
	right: var(--skpl-inset-x);
	bottom: var(--skpl-inset-y);
	height: var(--skpl-bar-h);
	border-radius: 999px;
	background: var(--skpl-line);
	/* Rounds the ends of the bar too, rather than the bar carrying its own
	   radius — the scaleX that drives it would squash that into an oval. */
	overflow: hidden;
}

.skpl__bar {
	display: block;
	width: 100%;
	height: 100%;
	transform: scaleX(0);
	transform-origin: left center;
	background: var(--skpl-accent, #6647ff);
	/* Half the glow it carried on the dark ground — bloom that read as light on
	   near-black just reads as a purple smudge on a near-white wash. */
	box-shadow: 0 0 12px color-mix(in srgb, var(--skpl-accent, #6647ff) 45%, transparent);
}

/* Only the closing snap to 100% is transitioned — the run itself is driven
   frame by frame, where a transition would just add lag. */
.skpl.is-finishing .skpl__bar {
	transition: transform 0.28s cubic-bezier(0.33, 1, 0.68, 1);
}

/* Thinner bar and a tighter gap on phones — set on the vars so the counter's
   offset follows the bar up rather than drifting away from it. */
@media (max-width: 768px) {
	.skpl {
		--skpl-bar-h: 3px;
		--skpl-bar-gap: 20px;
	}
}

/* Belt and braces — the head script already skips the loader entirely here. */
@media (prefers-reduced-motion: reduce) {
	html.skpl-on .skpl { display: none; }
	html.skpl-lock,
	html.skpl-lock body { overflow: auto !important; }
}

@media print {
	.skpl { display: none !important; }
}
