/* ============================================================================
   hub-dots.css -- the live 4-dot indicator on the hub-and-spoke "AI" artwork.

   The same illustration appears on four AI pages and on all 47 hire / service
   pages. In Figma it is not static art: the component has four variants
   (Default, Variant2, Variant3, Variant4), each held 0.2s via AFTER_TIMEOUT and
   swapped with transition:null (instant), so the active dot steps
   left-to-right on a closed 0.8s loop. Every exported asset bakes in variant 1
   only, which is why the dots sit still until something redraws them.

   The hire / service family solved this in figma-pages-base.css
   (.hrf-ai__flow-dots) by masking the baked row with the card fill and
   redrawing four HTML elements over it. That works there because those pages
   wrap the illustration in a box whose painted rect is known
   (.hrf-ai__illus-inner). The AI pages paint the same artwork at four
   different sizes and with three different fits, so percentage-positioned HTML
   would drift.

   This file does it with an SVG overlay instead. Each overlay carries the
   viewBox of the image it sits on and a preserveAspectRatio that mirrors that
   image's object-fit -- 'slice' for cover, 'meet' for contain -- so the SVG
   user units land on exactly the pixels the browser painted the artwork at,
   at every viewport, including where cover crops the sides. The dot
   coordinates are therefore the artwork's own, straight out of Figma: 6px dots
   on a 10px pitch, and twice that on the 2x exports.

   The fourth AI page, page-ai-in-business.php, is NOT handled here. Its copy
   of the artwork is a real SVG (assets/images/ai-in-business/work-card2.svg)
   whose dots are live <circle> elements, so the same animation lives inside
   that file instead -- CSS in an SVG runs even when the file is loaded through
   <img>. Keep the two in sync: same 0.2s step, same #543582 / #D0D0D0.

   Enqueued by tbi_ai_assets() on the three templates that use the overlay.
   ========================================================================= */

.hubdots {
	position: relative;
	display: block;
	/* Kills the inline strut so the wrapper is exactly as tall as the image --
	   matters for the <picture> on the AI Development Services card, which is
	   display:inline by default. */
	font-size: 0;
}

.hubdots > picture {
	display: block;
}

.hubdots__fx {
	--hubdots-step: 0.2s;	/* Figma AFTER_TIMEOUT, per variant */
	--hubdots-on: #543582;	/* Figma Ellipse 7082 fill */
	--hubdots-off: #d0d0d0;	/* Figma Ellipse 7083-7085 fill */
	position: absolute;
	left: 0;
	top: 0;
	width: 100%;
	height: 100%;
	pointer-events: none;
}

/* The baked dots are covered by four fill-coloured circles rather than one
   rectangle: the card fill carries a faint vertical gradient, so a flat band
   across the whole row can show a seam, while a circle a third wider than the
   dot it hides cannot. Those masks live in a <g>, which keeps them out of
   :nth-of-type below -- that counts <circle> siblings, and the live dots are
   the only ones that are direct children of the <svg>. */
.hubdots__dot {
	fill: var(--hubdots-off);
	animation: hubdots-step calc(var(--hubdots-step) * 4) step-end infinite;
}

/* Negative delays put each dot one step behind the one before it, so the
   steady-state cycle is already running on the first painted frame. */
.hubdots__dot:nth-of-type(2) { animation-delay: calc(var(--hubdots-step) * -3); }
.hubdots__dot:nth-of-type(3) { animation-delay: calc(var(--hubdots-step) * -2); }
.hubdots__dot:nth-of-type(4) { animation-delay: calc(var(--hubdots-step) * -1); }

/* step-end, not a fade: Figma swaps the variants instantly. */
@keyframes hubdots-step {
	0%   { fill: var(--hubdots-on); }
	25%  { fill: var(--hubdots-off); }
	100% { fill: var(--hubdots-off); }
}

@media (prefers-reduced-motion: reduce) {
	.hubdots__dot { animation: none; }
	.hubdots__dot:nth-of-type(1) { fill: var(--hubdots-on); }
}

/* --- per-page glue ------------------------------------------------------- */

/* Agentic AI: .waf-card__inner is a column flex container with
   align-items:flex-end, so the wrapper would shrink-wrap to its content
   instead of taking the image's full width. */
body.page-template-page-agentic-ai .hubdots {
	width: 100%;
}
