/* Sketch Suite — Logo Grid
   A centred "who are we" intro (dark pointer pill + short paragraph) above rows
   of client-logo cards that drift past, each row running against the one above.
   Every logo is contained inside an identical card, so mixed aspect ratios still
   read as an even wall of marks.
*/

.sklg {
	box-sizing: border-box;
	/* Break out of any constrained content container so the section background
	   and the drifting rows span the full viewport width wherever it's used. */
	position: relative;
	width: 100vw;
	left: 50%;
	right: 50%;
	margin-left: -50vw;
	margin-right: -50vw;
	padding: var(--sklg-pad-top, 96px) 0 var(--sklg-pad-bottom, 96px);
	background: var(--sklg-bg, #ffffff);
	color: var(--sklg-fg, #0b0b0b);
	font-family: var(--sk-font, "Saans", system-ui, -apple-system, "Segoe UI", Roboto, sans-serif);
	/* Belt-and-braces full bleed: paint the background out past the box so a
	   constrained parent's own background can't show at the left/right edges. */
	box-shadow: 0 0 0 100vmax var(--sklg-bg, #ffffff);
	clip-path: inset(0 -100vmax);
	/* Uniform shrink for small screens. Card width, gap and the track's travel
	   distance all scale by this together, so the loop stays seamless. */
	--sklg-scale: 1;
}
.sklg *,
.sklg *::before,
.sklg *::after { box-sizing: border-box; }

/* Shared container for everything in the section. Deliberately the same
   max-width and side padding as the case-study grid (`modules/case-study-grid`,
   `--skcsg-max` / `clamp(20px, 4vw, 48px)`), so the two stack up flush on the
   home page. Only the section background runs to the edges of the screen. */
.sklg__inner,
.sklg__rows {
	max-width: var(--sklg-content-max, 1440px);
	margin: 0 auto;
	padding: 0 clamp(20px, 4vw, 48px);
	/* Above the decorative tiles, so they can tuck behind the copy. */
	position: relative;
	z-index: 1;
}

/* ── Team tiles ───────────────────────────────────────────────
   Three tilted photo tiles either side of the intro, stacked loosely and
   hanging off the edge of the screen. Decorative: aria-hidden, and they sit
   behind the text so a tile can never take a click meant for a link.

   The layer covers its host section, so anchoring the clusters to its
   left/right edge is what puts them off the side of the page — they don't need
   to know anything about the 1440px container the rest of the section uses.
   That holds for any full-bleed host: `SKLG_Plugin::render_tiles()` drops the
   same layer into the careers hero, which is why these rules are written
   against the layer rather than against `.sklg`. */

.sklg-tiles {
	position: absolute;
	inset: 0;
	z-index: 0;
	/* Only the tiles themselves are interactive; the layer covers the whole
	   section, so it must never take a click meant for the copy under it. */
	pointer-events: none;
}

.sklg__cluster {
	position: absolute;
	/* Offset from where the *content* starts, not from the section's padding box.
	   An absolutely positioned child resolves `top` against the padding box, so
	   without adding the section's own top padding the tiles would stay put while
	   the copy moved down every time that padding changed. */
	top: calc(var(--sklg-pad-top, 96px) + var(--sklg-tile-top, 10px));
	z-index: 0;
	width: calc(var(--sklg-tile, 176px) * 1.95);
	height: calc(var(--sklg-tile, 176px) * 2.0);
	/* Only the tiles themselves are interactive; the empty cluster box isn't,
	   so it can overlap the paragraph's bounding box harmlessly. */
	pointer-events: none;
}
.sklg__cluster--left  { left: calc(var(--sklg-tile, 176px) * -0.34); }
.sklg__cluster--right { right: calc(var(--sklg-tile, 176px) * -0.34); }

.sklg__tile-wrap {
	position: absolute;
	top: var(--sklg-t-top, 0);
	pointer-events: auto;
}
.sklg__cluster--left  .sklg__tile-wrap { left: var(--sklg-t-side, 0); }
.sklg__cluster--right .sklg__tile-wrap { right: var(--sklg-t-side, 0); }

/* The wrapper is the reveal target and the tile owns the tilt — Sketch Reveal's
   `.sk-in { transform: none }` would otherwise flatten every tile on entrance. */
.sklg__tile {
	position: relative;
	width: var(--sklg-tile, 176px);
	height: var(--sklg-tile, 176px);
	border-radius: var(--sklg-tile-radius, 30px);
	overflow: hidden;
	background: #e9e9e7;
	box-shadow: 0 18px 40px -22px rgba(0, 0, 0, 0.55);
	transform: rotate(var(--sklg-t-rot, 0deg));
	transition:
		transform 620ms cubic-bezier(0.22, 1, 0.36, 1),
		box-shadow 620ms ease;
}

/* Doubled-up selector on purpose — don't "simplify" it to one class. BeTheme's
   be.css has `.scale-with-grid, .content_wrapper img { height: auto }`, and
   `.content_wrapper img` (0,1,1) outranks a single class (0,1,0). The photo then
   keeps its own aspect ratio and the tile letterboxes. Any image in this suite
   that has to fill a box needs to clear that bar. */
.sklg__tile .sklg__tile-img {
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
	max-width: none;
	object-fit: cover;
	object-position: center;
	display: block;
	/* Resting state of the *outgoing* layer. Both scales stay at or above 1 so a
	   growing photo never pulls its edges in and flashes the tile background —
	   the old one expands out of frame as the new one settles in behind it. */
	opacity: 0;
	transform: scale(1.16);
	transition:
		opacity 760ms ease,
		transform 760ms cubic-bezier(0.22, 0.7, 0.3, 1);
}
.sklg__tile .sklg__tile-img.is-on {
	opacity: 1;
	transform: scale(1);
}

/* Hover.

   The hit target has to be the TILE, not its wrapper. The wrapper is an
   unrotated square; the tile inside it is rotated, so the two don't cover the
   same pixels — near the corners you get wrapper with no tile under the cursor,
   and tile with no wrapper. Worse, the three wrappers overlap, so a wrapper
   sitting later in the DOM would swallow hovers meant for the tile visible
   beneath it. Hovering the rotated element itself matches what you can see,
   because a rotated box hit-tests as rotated. That's the "sometimes it works,
   sometimes it doesn't". */
.sklg__tile-wrap { pointer-events: none; }
.sklg__tile { pointer-events: auto; }

/* The other half of the problem: .sklg__inner is a full-container-width block
   sitting at z-index 1, directly over the clusters. Its *empty* area was
   swallowing every hover aimed at a tile — which is why the two tiles nearest
   the copy were completely dead. So the text column passes pointer events
   through everywhere except on the actual inline content. */
.sklg__inner,
.sklg__head,
.sklg__pill,
.sklg__intro,
.sklg__more-wrap { pointer-events: none; }

.sklg__bubble,
.sklg__word,
.sklg__more { pointer-events: auto; }

/* :has() lets the wrapper react to its own tile being hovered, and the cluster
   to any of its tiles. Without :has() support the hovered tile still lifts —
   only the stacking and the fan drop out. */
.sklg__tile-wrap:has(.sklg__tile:hover) { z-index: 3; }

.sklg__tile:hover {
	transform: rotate(0deg) scale(1.16) translateY(-16px);
	box-shadow: 0 40px 70px -24px rgba(0, 0, 0, 0.62);
	transition:
		transform 380ms cubic-bezier(0.34, 1.4, 0.5, 1),
		box-shadow 380ms ease;
}

/* The other two in that stack get out of the way rather than just sitting there. */
.sklg__cluster:has(.sklg__tile:hover) .sklg__tile:not(:hover) {
	transform:
		rotate(calc(var(--sklg-t-rot, 0deg) * 1.7))
		translate(var(--sklg-t-fx, 0), var(--sklg-t-fy, 0))
		scale(0.95);
}

@media (prefers-reduced-motion: reduce) {
	.sklg__tile { transition: none; }
	.sklg__tile:hover,
	.sklg__cluster:has(.sklg__tile:hover) .sklg__tile:not(:hover) {
		transform: rotate(var(--sklg-t-rot, 0deg));
	}
	.sklg__tile .sklg__tile-img { transition: none; }
}

/* ── Intro ────────────────────────────────────────────────── */

.sklg__head {
	text-align: center;
	/* Generous, so the supporting line has room to breathe before the logo rows
	   start — without it the two read as one block. */
	margin: 0 0 clamp(52px, 6.5vw, 94px);
}

/* The pill is two elements: an outer <p> that Sketch Reveal transitions in, and
   an inner bubble carrying the look and the wobble. They can't be the same
   element — reveal transitions `transform`, and the wobble animates it. */
.sklg__pill {
	margin: 0 0 clamp(22px, 2.6vw, 34px);
}

.sklg__bubble {
	position: relative;
	display: inline-block;
	padding: 9px 18px 10px;
	border-radius: 10px;
	background: var(--sklg-pill-bg, #8b6cff);
	color: var(--sklg-pill-fg, #ffffff);
	font-size: 15px;
	font-weight: 500;
	line-height: 1.2;
	letter-spacing: -0.005em;
	/* Pivot on the tail, so a wobble reads as a sign swinging on its pin. */
	transform-origin: 50% 100%;
}
/* Speech-bubble tail, pointing down at the paragraph. */
.sklg__bubble::after {
	content: "";
	position: absolute;
	top: 100%;
	left: 50%;
	transform: translateX(-50%);
	border-left: 9px solid transparent;
	border-right: 9px solid transparent;
	border-top: 9px solid var(--sklg-pill-bg, #8b6cff);
}

/* Wobble on arrival, then again every cycle. The shake occupies only the first
   fifth of the keyframes and the rest is rest, which is what puts the ~3s pause
   between shakes without needing a second animation or any JS. The delay lets
   the reveal land first. */
.sklg__pill--wobble.sk-in .sklg__bubble {
	animation: sklg-wobble 4s ease-in-out 0.45s infinite;
}

@keyframes sklg-wobble {
	0%   { transform: rotate(0deg); }
	2%   { transform: rotate(-4.5deg); }
	5%   { transform: rotate(3.6deg); }
	8%   { transform: rotate(-2.6deg); }
	11%  { transform: rotate(1.7deg); }
	14%  { transform: rotate(-1deg); }
	17%  { transform: rotate(0.5deg); }
	20%  { transform: rotate(0deg); }
	100% { transform: rotate(0deg); }
}

@media (prefers-reduced-motion: reduce) {
	.sklg__pill--wobble.sk-in .sklg__bubble { animation: none; }
}

/* The statement. An <h2>, so it picks up Saans from the suite-wide
   heading rule and reads as a headline rather than a long paragraph. */
.sklg__intro {
	max-width: var(--sklg-intro-max, 1120px);
	margin: 0 auto;
	font-size: clamp(26px, 3.4vw, var(--sklg-intro-size, 46px));
	font-weight: 500;
	line-height: 1.14;
	letter-spacing: -0.025em;
	text-wrap: balance;
}

/* The supporting line. Deliberately a much shorter measure than the statement —
   the narrower column is what makes it read as support rather than a second
   headline — and set back a little so the statement keeps the weight. */
.sklg__sub {
	max-width: var(--sklg-sub-max, 720px);
	margin: clamp(18px, 2vw, 26px) auto 0;
	font-size: clamp(16px, 1.35vw, var(--sklg-sub-size, 19px));
	font-weight: 400;
	line-height: 1.6;
	letter-spacing: -0.005em;
	color: color-mix(in srgb, var(--sklg-fg, #0b0b0b) 66%, transparent);
	text-wrap: pretty;
}

/* Secondary button. Neutral fill rather than the brand purple, matching the
   Intro Section's secondary CTA — the purple is spoken for by the pill above it,
   and two purple elements this close would fight. The arrow points down because
   this scrolls the page rather than navigating away. */
.sklg__cta-wrap {
	margin: clamp(24px, 2.6vw, 34px) 0 0;
	pointer-events: none; /* the empty block shouldn't eat tile hovers */
}

.sklg__cta {
	display: inline-flex;
	align-items: center;
	gap: 9px;
	padding: 14px 24px;
	border-radius: 999px;
	background: #f1f1f4;
	color: var(--sklg-fg, #0b0b0b);
	font-size: 15px;
	font-weight: 600;
	line-height: 1;
	text-decoration: none;
	pointer-events: auto;
	transition:
		background-color 260ms ease,
		transform 260ms cubic-bezier(0.22, 1, 0.36, 1);
}

.sklg__cta:hover,
.sklg__cta:focus-visible {
	background: #e6e6ec;
	transform: translateY(-2px);
}

.sklg__cta-arrow {
	flex: 0 0 auto;
	transition: transform 260ms cubic-bezier(0.22, 1, 0.36, 1);
}
.sklg__cta:hover .sklg__cta-arrow,
.sklg__cta:focus-visible .sklg__cta-arrow {
	transform: translateY(3px);
}

.sklg__cta:focus-visible {
	outline: 3px solid var(--sklg-pill-bg, #8b6cff);
	outline-offset: 3px;
}

@media (prefers-reduced-motion: reduce) {
	.sklg__cta,
	.sklg__cta-arrow { transition: none; }
	.sklg__cta:hover { transform: none; }
	.sklg__cta:hover .sklg__cta-arrow { transform: none; }
}

.sklg__intro a,
.sklg__sub a {
	color: inherit;
	text-decoration: underline;
	text-underline-offset: 3px;
}

/* Each word reveals on its own, a beat after the last. inline-block is what
   makes them animatable; the whitespace between them is left as real text
   nodes, so wrapping and word spacing are untouched. The shorter duration
   keeps the sentence from taking too long to finish arriving. */
.sklg__word {
	display: inline-block;
	--sk-duration: 0.5s;
}

/* ── Colour sweep ─────────────────────────────────────────────
   Ported from the Fit Finder landing-page hero. A gradient runs through the
   paragraph one line at a time — each line goes text colour → gradient → text
   colour, 620ms behind the line above. grid.js measures the wrapped lines and
   wraps each in .sklg__line, then adds .is-lit once the words have landed.

   Clipped on the LINE, not the word: per-word clipping restarts the gradient at
   every word boundary, which reads as words changing colour rather than one
   sweep passing through the text.

   NOTE: the shared primitive now exists — modules/sweep (`data-sk-sweep`),
   extracted when the Blog Post hero became the fourth use. This copy is
   unchanged and still runs its own code; migrating it onto the module is a
   rename away. Until then a change to the effect has to be made here as well. */
.sklg__line { display: block; }

@supports ((-webkit-background-clip: text) or (background-clip: text)) {
	.sklg__intro.is-lit .sklg__word {
		/* Load-bearing, not tidying. A composited descendant's glyphs don't
		   contribute to an ancestor's background-clip: text, and Sketch Reveal
		   leaves `will-change: opacity, transform` on every word it handles — so
		   the line would clip to nothing and the paragraph would vanish. Dropping
		   the compositing hint (and settling what the transition was holding)
		   puts the glyphs back into the clip. */
		will-change: auto;
		transition: none;
		opacity: 1;
		transform: none;
		-webkit-text-fill-color: transparent;
		color: transparent;
	}

	.sklg__intro.is-lit .sklg__line {
		background-image: linear-gradient(100deg,
			var(--sklg-fg, #0b0b0b) 0%, var(--sklg-fg, #0b0b0b) 38%,
			var(--sklg-sweep-a, #6d46ff) 46%, var(--sklg-sweep-b, #24b6ff) 54%,
			var(--sklg-fg, #0b0b0b) 62%, var(--sklg-fg, #0b0b0b) 100%);
		background-size: 300% 100%;
		background-repeat: no-repeat;
		-webkit-background-clip: text;
		background-clip: text;
		animation: sklg-sweep 6s linear infinite;
		animation-delay: calc(var(--sklg-l, 0) * 620ms);
	}
}

/* At 0% the visible slice of the 300%-wide layer is its first third and at 100%
   its last — both entirely inside the flat runs, so a line rests in the plain
   text colour rather than faintly tinted. The colour only crosses during the
   first 35% of the cycle (~2.1s); the rest is rest.

   Runs 100% → 0%, not 0% → 100%: raising background-position shifts an oversized
   layer *left*, so counting up would send the colour right to left. Counting
   down travels left to right, with the reading order and the word entrance. */
@keyframes sklg-sweep {
	0%   { background-position: 100% 0; }
	35%  { background-position: 0% 0; }
	100% { background-position: 0% 0; }
}

@media (prefers-reduced-motion: reduce) {
	/* Drop the clip too, not just the animation — a frozen sweep would park a
	   band of colour mid-line. */
	.sklg__intro.is-lit .sklg__word {
		-webkit-text-fill-color: var(--sklg-fg, #0b0b0b);
		color: var(--sklg-fg, #0b0b0b);
	}
	.sklg__intro.is-lit .sklg__line {
		background-image: none;
		animation: none;
	}
}

/* ── Drifting rows ────────────────────────────────────────── */

.sklg__rows {
	display: flex;
	flex-direction: column;
	gap: calc(var(--sklg-gap, 10px) * var(--sklg-scale, 1));
}

.sklg__row {
	position: relative;
	overflow: hidden;
	/* Dissolve each row into the section background at the left and right, so
	   the cards arrive and leave rather than being cut off at the edge. */
	-webkit-mask-image: linear-gradient(
		to right,
		transparent 0,
		#000 var(--sklg-fade, 180px),
		#000 calc(100% - var(--sklg-fade, 180px)),
		transparent 100%
	);
	mask-image: linear-gradient(
		to right,
		transparent 0,
		#000 var(--sklg-fade, 180px),
		#000 calc(100% - var(--sklg-fade, 180px)),
		transparent 100%
	);
}

.sklg__track {
	display: flex;
	align-items: center;
	gap: calc(var(--sklg-gap, 10px) * var(--sklg-scale, 1));
	/* Trailing gap so the hand-off from set one to set two is evenly spaced. */
	padding-right: calc(var(--sklg-gap, 10px) * var(--sklg-scale, 1));
	width: max-content;
	will-change: transform;
	animation: sklg-drift var(--sklg-duration, 60s) linear infinite;
}

.sklg__row--right .sklg__track { animation-direction: reverse; }

@keyframes sklg-drift {
	from { transform: translate3d(0, 0, 0); }
	to   { transform: translate3d(calc(-1 * var(--sklg-set-w) * var(--sklg-scale, 1)), 0, 0); }
}

.sklg__row:hover .sklg__track { animation-play-state: paused; }

@media (prefers-reduced-motion: reduce) {
	.sklg__track { animation: none; }
}

/* ── Cards ────────────────────────────────────────────────── */

.sklg__card {
	flex: 0 0 auto;
	display: flex;
	align-items: center;
	justify-content: center;
	width: calc(var(--sklg-card-w, 240px) * var(--sklg-scale, 1));
	height: calc(var(--sklg-card-h, 104px) * var(--sklg-scale, 1));
	padding: 14px 12px;
	border: 1px solid var(--sklg-card-border, #e9e9e7);
	border-radius: var(--sklg-card-radius, 14px);
	background: var(--sklg-card-bg, #ffffff);
}

.sklg__logo {
	display: block;
	width: auto;
	height: auto;
	max-width: var(--sklg-logo-max-w, 70%);
	max-height: calc(var(--sklg-logo-max-h, 54px) * var(--sklg-scale, 1));
	object-fit: contain;
}

.sklg--mono .sklg__logo { filter: grayscale(1); }

/* ── "+ Many more" pill ───────────────────────────────────── */

.sklg__more-wrap {
	margin-top: clamp(28px, 3.5vw, 44px);
	text-align: center;
}

.sklg__more {
	display: inline-flex;
	align-items: center;
	padding: 11px 20px;
	border-radius: 999px;
	background: var(--sklg-more-bg, #eaf9cf);
	color: var(--sklg-more-fg, #3f5c10);
	font-size: 15px;
	font-weight: 500;
	line-height: 1.2;
	text-decoration: none;
	white-space: nowrap;
}
a.sklg__more {
	transition: transform 0.25s cubic-bezier(0.22, 0.61, 0.36, 1), filter 0.25s ease;
}
a.sklg__more:hover,
a.sklg__more:focus-visible {
	transform: translateY(-2px);
	filter: brightness(0.96);
}

/* ── Responsive ───────────────────────────────────────────── */

/* Below this the tiles would crowd the paragraph rather than frame it. */
@media (max-width: 1240px) {
	.sklg__cluster { display: none; }
}

@media (max-width: 1440px) {
	.sklg { --sklg-tile: 148px; }
}

@media (max-width: 860px) {
	.sklg { --sklg-scale: 0.82; }
	.sklg__row {
		-webkit-mask-image: linear-gradient(
			to right,
			transparent 0,
			#000 calc(var(--sklg-fade, 180px) * 0.45),
			#000 calc(100% - var(--sklg-fade, 180px) * 0.45),
			transparent 100%
		);
		mask-image: linear-gradient(
			to right,
			transparent 0,
			#000 calc(var(--sklg-fade, 180px) * 0.45),
			#000 calc(100% - var(--sklg-fade, 180px) * 0.45),
			transparent 100%
		);
	}
}

@media (max-width: 560px) {
	.sklg { --sklg-scale: 0.68; }
	.sklg__pill { font-size: 14px; }
	.sklg__more {
		padding: 9px 15px;
		font-size: 14px;
	}
}
