Great Tech Teams Don't Create Themselves. We'll Show You How.

Navigate the ever-evolving IT landscape with expert insights, strategies, and articles on building and scaling top-tier tech teams.

Thank you! Your submission has been received!
Oops! Something went wrong while submitting the form.
var Webflow = Webflow || [] Webflow.push(function () { const draggableCardsWrappers = document.querySelectorAll('[fc-draggable-card = wrapper]') for(const wrapper of draggableCardsWrappers) { let draggableCards = Array.from(wrapper.querySelectorAll('[fc-draggable-card = component]')) // Initial setup on page load — target the top card if (draggableCards.length) { const topCard = draggableCards[draggableCards.length - 1] addHoverEffect(topCard) initDraggable(topCard, draggableCards) } // Reset button logic: clear all styles and reinitialize top card wrapper.querySelector('[fc-draggable-card = reset]').addEventListener('click', () => { draggableCards = Array.from(wrapper.querySelectorAll('[fc-draggable-card = component]')) draggableCards.forEach(card => { // Remove all inline styles applied by GSAP gsap.set(card, { clearProps: "all" }) }) if (draggableCards.length) { const topCard = draggableCards[draggableCards.length - 1] addHoverEffect(topCard) initDraggable(topCard, draggableCards) } }) } }) // Helper: get a numeric attribute from an element, with fallback if missing or invalid function getAttr(el, attr, fallback) { const val = el.getAttribute(attr) const num = parseFloat(val) return !isNaN(num) ? num : fallback } // Helper: get a string attribute from an element, with fallback if missing function getStringAttr(el, attr, fallback) { const val = el.getAttribute(attr) return val && typeof val === "string" ? val : fallback } // Adds a hover animation to the topmost card — used only once on load or reset function addHoverEffect(card) { card.addEventListener('mouseenter', () => { gsap.to(card, { rotation: 10, x: '30%', duration: 0.3, ease: 'power2.out' }) }) card.addEventListener('mouseleave', () => { gsap.to(card, { rotation: 0, x: 0, duration: 0.3, ease: 'power2.out' }) }) } // Initializes GSAP Draggable for a given card function initDraggable(card, draggableCards) { // Extract configuration from attributes with fallbacks const rotation = getAttr(card, 'fc-draggable-card-rotation', 45) const resetDuration = getAttr(card, 'fc-draggable-card-reset-duration', 0.2) const throwDuration = getAttr(card, 'fc-draggable-card-throw-duration', 0.5) const throwDistance = getAttr(card, 'fc-draggable-card-throw-distance', 1000) const throwRotation = getAttr(card, 'fc-draggable-card-throw-rotation', 45) const threshold = getAttr(card, 'fc-draggable-card-threshold', 100) const delayBeforeNext = getAttr(card, 'fc-draggable-card-delay', 0) const easingFunctionRaw = getStringAttr(card, 'fc-draggable-card-ease', 'power4.out') let easingFunction try { easingFunction = gsap.parseEase(easingFunctionRaw) } catch (e) { easingFunction = 'power4.out' } let isReleased = false // Ensure no duplicate Draggable instance is attached Draggable.get(card)?.kill() Draggable.create(card, { type: "x", // On press: kill any hover animation in progress onPress() { gsap.killTweensOf(card) }, // On drag: update rotation dynamically, with configured easing onDrag() { if (isReleased) return gsap.to(card, { rotation: this.x / rotation, ease: easingFunction, duration: 0.2, overwrite: true }) }, // On release: handle reset or throw based on threshold onRelease() { const nextCard = draggableCards[draggableCards.indexOf(card) - 1] if (Math.abs(this.x) < threshold) { // If under threshold, reset to initial position gsap.to(card, { x: 0, opacity: 1, duration: resetDuration, ease: easingFunction, overwrite: true, onComplete: () => { isReleased = false } }) } else { // If dragged past threshold, animate out and initialize next card const direction = this.x > 0 ? 1 : -1 gsap.to(card, { x: direction * throwDistance, rotation: direction * throwRotation, opacity: 0, duration: throwDuration, ease: easingFunction, onComplete: () => { card.style.display = 'none' setTimeout(() => { // Find next visible card from the top of the stack const next = draggableCards.slice().reverse().find(card => card.style.display !== 'none') if (next) initDraggable(next, draggableCards) }, delayBeforeNext) } }) } } }) }
Software development team collaborating on enterprise financial aid software, reviewing code and compliance-driven workflows as part of an embedded development partnership.
Case Study
Genius Match + Regent Education: A Partnership for Development Success

This case study showcases how Genius Match partnered with Regent Education to build enterprise financial aid software - with embedded engineers who delivered 60-70% ROI to customers.

Learn more
Case Study
Empowering EdTech Innovation with Tailored Talent Solutions

This case study showcases how Genius Match helped a leading EdTech company fast-track its digital transformation and product roadmap through tailored outstaffing solutions.

Learn more
News
What HR Media Picked Up When Geni Launched

Geni launched in September. Here is what HR and tech media wrote about it, and the hiring numbers sitting underneath the coverage.

Learn more
Market Insights
Why fraud and application overload are the same problem - and what it takes to solve both

Recruiters have never had more applicants to choose from. They have never had less certainty about who those applicants are. We look at how volume and fraud became one problem, and what it takes to fix it at the source.

Learn more
Thought Leadership
Thought Leadership
Hiring Is Getting Harder in GovCon, and Here's What It's Costing Contractors

Intro for the blog page A bad hire in GovCon doesn't cost you a salary. It costs you a CPARS rating, and CPARS follows you into the next recompete. Here's how one screening decision reaches an award you haven't bid yet.

Learn more
Market Insights
Volume buries your best people, and that's finally fixable

Learn more
Thought Leadership
The Humans Behind the Orchestration Layer - Why the AI era demands more skilled people, not fewer

Everyone talks about AI tools. Nobody talks about who actually builds the systems behind them. We look at the roles driving real AI outcomes and why the talent gap is widening.

Learn more
Blog
Your AI Engineers Aren't AI Engineers

70% of people calling themselves AI engineers have never trained a model. They learned to call APIs and got a title bump during the hype cycle. Here's how to tell who's real before you waste $90K finding out the hard way.

Learn more