# Services Hover Video Reveal Cards

> Five expanding service cards that fade in a video preview with duotone tint as the bottom label turns transparent on hover.

**Definition:** Services Hover Video Reveal Cards is a cards UI animation from collections.html. It is built with HTML, CSS, JavaScript, and GSAP, ships with a live preview, and is free to copy into personal and commercial projects.

## Facts
- Category: Cards
- Stack: HTML, CSS, JavaScript, and GSAP
- Added: 2026-09-06
- Canonical page: https://html.bosconvertpro.com/collection/services-hover-video-reveal-cards
- Full-page preview: https://html.bosconvertpro.com/collection/services-hover-video-reveal-cards/full
- Live demo: https://html.bosconvertpro.com/demos/services-hover-video-reveal-cards/index.html
- Markdown mirror: https://html.bosconvertpro.com/collection/services-hover-video-reveal-cards/index.md
- License: https://html.bosconvertpro.com/terms

## How to use
1. Open https://html.bosconvertpro.com/collection/services-hover-video-reveal-cards/full to preview the animation in full screen.
2. Copy index.html, styles.css, and script.js from the code tabs on https://html.bosconvertpro.com/collection/services-hover-video-reveal-cards.
3. Paste the files into your project and adjust timing, easing, and content as needed.

## FAQ
### What is Services Hover Video Reveal Cards?

Services Hover Video Reveal Cards is a cards UI animation from collections.html. Five expanding service cards that fade in a video preview with duotone tint as the bottom label turns transparent on hover.

### What is Services Hover Video Reveal Cards built with?

Services Hover Video Reveal Cards is built with HTML, CSS, JavaScript, and GSAP. The source for every file is shown on the animation page and can be copied straight into your project.

### How do I use Services Hover Video Reveal Cards in my project?

Open the animation page (https://html.bosconvertpro.com/collection/services-hover-video-reveal-cards), preview it live, then copy index.html, styles.css, and script.js from the code tabs. Paste the files into your project and adjust timing, easing, and content as needed. A standalone demo runs at https://html.bosconvertpro.com/demos/services-hover-video-reveal-cards/index.html.

### Is Services Hover Video Reveal Cards free to use?

Yes. The Services Hover Video Reveal Cards demo code may be used in personal and commercial projects. You may not resell or redistribute the collection itself as a competing template pack. Full terms: https://html.bosconvertpro.com/terms.

## Source — index.html
````html
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <title>Services Hover Video Reveal Cards — Expanding Hover Cards with Video Preview</title>
  <meta name="description" content="Services hover video reveal cards: 5-column expanding service cards with video preview, duotone tint and collapsing label bar on hover. Volt-style recreation with HTML, CSS, JS and GSAP." />
  <link rel="preconnect" href="https://fonts.googleapis.com" />
  <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
  <link href="https://fonts.googleapis.com/css2?family=Roboto+Mono&display=swap" rel="stylesheet" />
  <link rel="stylesheet" href="styles.css" />
</head>
<body>
  <!-- Custom cursor (voltlites crosshair) -->
  <div class="cursor" id="cursor" aria-hidden="true">
    <svg xmlns="http://www.w3.org/2000/svg" width="34" height="25" viewBox="0 0 34 25" fill="none">
      <path d="M8.50401 23.7775V24.821H0V18.4861H1.0447V23.7763H8.50401V23.7775ZM32.8671 23.7775H25.4078V24.821H33.9118V18.4861H32.8683V23.7763L32.8671 23.7775ZM1.04353 1.04353H8.50284V0H0V6.33497H1.04353V1.04353ZM32.8671 1.04353V6.3338H33.9118V0H25.4078V1.04353H32.8671ZM16.433 17.3957V24.2999H17.4777V17.3957C17.3055 17.4133 17.1322 17.4226 16.9553 17.4226C16.7785 17.4226 16.6051 17.4133 16.433 17.3957ZM17.4777 7.42652V0.522351H16.433V7.42652C16.6051 7.40895 16.7785 7.39958 16.9553 7.39958C17.1322 7.39958 17.3055 7.40895 17.4777 7.42652ZM21.9668 12.4111C21.9668 12.588 21.9575 12.7613 21.9399 12.9335H28.8441V11.8888H21.9399C21.9575 12.0609 21.9668 12.2343 21.9668 12.4111ZM11.9707 11.8888H5.06657V12.9335H11.9707C11.9532 12.7613 11.9438 12.588 11.9438 12.4111C11.9438 12.2343 11.9532 12.0609 11.9707 11.8888ZM16.9553 15.8567C18.8585 15.8567 20.401 14.3143 20.401 12.4111C20.401 10.5079 18.8585 8.96546 16.9553 8.96546C15.0521 8.96546 13.5097 10.5079 13.5097 12.4111C13.5097 14.3143 15.0521 15.8567 16.9553 15.8567Z" fill="white"/>
    </svg>
  </div>

  <main class="services-section" id="services-section">
    <span class="noise" aria-hidden="true"></span>

    <div class="container">
      <section class="services-head">
        <p class="services-kicker">Hover to preview — video reveal + expanding card</p>
        <h2 class="services-title">Services</h2>
        <p class="services-sub">Five plated-blue service cards that grow on hover, fading in a video preview with duotone tint as the bottom label turns transparent.</p>
        <div class="services-head-spacer"></div>
      </section>

      <div class="services-grid" id="servicesGrid">
        <!-- 01 -->
        <div class="service-item">
          <a href="https://www.pexels.com/video/2022395/" class="service-link group" data-theme="rentals">
            <div class="service-card card-rentals" data-cursor>
              <div class="service-media">
                <img class="service-poster" src="https://images.unsplash.com/photo-1470229722913-7c0e2dbbafd3?auto=format&fit=crop&w=800&q=80" alt="Concert crowd under stage lights" loading="lazy" />
                <video class="service-video" src="https://videos.pexels.com/video-files/2022395/2022395-hd_1920_1080_30fps.mp4" poster="https://images.unsplash.com/photo-1470229722913-7c0e2dbbafd3?auto=format&fit=crop&w=800&q=80" muted loop playsinline autoplay preload="metadata"></video>
                <div class="service-tint tint-rentals"></div>
              </div>
              <p class="service-num">01</p>
              <div class="service-label label-rentals">
                <p>Live Production</p>
              </div>
            </div>
            <div class="service-spacer"></div>
          </a>
        </div>

        <!-- 02 -->
        <div class="service-item">
          <a href="https://www.pexels.com/video/3141210/" class="service-link group is-light" data-theme="sales">
            <div class="service-card card-sales" data-cursor>
              <div class="service-media">
                <img class="service-poster" src="https://images.unsplash.com/photo-1473968512647-3e447244af8f?auto=format&fit=crop&w=800&q=80" alt="Drone flying over event venue" loading="lazy" />
                <video class="service-video" src="https://videos.pexels.com/video-files/3141210/3141210-uhd_3840_2160_25fps.mp4" poster="https://images.unsplash.com/photo-1473968512647-3e447244af8f?auto=format&fit=crop&w=800&q=80" muted loop playsinline autoplay preload="metadata"></video>
                <div class="service-tint tint-sales"></div>
              </div>
              <p class="service-num">02</p>
              <div class="service-label label-sales">
                <p>Aerial Filming</p>
              </div>
            </div>
            <div class="service-spacer"></div>
          </a>
        </div>

        <!-- 03 -->
        <div class="service-item">
          <a href="https://www.pexels.com/video/3129671/" class="service-link group is-light" data-theme="integration">
            <div class="service-card card-integration" data-cursor>
              <div class="service-media">
                <img class="service-poster" src="https://images.unsplash.com/photo-1505373877841-8d25f7d46678?auto=format&fit=crop&w=800&q=80" alt="Stage with purple lights" loading="lazy" />
                <video class="service-video" src="https://videos.pexels.com/video-files/3129671/3129671-uhd_3840_2160_30fps.mp4" poster="https://images.unsplash.com/photo-1505373877841-8d25f7d46678?auto=format&fit=crop&w=800&q=80" muted loop playsinline autoplay preload="metadata"></video>
                <div class="service-tint tint-integration"></div>
              </div>
              <p class="service-num">03</p>
              <div class="service-label label-integration">
                <p>Stage Visuals</p>
              </div>
            </div>
            <div class="service-spacer"></div>
          </a>
        </div>

        <!-- 04 -->
        <div class="service-item">
          <a href="https://www.pexels.com/video/3209828/" class="service-link group is-light" data-theme="previz">
            <div class="service-card card-previz" data-cursor>
              <div class="service-media">
                <img class="service-poster" src="https://images.unsplash.com/photo-1519501025264-65ba15a82390?auto=format&fit=crop&w=800&q=80" alt="City night event" loading="lazy" />
                <video class="service-video" src="https://videos.pexels.com/video-files/3209828/3209828-uhd_3840_2160_25fps.mp4" poster="https://images.unsplash.com/photo-1519501025264-65ba15a82390?auto=format&fit=crop&w=800&q=80" muted loop playsinline autoplay preload="metadata"></video>
                <div class="service-tint tint-previz"></div>
              </div>
              <p class="service-num">04</p>
              <div class="service-label label-previz">
                <p>City Events</p>
              </div>
            </div>
            <div class="service-spacer"></div>
          </a>
        </div>

        <!-- 05 -->
        <div class="service-item">
          <a href="https://www.pexels.com/video/3121459/" class="service-link group is-light" data-theme="repairs">
            <div class="service-card card-repairs" data-cursor>
              <div class="service-media">
                <img class="service-poster" src="https://images.unsplash.com/photo-1533174072545-7a4b6ad7a6c3?auto=format&fit=crop&w=800&q=80" alt="Outdoor festival crowd" loading="lazy" />
                <video class="service-video" src="https://videos.pexels.com/video-files/3121459/3121459-uhd_3840_2160_24fps.mp4" poster="https://images.unsplash.com/photo-1533174072545-7a4b6ad7a6c3?auto=format&fit=crop&w=800&q=80" muted loop playsinline autoplay preload="metadata"></video>
                <div class="service-tint tint-repairs"></div>
              </div>
              <p class="service-num">05</p>
              <div class="service-label label-repairs">
                <p>Outdoor Festivals</p>
              </div>
            </div>
            <div class="service-spacer"></div>
          </a>
        </div>
      </div>

      <div class="services-foot">
        <div class="services-foot-grid">
          <div class="services-foot-col"></div>
        </div>
      </div>
    </div>
  </main>

  <script src="https://cdn.jsdelivr.net/npm/gsap@3.12.5/dist/gsap.min.js"></script>
  <script src="https://cdn.jsdelivr.net/npm/gsap@3.12.5/dist/ScrollTrigger.min.js"></script>
  <script src="script.js"></script>
</body>
</html>
````

## Source — styles.css
````css
/* --------------------------------------------------------------------------
   Services — voltlites.com recreation
   5 hover cards · video reveal · collapsing spacer · exact palette
   -------------------------------------------------------------------------- */

*,
*::before,
*::after {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

:root {
  --padding-container: 20px;
  --blue: #56ccf2;
  --blue-dark: #3a86ff;
  --blue-mediumdark: #2456a6;
  --blue-darker: #1a3a6b;
  --blue-darkest: #0b1e3e;
  --label-1: #bfe9ff;
  --label-2: #5e9bff;
  --label-3: #2f6fd0;
  --label-4: #1e4a8a;
  --label-5: #0e2547;
  --ink: #0b0b0b;
  --bar-h: 56px;
  --bar-h-lg: 64px;
}

@media (min-width: 1024px) {
  :root {
    --padding-container: 40px;
  }
}

html {
  -webkit-text-size-adjust: 100%;
}

html,
body {
  height: 100%;
}

body {
  font-family: "Neue Montreal", "Helvetica Neue", Helvetica, Arial, system-ui, -apple-system, sans-serif;
  background: #fff;
  color: var(--ink);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  overflow-x: clip;
}

img,
video {
  display: block;
  max-width: 100%;
}

a {
  color: inherit;
}

/* ---------- cursor ---------- */
.cursor {
  position: fixed;
  top: 0;
  left: 0;
  z-index: 9999;
  pointer-events: none;
  mix-blend-mode: difference;
  opacity: 0;
  will-change: transform;
}

@media (hover: none), (max-width: 1023px) {
  .cursor {
    display: none;
  }
}

/* ---------- section ---------- */
.services-section {
  position: relative;
  background: #fff;
  min-height: 100svh;
  isolation: isolate;
}

.noise {
  position: absolute;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  opacity: 0.035;
  background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 200 200' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
  background-size: 180px 180px;
}

.container {
  position: relative;
  z-index: 2;
  width: 100%;
  min-height: 100svh;
  padding-left: var(--padding-container);
  padding-right: var(--padding-container);
  padding-top: 24px;
  padding-bottom: 24px;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  flex: 1;
}

/* ---------- heading ---------- */
.services-head {
  position: relative;
  z-index: 10;
}

.services-kicker {
  font-family: "Roboto Mono", ui-monospace, monospace;
  font-size: 12px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  opacity: 0.65;
  margin-bottom: 12px;
}

.services-title {
  font-weight: 500;
  letter-spacing: -0.03em;
  line-height: 0.88;
  font-size: clamp(64px, 10.5vw, 168px);
  text-wrap: balance;
}

.services-sub {
  margin-top: 14px;
  max-width: 62ch;
  font-size: 15px;
  line-height: 1.55;
  opacity: 0.72;
}

.services-head-spacer {
  height: 40px;
}

@media (min-width: 1024px) {
  .services-head-spacer {
    height: 64px;
  }
}

/* ---------- grid ---------- */
.services-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: 16px;
  align-items: stretch;
  z-index: 50;
  position: relative;
}

@media (min-width: 640px) {
  .services-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 0;
  }
}

@media (min-width: 1024px) {
  .services-grid {
    grid-template-columns: repeat(5, minmax(0, 1fr));
    gap: 0;
  }
}

.service-item {
  display: flex;
  min-width: 0;
}

.service-link {
  display: flex;
  flex-direction: column;
  width: 100%;
  height: 100%;
  position: relative;
  text-decoration: none;
}

/* ---------- card ---------- */
.service-card {
  position: relative;
  width: 100%;
  aspect-ratio: 1 / 1;
  flex-grow: 1;
  flex-shrink: 0;
  padding: 12px;
  overflow: hidden;
  isolation: isolate;
  transition: color 0.2s ease-in-out;
}

/* plated blue card bases */
.card-rentals { background: linear-gradient(160deg, #8fdcff 0%, var(--blue) 55%, #2aa9dd 100%); color: #00131d; border: 1px solid rgba(255,255,255,.5); box-shadow: inset 0 1px 0 rgba(255,255,255,.7), inset 0 0 28px rgba(255,255,255,.15); }
.card-sales { background: linear-gradient(160deg, #7aabff 0%, var(--blue-dark) 55%, #2456c9 100%); color: #fff; border: 1px solid rgba(255,255,255,.35); box-shadow: inset 0 1px 0 rgba(255,255,255,.5), inset 0 0 28px rgba(0,0,0,.18); }
.card-integration { background: linear-gradient(160deg, #4a86d4 0%, var(--blue-mediumdark) 55%, #163a75 100%); color: #fff; border: 1px solid rgba(255,255,255,.25); box-shadow: inset 0 1px 0 rgba(255,255,255,.35), inset 0 0 28px rgba(0,0,0,.25); }
.card-previz { background: linear-gradient(160deg, #2e5495 0%, var(--blue-darker) 55%, #0e2547 100%); color: #fff; border: 1px solid rgba(255,255,255,.18); box-shadow: inset 0 1px 0 rgba(255,255,255,.25), inset 0 0 28px rgba(0,0,0,.35); }
.card-repairs { background: linear-gradient(160deg, #1b3a68 0%, var(--blue-darkest) 60%, #060f24 100%); color: #fff; border: 1px solid rgba(255,255,255,.14); box-shadow: inset 0 1px 0 rgba(255,255,255,.18), inset 0 0 28px rgba(0,0,0,.45); }

.service-link:hover .service-card {
  color: #fff;
  border-color: rgba(255, 255, 255, 0.85);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.7), 0 14px 36px rgba(11, 30, 62, 0.35);
}

/* ---------- media (video + duotone tint) ---------- */
.service-media {
  position: absolute;
  inset: 0;
  z-index: 0;
  opacity: 0;
  transition: opacity 0.2s ease-in-out;
  overflow: hidden;
  background: inherit;
}

.service-link:hover .service-media,
.service-link:focus-visible .service-media {
  opacity: 1;
}

/* mobile / touch: always show video like voltlites (md:opacity-0) */
@media (max-width: 767px) {
  .service-media {
    opacity: 1;
  }
}

.service-video {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center;
  transform: scale(1.04);
  transition: transform 0.8s cubic-bezier(0.16, 1, 0.3, 1);
  will-change: transform;
  position: relative;
  z-index: 1;
}

.service-poster {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center;
  z-index: 0;
}

.service-link:hover .service-video {
  transform: scale(1);
}

.service-tint {
  position: absolute;
  inset: 0;
  mix-blend-mode: color;
  pointer-events: none;
}

.tint-rentals { background: var(--blue); }
.tint-sales { background: var(--blue-dark); }
.tint-integration { background: var(--blue-mediumdark); }
.tint-previz { background: var(--blue-darker); }
.tint-repairs { background: var(--blue-darkest); }

/* ---------- number ---------- */
.service-num {
  position: relative;
  z-index: 2;
  font-family: "Roboto Mono", ui-monospace, monospace;
  font-size: 14px;
  line-height: 1.25;
  letter-spacing: 0;
}

/* ---------- bottom label bar ---------- */
.service-label {
  position: absolute;
  left: 0;
  bottom: 0;
  width: 100%;
  height: var(--bar-h);
  padding: 12px;
  display: flex;
  align-items: center;
  z-index: 2;
  font-size: 16px;
  line-height: 1.25;
  letter-spacing: -0.01em;
  font-weight: 500;
  transition: background-color 0.2s ease-in-out, color 0.2s ease-in-out;
}

@media (min-width: 1024px) {
  .service-label {
    height: var(--bar-h-lg);
    font-size: 17px;
  }
}

@media (min-width: 1280px) {
  .service-label {
    font-size: 21px;
  }
}

.service-label p {
  margin: 0;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.label-rentals { background: linear-gradient(135deg, #e3f4ff 0%, var(--label-1) 60%, #8fd4f7 100%); color: #00131d; }
.label-sales { background: linear-gradient(135deg, #9cc2ff 0%, var(--label-2) 60%, #2f6fd0 100%); color: #fff; }
.label-integration { background: linear-gradient(135deg, #5d95e0 0%, var(--label-3) 60%, #1a3f7d 100%); color: #fff; }
.label-previz { background: linear-gradient(135deg, #3a639f 0%, var(--label-4) 60%, #10294f 100%); color: #fff; }
.label-repairs { background: linear-gradient(135deg, #24406e 0%, var(--label-5) 60%, #060f24 100%); color: #fff; }

.service-link:hover .service-label,
.service-link:focus-visible .service-label {
  background: transparent;
  color: #fff;
}

/* ---------- collapsing spacer (the grow trick) ---------- */
.service-spacer {
  height: 0;
  flex-shrink: 0;
  transition: height 0.3s ease-in-out;
}

@media (min-width: 1024px) {
  .service-spacer {
    height: var(--bar-h-lg);
  }
  .service-link:hover .service-spacer,
  .service-link:focus-visible .service-spacer {
    height: 0;
  }
}

/* ---------- foot ---------- */
.services-foot {
  position: relative;
  z-index: 2;
  padding-top: 24px;
  min-height: 56px;
}

@media (min-width: 1024px) {
  .services-foot {
    padding-top: 64px;
    min-height: 64px;
  }
}

/* ---------- entrance initial state (JS animates in) ---------- */
.service-item {
  will-change: transform, opacity;
}

/* ---------- focus ---------- */
.service-link:focus-visible {
  outline: 2px solid #000;
  outline-offset: 3px;
}

/* ---------- reduced motion ---------- */
@media (prefers-reduced-motion: reduce) {
  .service-media,
  .service-video,
  .service-label,
  .service-spacer {
    transition: none !important;
  }
}
````

## Source — script.js
````javascript
/* Services — voltlites.com recreation
   GSAP entrance (verticalEase) + crosshair cursor + video handling */
(function () {
  gsap.registerPlugin(ScrollTrigger);

  var grid = document.getElementById('servicesGrid');
  var items = gsap.utils.toArray('.service-item');
  var title = document.querySelector('.services-title');
  var reduceMotion = window.matchMedia('(prefers-reduced-motion: reduce)').matches;

  /* ---------- entrance ---------- */
  if (!reduceMotion) {
    gsap.set(title, { y: 50, opacity: 0 });
    gsap.set(items, { y: 70, opacity: 0 });

    var tl = gsap.timeline({ defaults: { ease: 'power4.out' } });
    tl.to(title, { y: 0, opacity: 1, duration: 1.1, delay: 0.15 })
      .to(
        items,
        {
          y: 0,
          opacity: 1,
          duration: 1.2,
          stagger: 0.09,
          // verticalEase approximation: fast start, soft land
          ease: 'expo.out',
          clearProps: 'transform',
        },
        '-=0.7'
      );

    // subtle scroll parallax on scroll (like volt scrub)
    gsap.to(grid, {
      y: -24,
      ease: 'none',
      scrollTrigger: {
        trigger: '#services-section',
        start: 'top bottom',
        end: 'bottom top',
        scrub: 1,
      },
    });
  } else {
    gsap.set([title, items], { clearProps: 'all', opacity: 1, y: 0 });
  }

  /* ---------- videos: force muted autoplay, resume on hover ---------- */
  var videos = Array.prototype.slice.call(document.querySelectorAll('.service-video'));
  videos.forEach(function (v) {
    v.muted = true;
    v.loop = true;
    v.playsInline = true;
    var p = v.play();
    if (p && p.catch) p.catch(function () {});
    // if video errors, hide video only — Unsplash poster underneath stays visible
    v.addEventListener('error', function () {
      v.style.display = 'none';
    });
    // image fallback: if poster image fails, hide it too
    var poster = v.parentElement ? v.parentElement.querySelector('.service-poster') : null;
    if (poster) {
      poster.addEventListener('error', function () {
        poster.style.display = 'none';
      });
    }
  });

  document.querySelectorAll('.service-link').forEach(function (link) {
    var video = link.querySelector('video');
    link.addEventListener('mouseenter', function () {
      if (video && video.paused) {
        var pr = video.play();
        if (pr && pr.catch) pr.catch(function () {});
      }
      // snappy label lift like volt (CSS handles bg, JS adds micro y)
      if (!reduceMotion) {
        gsap.to(link.querySelector('.service-label'), {
          x: 2,
          duration: 0.25,
          ease: 'power2.out',
          overwrite: 'auto',
        });
      }
    });
    link.addEventListener('mouseleave', function () {
      if (!reduceMotion) {
        gsap.to(link.querySelector('.service-label'), {
          x: 0,
          duration: 0.3,
          ease: 'power2.out',
          overwrite: 'auto',
        });
      }
    });
    // touch: tap toggles active state
    link.addEventListener('click', function () {
      if (video && video.paused) {
        var pr2 = video.play();
        if (pr2 && pr2.catch) pr2.catch(function () {});
      }
    });
  });

  /* ---------- custom crosshair cursor ---------- */
  var cursor = document.getElementById('cursor');
  var fine = window.matchMedia('(hover: hover) and (pointer: fine)').matches;
  if (cursor && fine && !reduceMotion) {
    var xTo = gsap.quickTo(cursor, 'x', { duration: 0.35, ease: 'power3.out' });
    var yTo = gsap.quickTo(cursor, 'y', { duration: 0.35, ease: 'power3.out' });
    var showing = false;

    window.addEventListener('mousemove', function (e) {
      xTo(e.clientX - 17);
      yTo(e.clientY - 12);
      if (!showing) {
        showing = true;
        gsap.to(cursor, { opacity: 1, duration: 0.25, overwrite: 'auto' });
      }
    });

    document.querySelectorAll('[data-cursor]').forEach(function (el) {
      el.addEventListener('mouseenter', function () {
        gsap.to(cursor, { scale: 1.6, duration: 0.25, ease: 'power2.out', overwrite: 'auto' });
      });
      el.addEventListener('mouseleave', function () {
        gsap.to(cursor, { scale: 1, duration: 0.25, ease: 'power2.out', overwrite: 'auto' });
      });
    });
  }
})();
````
