/* Sketch Suite — Services Footer  ([sketch_services_footer]).

   The band that closes the Services Accordion: two equal cards. An "Explore
   more services" CTA under a soft gradient wash on the left, "Tools and
   workflows" on the right with the tool marks running past as white tiles.

   Design system, borrowed rather than re-decided — the accordion's, which is
   the /services hero index's:
     · ink #101326, eyebrows #98a2b3, hairlines rgba(16,19,38,.10),
       indigo #6552ff
     · type via var(--sk-font) (Saans) — never a literal family name
     · entrance is the shared Sketch Reveal primitive (data-sk-reveal)

   The marquee is CSS only: the track carries the set twice and slides exactly
   one set's width, which PHP works out from the tile size and count. Nothing
   to measure, so nothing to re-measure on resize.                            */

.sksf {
	--sksf-fg: #101326;
	--sksf-muted: #101326;
	--sksf-label: #98a2b3;
	--sksf-line: rgba(16, 19, 38, 0.10);
	--sksf-accent: #6552ff;
	--sksf-bg: #ffffff;
	--sksf-card-bg: #f7f7f7;
	--sksf-tile-bg: #ffffff;
	--sksf-badge-bg: #f4511e;
	--sksf-grad-a: #a9d5f4;
	--sksf-grad-b: #f2c9e2;
	--sksf-grad-c: #fbd6a0;
	--sksf-max: 1180px;
	--sksf-gutter: clamp(20px, 4vw, 48px);
	--sksf-pad-top: 72px;
	--sksf-pad-bottom: 96px;
	--sksf-col-gap: 20px;
	--sksf-card-radius: 18px;
	/* One value for the card's inset, because the marquee has to cancel it
	   exactly to reach the card's edges. */
	--sksf-card-pad: clamp(26px, 3.2vw, 44px);
	--sksf-mark-h: 52px;
	--sksf-tile: 88px;
	--sksf-gap: 14px;
	--sksf-radius: 12px;
	--sksf-duration: 44s;

	position: relative;
	box-sizing: border-box;
	/* Full-bleed breakout from the builder's centred content column, exactly as
	   the accordion above does — otherwise the cards wouldn't line up with its
	   rows. */
	width: 100vw;
	max-width: 100vw;
	margin-left: calc(50% - 50vw);
	margin-right: calc(50% - 50vw);
	padding: var(--sksf-pad-top) 0 var(--sksf-pad-bottom);
	background: var(--sksf-bg);
	color: var(--sksf-fg);
	font-family: var(--sk-font, "Saans", system-ui, -apple-system, "Segoe UI", Roboto, sans-serif);
}

.sksf *,
.sksf *::before,
.sksf *::after { box-sizing: border-box; }

.sksf__inner {
	display: grid;
	grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
	gap: var(--sksf-col-gap);
	/* Stretch, so the two cards are the same height whatever is in them and the
	   links along their bottoms sit on one line. */
	align-items: stretch;
	max-width: var(--sksf-max);
	margin: 0 auto;
	padding: 0 var(--sksf-gutter);
}

/* One card configured — it takes the full column rather than sitting in half
   of a grid it no longer shares. */
.sksf--single .sksf__inner { grid-template-columns: minmax(0, 1fr); }

/* The rule belongs to the *content* column, not the full-bleed section, so it
   lines up exactly with the accordion's own hairlines above it. Off by default:
   the cards already give the band an edge. */
.sksf--ruled .sksf__inner {
	border-top: 1px solid var(--sksf-line);
	padding-top: var(--sksf-card-pad);
}

/* ── The cards ────────────────────────────────────────────── */

.sksf-card {
	position: relative;
	display: flex;
	flex-direction: column;
	align-items: center;
	min-height: clamp(360px, 30vw, 440px);
	padding: var(--sksf-card-pad);
	border-radius: var(--sksf-card-radius);
	background: var(--sksf-card-bg);
	text-align: center;
	/* Clips the wash to the card's corners and, on the right, gives the marquee
	   the hard edge it runs out through. */
	overflow: hidden;
	isolation: isolate;
}

/* The gradient bloom across the top of the CTA card. Its own layer rather than
   a background on the card, so it can fade to nothing without dragging the
   card's colour with it. Three radials rather than one linear: they overlap
   into each other the way the source artwork does, where a linear ramp would
   band. */
.sksf-card__wash {
	position: absolute;
	inset: 0 0 auto;
	z-index: 0;
	height: 52%;
	/* Each radial stays near its own anchor — wide enough that the three
	   overlap into a continuous band along the top edge, tight enough that none
	   of them washes across the whole card. */
	background:
		radial-gradient(64% 124% at 0% -10%, var(--sksf-grad-a) 0%, transparent 74%),
		radial-gradient(58% 122% at 42% -12%, var(--sksf-grad-b) 0%, transparent 74%),
		radial-gradient(70% 126% at 100% -8%, var(--sksf-grad-c) 0%, transparent 72%);
	/* Holds full strength through the top quarter, then is gone well before the
	   heading — the wash is a light source above the card, not a panel on it. */
	-webkit-mask-image: linear-gradient(to bottom, #000 0%, #000 26%, transparent 92%);
	mask-image: linear-gradient(to bottom, #000 0%, #000 26%, transparent 92%);
	pointer-events: none;
}

/* Everything else sits over the wash. Named rather than `> *:not(.wash)`,
   which outranks the badge's own rule and flips it back to position: relative. */
.sksf-card__body,
.sksf__stage,
.sksf-card__link { position: relative; }

.sksf-card__badge,
.sksf-card__body,
.sksf__stage,
.sksf-card__link { z-index: 1; }

.sksf-card__badge {
	position: absolute;
	top: var(--sksf-card-pad);
	right: var(--sksf-card-pad);
	padding: 8px 12px;
	border-radius: 4px;
	background: var(--sksf-badge-bg);
	color: #ffffff;
	font-size: 12px;
	font-weight: 600;
	letter-spacing: .07em;
	line-height: 1;
	text-transform: uppercase;
	white-space: nowrap;
}

.sksf-card__body {
	display: flex;
	flex-direction: column;
	align-items: center;
	width: 100%;
}

/* The CTA card has nothing between its copy and its link, so the copy takes the
   slack and centres in it. */
.sksf-card--cta .sksf-card__body {
	flex: 1 1 auto;
	justify-content: center;
}

/* The badge is out of flow, so the centred body would otherwise happily settle
   underneath it — most visibly when the marks row wraps. This reserves its
   corner: the body still centres, just in the space left below it.

   A flat value rather than a clamp — the badge is a fixed height at every
   width, so clearance that shrinks with the viewport stops clearing it. */
.sksf-card--badged .sksf-card__body { padding-top: 38px; }

/* The tools card reads top-down instead: copy at the top, tiles pushed to the
   foot of the card by the marquee's own auto margin below. */
.sksf-card--tools .sksf-card__body { flex: 0 0 auto; }

.sksf-card__eyebrow {
	margin: 0 0 clamp(12px, 1.4vw, 18px);
	font-size: clamp(12px, .85vw, 14px);
	font-weight: 500;
	letter-spacing: .14em;
	line-height: 1.2;
	text-transform: uppercase;
	color: var(--sksf-label);
}

/* Scoped past the theme's own h3 sizing/margins. */
.sksf .sksf-card__title {
	margin: 0;
	padding: 0;
	font-family: var(--sk-font-heading, var(--sk-font, "Saans", system-ui, sans-serif));
	font-size: clamp(26px, 2.9vw, 42px);
	font-weight: 700;
	letter-spacing: -0.022em;
	line-height: 1.08;
	color: var(--sksf-fg);
	text-wrap: balance;
}

.sksf .sksf-card__intro {
	margin: clamp(12px, 1.4vw, 18px) 0 0;
	max-width: 42ch;
	font-size: clamp(16px, 1.3vw, 20px);
	font-weight: 400;
	line-height: 1.45;
	color: var(--sksf-muted);
	/* Two even lines rather than a long one and an orphan. */
	text-wrap: balance;
}

/* ── The card link ────────────────────────────────────────── */

/* Pinned to the foot of the card, so both cards' links sit on one line. */
.sksf .sksf-card__link {
	display: inline-flex;
	align-items: center;
	gap: 9px;
	margin-top: clamp(22px, 2.6vw, 36px);
	padding-bottom: 5px;
	border-bottom: 1.5px solid currentColor;
	color: var(--sksf-fg);
	font-size: clamp(15px, 1.05vw, 17px);
	font-weight: 500;
	line-height: 1.2;
	text-decoration: none;
	transition: color 240ms ease;
}

/* No tiles configured, so nothing above the link is taking the slack — the link
   takes it itself and stays on the card's foot. Not on the CTA card, whose body
   already has flex: 1 and would leave the auto margin nothing to resolve to. */
.sksf .sksf-card--tools .sksf-card__body + .sksf-card__link { margin-top: auto; }

.sksf-card__arrow { transition: transform 320ms cubic-bezier(0.22, 1, 0.36, 1); }

.sksf .sksf-card__link:hover,
.sksf .sksf-card__link:focus-visible { color: var(--sksf-accent); }

.sksf-card__link:hover .sksf-card__arrow,
.sksf-card__link:focus-visible .sksf-card__arrow { transform: translateX(4px); }

.sksf .sksf-card__link:focus-visible {
	outline: 2px solid var(--sksf-accent);
	outline-offset: 4px;
}

/* ── The CTA card's still marks ───────────────────────────── */

/* Scoped past the theme's `ul { margin-left: 30px }` and its `li` bullets. */
.sksf .sksf-card__marks {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	justify-content: center;
	gap: clamp(22px, 3vw, 44px);
	margin: 0 0 clamp(20px, 2.4vw, 34px);
	padding: 0;
	list-style: none;
}

.sksf .sksf-card__mark {
	display: flex;
	align-items: center;
	list-style: none;
	margin: 0;
	padding: 0;
}

/* Doubled-up selector for the same theme reason as everywhere else here: the
   theme's own `img` rules (max-width / height:auto) otherwise win and the mark
   stops sitting to its box. */
/* Capped as well as sized: these are meant to be marks, and one wide wordmark
   left to its natural width takes the whole row and wraps the rest under it.
   The cap letterboxes rather than squashes, because of object-fit. */
.sksf .sksf-card__mark-img {
	display: block;
	width: auto;
	height: var(--sksf-mark-h);
	max-width: min(150px, 100%);
	object-fit: contain;
}

/* ── The hosting animation ────────────────────────────────── */

/* A cloud with deploys rising into it off a baseline: the card's own sentence,
   "from vibe code to live website", as one small picture. Drawn rather than
   an image so it takes the ink colour, scales without a second asset, and
   costs no request.

   Every moving part is a transform or an opacity — no layout property is
   animated, so the loop stays on the compositor and can't reflow the card
   underneath it. */
.sksf-cloud {
	display: flex;
	justify-content: center;
	margin: 0 0 clamp(20px, 2.4vw, 34px);
	color: var(--sksf-fg);
}

.sksf .sksf-cloud__art {
	display: block;
	width: auto;
	height: var(--sksf-cloud-h, 96px);
	max-width: 100%;
	overflow: visible;
}

/* The cloud breathes; the deploys keep their own rhythm, so the drift reads as
   the cloud floating rather than the whole drawing wobbling. */
.sksf-cloud__body {
	animation: sksf-cloud-float 4600ms ease-in-out infinite;
}

/* The deploy rises off the bottom and is absorbed by the cloud's base. */
.sksf-cloud__lift {
	animation: sksf-cloud-lift 2200ms cubic-bezier(0.4, 0, 0.2, 1) infinite;
}

@keyframes sksf-cloud-float {
	0%, 100% { transform: translateY(0); }
	50%      { transform: translateY(-1.4px); }
}

/* Values are SVG user units, not CSS pixels — the viewBox is 48 × 42. The arrow
   is drawn with its head at y 28.6, just under the cloud's flat base at 26, so
   this carries it from below the frame to just inside the cloud. It fades out
   as it arrives rather than stopping, which is what makes it read as a stream
   of deploys instead of one arrow bouncing.

   Full opacity is held only while the arrow is clearly below the cloud; it's
   already fading by the time it meets the base stroke, so it reads as absorbed
   rather than as piercing through the outline. */
@keyframes sksf-cloud-lift {
	0%   { transform: translateY(6px);  opacity: 0; }
	22%  { opacity: 1; }
	50%  { opacity: 1; }
	100% { transform: translateY(-4px); opacity: 0; }
}

/* ── Tool tiles ───────────────────────────────────────────── */

/* Cancels the card's padding exactly, so the row reaches both card edges and is
   cut off there by the card's own overflow — the tiles run out of the card
   rather than stopping inside it. The auto margin pushes it down to sit just
   above the link. */
.sksf__stage {
	align-self: stretch;
	margin: auto calc(-1 * var(--sksf-card-pad)) 0;
	padding-top: clamp(24px, 3vw, 40px);
}

.sksf__row { overflow: hidden; }

.sksf__row + .sksf__row { margin-top: var(--sksf-gap); }

.sksf__track {
	display: flex;
	width: max-content;
	will-change: transform;
	animation: sksf-marquee var(--sksf-duration, 44s) linear infinite;
}

/* Every other row runs the other way, so a multi-row block reads as movement
   rather than as one long conveyor. */
.sksf__row--reverse .sksf__track { animation-direction: reverse; }

.sksf__set {
	display: flex;
	gap: var(--sksf-gap);
	padding-right: var(--sksf-gap); /* trailing gap, so set → clone stays even */
}

/* Slides exactly one set's width: at the end, the clone sits precisely where
   the original started, so the restart is invisible. --sksf-set-w is written
   inline per row by the template. */
@keyframes sksf-marquee {
	from { transform: translate3d(0, 0, 0); }
	to   { transform: translate3d(calc(-1 * var(--sksf-set-w)), 0, 0); }
}

.sksf__stage:hover .sksf__track { animation-play-state: paused; }

.sksf__tile {
	flex: 0 0 auto;
	display: grid;
	place-items: center;
	width: var(--sksf-tile);
	height: var(--sksf-tile);
	padding: calc(var(--sksf-tile) * 0.28);
	border-radius: var(--sksf-radius);
	background: var(--sksf-tile-bg);
	transition: box-shadow 240ms ease;
}

.sksf .sksf__logo {
	display: block;
	width: 100%;
	height: 100%;
	max-width: 100%;
	object-fit: contain;
	transition: filter 300ms ease, opacity 300ms ease;
}

/* Optional: grey until the row is hovered. Off by default — the tool marks are
   already monochrome, so there is nothing for it to hold back. */
.sksf--grey .sksf__logo {
	filter: grayscale(1);
	opacity: .62;
}

@media (hover: hover) {
	.sksf--grey .sksf__stage:hover .sksf__logo {
		filter: grayscale(0);
		opacity: 1;
	}

	.sksf__stage:hover .sksf__tile {
		box-shadow: 0 10px 24px -16px rgba(16, 19, 38, 0.45);
	}
}

/* ── Breakpoints ──────────────────────────────────────────── */

@media (max-width: 900px) {
	.sksf__inner {
		grid-template-columns: minmax(0, 1fr);
		gap: clamp(16px, 3vw, 24px);
	}

	.sksf-card { min-height: 0; }

	/* The copy has already taken its own space by this width, so the marquee
	   doesn't need the auto margin to hold it down. */
	.sksf__stage { margin-top: clamp(24px, 5vw, 34px); }
}

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

	/* The drawing still has to read, so the arrow is parked at rest and lit
	   rather than left at the keyframe's opacity: 0. */
	.sksf-cloud__body,
	.sksf-cloud__lift {
		animation: none;
		transform: none;
		opacity: 1;
	}

	.sksf-card__arrow,
	.sksf-card__link,
	.sksf__tile,
	.sksf__logo { transition: none; }
}
