---
import { ClientRouter } from 'astro:transitions';
import {
  CANONICAL_URL,
  GTM_CONTAINER_ID_DEFAULT,
  PUBLIC_SITE_ROOT_URL,
  SITE_IS_SUBPATH_BUILD,
  SITE_META,
  SITE_OG_IMAGE_URL,
  stripSiteBase,
  withSiteBase
} from '@/lib/site';
import '@/styles/fonts.css';

interface Props {
  title?: string;
  description?: string;
  ogDescription?: string;
}

const {
  title = SITE_META.title,
  description = SITE_META.description,
  ogDescription = SITE_META.ogDescription
} = Astro.props;

const pagePath = stripSiteBase(Astro.url.pathname);
const canonical = new URL(pagePath, CANONICAL_URL).href;
const pageUrl = new URL(pagePath, PUBLIC_SITE_ROOT_URL).href;
const robotsContent = SITE_IS_SUBPATH_BUILD ? 'noindex,nofollow,noarchive' : 'index,follow,max-image-preview:large';
const gtmId = import.meta.env.PUBLIC_GTM_CONTAINER_ID || GTM_CONTAINER_ID_DEFAULT;
const structuredDataJsonLd = JSON.stringify({
  '@context': 'https://schema.org',
  '@graph': [
    {
      '@type': 'WebSite',
      '@id': `${CANONICAL_URL}#website`,
      url: CANONICAL_URL,
      name: "L'électron rare",
      inLanguage: 'fr-FR',
      description: SITE_META.description,
      potentialAction: {
        '@type': 'SearchAction',
        target: `${CANONICAL_URL}?q={search_term_string}`,
        'query-input': 'required name=search_term_string'
      }
    },
    {
      '@type': 'Organization',
      '@id': `${CANONICAL_URL}#organization`,
      name: "L'électron rare",
      legalName: "Clément Saillant — L'Électron Rare",
      url: CANONICAL_URL,
      logo: {
        '@type': 'ImageObject',
        url: new URL('assets/brand/logo-mark.png', CANONICAL_URL).href,
        width: 512,
        height: 512
      },
      image: new URL('assets/og-cover.jpg', CANONICAL_URL).href,
      foundingDate: '2024',
      founder: { '@id': `${CANONICAL_URL}#person` },
      address: {
        '@type': 'PostalAddress',
        addressCountry: 'FR',
        addressLocality: 'France'
      },
      contactPoint: {
        '@type': 'ContactPoint',
        contactType: 'customer service',
        email: 'contact@lelectronrare.fr',
        url: `${CANONICAL_URL}#contact`,
        availableLanguage: ['fr', 'en']
      },
      knowsAbout: [
        'systèmes électroniques spécifiques',
        'conception électronique sur mesure',
        'intégration électronique multi-technique',
        'consulting électronique',
        'formation électronique appliquée',
        'prototype hardware',
        'automatisme industriel',
        'gestion énergie et stockage',
        'développement IoT et embarqué',
        'microcontrôleur ESP32 STM32',
        'instrumentation et télémétrie',
        'PCB KiCad conception IPC-A-610',
        'compatibilité électromagnétique CEM EMC',
        'DMX Art-Net DANTE spectacle vivant',
        'intelligence artificielle embarquée',
        'prototypage rapide et petites séries'
      ],
      sameAs: [
        'https://fr.linkedin.com/in/electron-rare',
        'https://blog.saillant.cc',
        'https://github.com/electron-rare'
      ]
    },
    {
      '@type': 'Person',
      '@id': `${CANONICAL_URL}#person`,
      name: 'Clément Saillant',
      alternateName: "L'électron rare",
      url: CANONICAL_URL,
      jobTitle: 'Concepteur de systèmes électroniques spécifiques',
      description: "Concepteur de systèmes électroniques spécifiques. Diagnostic, conception, mise au point et fiabilisation de projets électroniques, avec mobilisation de partenaires adaptés quand le projet devient multi-technique.",
      hasCredential: {
        '@type': 'EducationalOccupationalCredential',
        credentialCategory: 'BTS',
        name: 'BTS Systèmes Numériques'
      },
      hasOccupation: {
        '@type': 'Occupation',
        name: 'Concepteur électronique embarquée',
        occupationLocation: { '@type': 'Country', name: 'France' },
        skills: 'PCB design, embedded firmware, industrial automation, energy management, IoT, AI-assisted electronics'
      },
      knowsAbout: [
        'specific electronic systems', 'electronic systems design', 'custom electronics designer',
        'electronics consultant', 'electronics trainer', 'IoT developer',
        'embedded AI', 'ESP32', 'STM32', 'KiCad', 'FreeCAD',
        'automatisme industriel', 'énergie et stockage',
        'PCB design', 'IPC-A-610', 'CEM EMC', 'DMX Art-Net DANTE',
        'spectacle vivant', 'industries créatives'
      ],
      worksFor: { '@id': `${CANONICAL_URL}#organization` },
      memberOf: {
        '@type': 'Organization',
        name: 'KompleX KapharnaüM',
        url: 'https://www.kfrancetyphon.com'
      },
      sameAs: [
        'https://fr.linkedin.com/in/electron-rare',
        'https://blog.saillant.cc',
        'https://github.com/electron-rare'
      ]
    },
    {
      '@type': 'ProfessionalService',
      '@id': `${canonical}#service`,
      name: "L'électron rare",
      url: canonical,
      provider: { '@id': `${CANONICAL_URL}#person` },
      serviceType: [
        'Systèmes électroniques spécifiques',
        'Prototype électronique',
        'Instrumentation et contrôle',
        'Automatisme industriel',
        'Consulting électronique',
        'Formation technique',
        'Énergie et stockage',
        'Intégration IA embarquée'
      ],
      areaServed: { '@type': 'Country', name: 'France' },
      description: 'Conception, mise au point et fiabilisation de systèmes électroniques spécifiques, avec partenaires adaptés pour les projets multi-techniques.',
      priceRange: '€€',
      hasOfferCatalog: {
        '@type': 'OfferCatalog',
        name: 'Formats de mission',
        itemListElement: [
          {
            '@type': 'Offer',
            itemOffered: {
              '@type': 'Service',
              name: 'Diagnostic',
              description: 'Analyse de faisabilité, identification des risques, plan d\'action — 1 à 2 semaines'
            }
          },
          {
            '@type': 'Offer',
            itemOffered: {
              '@type': 'Service',
              name: 'Prototype',
              description: 'Prototype testé, mesures documentées, go/no-go — 4 à 6 semaines'
            }
          },
          {
            '@type': 'Offer',
            itemOffered: {
              '@type': 'Service',
              name: 'Mission complète',
              description: 'Livrables phasés, dossier de production, transfert clé en main — 2 à 6 mois'
            }
          }
        ]
      }
    },
    {
      '@type': 'FAQPage',
      '@id': `${CANONICAL_URL}#faq`,
      mainEntity: [
        {
          '@type': 'Question',
          name: 'Quels types de projets électroniques prenez-vous en charge ?',
          acceptedAnswer: {
            '@type': 'Answer',
            text: 'Cartes sur mesure, interfaces capteurs, alimentations, reprise d\'existant, instrumentation, automatisme, dispositifs pour le spectacle vivant, gestion énergie et stockage, et montages multi-techniques avec partenaires.'
          }
        },
        {
          '@type': 'Question',
          name: 'Travaillez-vous avec des technologies IA embarquée ?',
          acceptedAnswer: {
            '@type': 'Answer',
            text: 'Oui, nous intégrons l\'intelligence artificielle dans les systèmes embarqués : inférence locale sur ESP32/STM32, optimisation de modèles pour edge computing, et assistance IA pour la conception PCB via KiCad et nos outils internes.'
          }
        },
        {
          '@type': 'Question',
          name: 'Quelle est la durée typique d\'un projet ?',
          acceptedAnswer: {
            '@type': 'Answer',
            text: 'Un diagnostic prend 1 à 2 semaines. Un prototype 4 à 6 semaines. Une mission complète de 2 à 6 mois selon la complexité.'
          }
        }
      ]
    }
  ]
});
---

<!doctype html>
<html lang="fr" data-theme="high-contrast">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta name="color-scheme" content="light" />
    <!-- Fonts self-hosted — see src/styles/fonts.css -->
    <title>{title}</title>
    <meta name="theme-color" content={SITE_META.themeColor} />
    <meta name="description" content={description} />
    <meta name="keywords" content={SITE_META.keywords} />
    <meta name="author" content={SITE_META.author} />
    <meta name="language" content="fr" />
    <meta name="geo.region" content="FR" />
    <meta name="geo.placename" content="France" />
    <link rel="icon" type="image/svg+xml" href={withSiteBase('/favicon.svg')} />
    <link rel="icon" type="image/png" sizes="32x32" href={withSiteBase('/favicon-32x32.png')} />
    <link rel="icon" type="image/png" sizes="16x16" href={withSiteBase('/favicon-16x16.png')} />
    <link rel="apple-touch-icon" sizes="180x180" href={withSiteBase('/apple-touch-icon.png')} />
    <link rel="shortcut icon" href={withSiteBase('/favicon.ico')} />

    <ClientRouter />
    <link rel="canonical" href={canonical} />
    <meta name="robots" content={robotsContent} />
    <meta name="robots" content="max-snippet:-1, max-image-preview:large, max-video-preview:-1" />

    <!-- AI / LLM crawling directives (SOTA 2026) -->
    <meta name="ai-content-declaration" content="human-created" />
    <meta name="generator-assisted" content="Claude Code (Anthropic) — site structure and WebGL; content authored by Clément Saillant" />
    <link rel="llms" href={withSiteBase('/llms.txt')} type="text/plain" />

    <!-- Speakable (voice search optimization) -->
    <meta name="speakable" content="true" />

    <meta property="og:type" content="website" />
    <meta property="og:locale" content="fr_FR" />
    <meta property="og:site_name" content="L'électron rare" />
    <meta property="og:title" content={title} />
    <meta property="og:url" content={pageUrl} />
    <meta property="og:description" content={ogDescription} />
    <meta property="og:image" content={SITE_OG_IMAGE_URL} />
    <meta property="og:image:width" content="1200" />
    <meta property="og:image:height" content="630" />
    <meta property="og:image:alt" content="L'electron rare - systemes electroniques specifiques, conception, mise au point et partenariats multi-techniques" />

    <meta name="twitter:card" content="summary_large_image" />
    <meta name="twitter:title" content={title} />
    <meta name="twitter:description" content={SITE_META.twitterDescription} />
    <meta name="twitter:image" content={SITE_OG_IMAGE_URL} />

    <script is:inline>
      (function () {
        if ('scrollRestoration' in history) {
          history.scrollRestoration = 'manual';
        }

        if (!window.location.hash) {
          window.scrollTo(0, 0);
        }

        var resetToTop = function () {
          if (window.location.hash) {
            return;
          }
          window.scrollTo(0, 0);
          document.documentElement.scrollTop = 0;
          document.body.scrollTop = 0;
        };

        window.addEventListener('pageshow', resetToTop);
        window.addEventListener('load', resetToTop);
        window.addEventListener('beforeunload', resetToTop);
        window.addEventListener('pagehide', resetToTop);
      })();
    </script>

    <script is:inline define:vars={{ gtmId }}>
      window.dataLayer = window.dataLayer || [];
      if (gtmId) {
        (function (w, d, s, l, i) {
          w[l] = w[l] || [];
          w[l].push({ "gtm.start": new Date().getTime(), event: "gtm.js" });
          var f = d.getElementsByTagName(s)[0],
            j = d.createElement(s),
            dl = l !== "dataLayer" ? "&l=" + l : "";
          j.async = true;
          j.src = "https://www.googletagmanager.com/gtm.js?id=" + i + dl;
          f.parentNode.insertBefore(j, f);
        })(window, document, "script", "dataLayer", gtmId);
      }
    </script>

</head>
<body>
    <script is:inline>
      (function () {
        var root = document.documentElement;
        var params = new URLSearchParams(window.location.search);
        var uiRaw = params.get('ui') || params.get('sprint') || '';
        var uiAllowed = { a: 1, b: 1 };
        var uiSprint = uiRaw.toLowerCase().trim() in uiAllowed ? uiRaw.toLowerCase().trim() : 'b';

        root.setAttribute('data-da-variant', 'v12');
        root.setAttribute('data-ui-sprint', uiSprint);
      })();
    </script>

    {
      gtmId && (
        <noscript>
          <iframe src={`https://www.googletagmanager.com/ns.html?id=${gtmId}`} height="0" width="0" style="display:none;visibility:hidden"></iframe>
        </noscript>
      )
    }

    <a class="sr-only focus:not-sr-only focus:fixed focus:left-3 focus:top-3 focus:z-50 focus:rounded-md focus:bg-white focus:px-3 focus:py-2 focus:text-black focus:ring-2 focus:ring-black focus:ring-offset-2 focus:ring-offset-white" href="#main-content">
      Aller au contenu
    </a>

    <slot />

    <script is:inline type="application/ld+json" set:html={structuredDataJsonLd} />

    <script is:inline>
      (function () {
        var daVariant = document.documentElement.getAttribute('data-da-variant') || 'v12';
        var pagePath = window.location.pathname || '/';
        var pageTitle = document.title || '';

        var pushTrackingEvent = function (eventName, payload) {
          window.dataLayer = window.dataLayer || [];
          window.dataLayer.push(
            Object.assign(
              {
                event: eventName,
                event_category: 'engagement',
                event_label: eventName,
                page_path: pagePath,
                page_title: pageTitle,
                da_variant: daVariant
              },
              payload || {}
            )
          );
        };

        var links = document.querySelectorAll("[data-track]");
        for (var i = 0; i < links.length; i += 1) {
          links[i].addEventListener("click", function () {
            var eventName = this.getAttribute("data-track");
            var destination = this.getAttribute("data-destination") || this.getAttribute("href") || "unknown";
            pushTrackingEvent(eventName, {
              destination: destination,
              link_text: (this.textContent || '').trim().slice(0, 80)
            });
          });
        }

        pushTrackingEvent('experiment_variant_exposed', {
          destination: pagePath
        });

        var firedDepths = {};
        var scrollDepths = [25, 50, 75, 100];
        var onScroll = function () {
          var doc = document.documentElement;
          var maxScroll = doc.scrollHeight - window.innerHeight;
          if (maxScroll <= 0) {
            return;
          }
          var percent = Math.min(100, Math.max(0, (window.scrollY / maxScroll) * 100));
          for (var i = 0; i < scrollDepths.length; i += 1) {
            var depth = scrollDepths[i];
            if (percent >= depth && !firedDepths[depth]) {
              firedDepths[depth] = true;
              pushTrackingEvent('engagement_scroll_depth', {
                destination: window.location.pathname || '/',
                scroll_depth: depth
              });
            }
          }
        };

        window.addEventListener('scroll', onScroll, { passive: true });
        onScroll();

        if ('IntersectionObserver' in window) {
          var sectionIds = ['a-propos', 'cas-clients', 'sprints-graphiques', 'contact'];
          var seenSections = {};
          var sectionObserver = new IntersectionObserver(
            function (entries, observer) {
              for (var e = 0; e < entries.length; e += 1) {
                if (!entries[e].isIntersecting) {
                  continue;
                }
                var id = entries[e].target.id;
                if (!id || seenSections[id]) {
                  continue;
                }
                seenSections[id] = true;
                pushTrackingEvent('engagement_section_view', {
                  destination: '#' + id,
                  section_id: id
                });
                observer.unobserve(entries[e].target);
              }
            },
            { threshold: 0.42 }
          );

          for (var s = 0; s < sectionIds.length; s += 1) {
            var node = document.getElementById(sectionIds[s]);
            if (node) {
              sectionObserver.observe(node);
            }
          }
        }

        if (!('PerformanceObserver' in window)) {
          return;
        }

        var getMetricRating = function (metricName, value) {
          if (metricName === 'LCP') {
            if (value <= 2500) return 'good';
            if (value <= 4000) return 'needs_improvement';
            return 'poor';
          }
          if (metricName === 'CLS') {
            if (value <= 0.1) return 'good';
            if (value <= 0.25) return 'needs_improvement';
            return 'poor';
          }
          if (metricName === 'INP') {
            if (value <= 200) return 'good';
            if (value <= 500) return 'needs_improvement';
            return 'poor';
          }
          return 'unknown';
        };

        var supports = PerformanceObserver.supportedEntryTypes || [];
        var lcpValue = 0;
        var clsValue = 0;
        var inpValue = 0;
        var lcpSent = false;
        var clsSent = false;
        var inpSent = false;

        var sendMetric = function (metricName, metricValue) {
          pushTrackingEvent('cwv_metric', {
            destination: window.location.pathname || '/',
            metric_name: metricName,
            metric_value: metricValue,
            metric_rating: getMetricRating(metricName, metricValue)
          });
        };

        if (supports.indexOf('largest-contentful-paint') !== -1) {
          var lcpObserver = new PerformanceObserver(function (entryList) {
            var entries = entryList.getEntries();
            var last = entries[entries.length - 1];
            if (last) {
              lcpValue = Math.round(last.startTime);
            }
          });
          lcpObserver.observe({ type: 'largest-contentful-paint', buffered: true });

          var flushLcp = function () {
            if (lcpSent || lcpValue <= 0) {
              return;
            }
            lcpSent = true;
            sendMetric('LCP', lcpValue);
          };
          document.addEventListener('visibilitychange', function () {
            if (document.visibilityState === 'hidden') {
              flushLcp();
            }
          });
          window.addEventListener('pagehide', flushLcp);
        }

        if (supports.indexOf('layout-shift') !== -1) {
          var clsObserver = new PerformanceObserver(function (entryList) {
            var entries = entryList.getEntries();
            for (var i = 0; i < entries.length; i += 1) {
              if (!entries[i].hadRecentInput) {
                clsValue += entries[i].value;
              }
            }
          });
          clsObserver.observe({ type: 'layout-shift', buffered: true });

          var flushCls = function () {
            if (clsSent) {
              return;
            }
            clsSent = true;
            sendMetric('CLS', Number(clsValue.toFixed(3)));
          };
          document.addEventListener('visibilitychange', function () {
            if (document.visibilityState === 'hidden') {
              flushCls();
            }
          });
          window.addEventListener('pagehide', flushCls);
        }

        if (supports.indexOf('event') !== -1) {
          var inpObserver = new PerformanceObserver(function (entryList) {
            var entries = entryList.getEntries();
            for (var i = 0; i < entries.length; i += 1) {
              var duration = entries[i].duration || 0;
              if (duration > inpValue) {
                inpValue = Math.round(duration);
              }
            }
          });
          inpObserver.observe({ type: 'event', buffered: true, durationThreshold: 40 });

          var flushInp = function () {
            if (inpSent || inpValue <= 0) {
              return;
            }
            inpSent = true;
            sendMetric('INP', inpValue);
          };
          document.addEventListener('visibilitychange', function () {
            if (document.visibilityState === 'hidden') {
              flushInp();
            }
          });
          window.addEventListener('pagehide', flushInp);
        }
      })();
    </script>

    <script is:inline>
      (function () {
        var nav = document.querySelector('.site-nav');
        if (!nav) {
          return;
        }

        var links = Array.prototype.slice.call(
          document.querySelectorAll('.site-navlink[href^="#"], .figma-lab-nav-link[href^="#"]')
        );
        if (!links.length) {
          return;
        }

        var sections = links
          .map(function (link) {
            var href = link.getAttribute('href') || '';
            var id = href.replace('#', '');
            var target = id ? document.getElementById(id) : null;
            return { id: id, link: link, target: target };
          })
          .filter(function (entry) {
            return !!entry.target;
          });

        var setPressedState = function (link) {
          link.classList.add('is-pressed');
          window.setTimeout(function () {
            link.classList.remove('is-pressed');
          }, 340);
        };

        for (var i = 0; i < links.length; i += 1) {
          links[i].addEventListener('click', function () {
            setPressedState(this);
          });
        }

        var ticking = false;
        var updateNavState = function () {
          ticking = false;
          var scrollTop = window.scrollY || window.pageYOffset || 0;

          nav.classList.toggle('is-compact', scrollTop > 18);

          var doc = document.documentElement;
          var maxScroll = doc.scrollHeight - window.innerHeight;
          var progress = maxScroll > 0 ? (scrollTop / maxScroll) * 100 : 0;
          nav.style.setProperty('--nav-progress', progress.toFixed(2) + '%');

          var threshold = scrollTop + window.innerHeight * 0.32;
          var activeId = '';

          for (var s = 0; s < sections.length; s += 1) {
            if (sections[s].target.offsetTop <= threshold) {
              activeId = sections[s].id;
            }
          }

          for (var l = 0; l < sections.length; l += 1) {
            var isActive = activeId !== '' && sections[l].id === activeId;
            sections[l].link.classList.toggle('is-active', isActive);
            if (isActive) {
              sections[l].link.setAttribute('aria-current', 'location');
            } else {
              sections[l].link.removeAttribute('aria-current');
            }
          }
        };

        var requestUpdate = function () {
          if (ticking) {
            return;
          }

          ticking = true;
          window.requestAnimationFrame(updateNavState);
        };

        window.addEventListener('scroll', requestUpdate, { passive: true });
        window.addEventListener('resize', requestUpdate);
        window.addEventListener('hashchange', requestUpdate);

        updateNavState();
      })();
    </script>

    <script is:inline>
      (function () {
        var menus = Array.prototype.slice.call(document.querySelectorAll('[data-nav-menu]'));
        if (!menus.length) {
          return;
        }

        var syncMenuState = function (menu) {
          var summary = menu.querySelector('summary');
          if (!summary) {
            return;
          }
          summary.setAttribute('aria-expanded', menu.hasAttribute('open') ? 'true' : 'false');
        };

        var closeMenu = function (menu) {
          if (!menu.hasAttribute('open')) {
            return;
          }
          menu.removeAttribute('open');
          syncMenuState(menu);
        };

        for (var i = 0; i < menus.length; i += 1) {
          var menu = menus[i];
          syncMenuState(menu);

          menu.addEventListener('toggle', function () {
            syncMenuState(this);
          });

          var links = menu.querySelectorAll('a');
          for (var l = 0; l < links.length; l += 1) {
            links[l].addEventListener('click', function () {
              var parentMenu = this.closest('[data-nav-menu]');
              if (parentMenu) {
                closeMenu(parentMenu);
              }
            });
          }
        }

        document.addEventListener('click', function (event) {
          for (var i = 0; i < menus.length; i += 1) {
            if (!menus[i].contains(event.target)) {
              closeMenu(menus[i]);
            }
          }
        });

        document.addEventListener('keydown', function (event) {
          if (event.key !== 'Escape') {
            return;
          }
          for (var i = 0; i < menus.length; i += 1) {
            closeMenu(menus[i]);
          }
        });

        var syncRootOpenState = function () {
          var isCompactViewport = window.innerWidth < 960;
          var hasOpenMenu = false;

          for (var i = 0; i < menus.length; i += 1) {
            if (menus[i].hasAttribute('open')) {
              hasOpenMenu = true;
              break;
            }
          }

          document.documentElement.classList.toggle('site-nav-open', isCompactViewport && hasOpenMenu);
        };

        window.addEventListener('resize', function () {
          if (window.innerWidth >= 960) {
            for (var i = 0; i < menus.length; i += 1) {
              closeMenu(menus[i]);
            }
          }
          syncRootOpenState();
        });

        for (var j = 0; j < menus.length; j += 1) {
          menus[j].addEventListener('toggle', syncRootOpenState);
        }

        syncRootOpenState();
      })();
    </script>

    <script is:inline>
      (function () {
        var items = Array.prototype.slice.call(document.querySelectorAll('[data-reveal]'));
        if (!items.length) {
          return;
        }

        var reduceMotion = window.matchMedia && window.matchMedia('(prefers-reduced-motion: reduce)').matches;
        if (reduceMotion || !('IntersectionObserver' in window)) {
          for (var i = 0; i < items.length; i += 1) {
            items[i].classList.add('is-revealed');
          }
          return;
        }

        var io = new IntersectionObserver(
          function (entries, observer) {
            for (var e = 0; e < entries.length; e += 1) {
              if (!entries[e].isIntersecting) {
                continue;
              }
              entries[e].target.classList.add('is-revealed');
              observer.unobserve(entries[e].target);
            }
          },
          { threshold: 0.18, rootMargin: '0px 0px -8% 0px' }
        );

        for (var j = 0; j < items.length; j += 1) {
          io.observe(items[j]);
        }
      })();
    </script>

    <script is:inline>
      (function () {
        var clips = Array.prototype.slice.call(document.querySelectorAll('.video-strip-clip'));
        for (var v = 0; v < clips.length; v++) {
          (function (clip) {
            clip.addEventListener('mouseenter', function () { clip.play(); });
            clip.addEventListener('mouseleave', function () { clip.pause(); clip.currentTime = 0; });
            clip.addEventListener('touchstart', function () {
              if (clip.paused) { clip.play(); } else { clip.pause(); clip.currentTime = 0; }
            }, { passive: true });
          })(clips[v]);
        }

        var reduceMotion = window.matchMedia && window.matchMedia('(prefers-reduced-motion: reduce)').matches;

        var sprintCards = Array.prototype.slice.call(document.querySelectorAll('.graphic-sprint-card'));
        if (sprintCards.length) {
          if (reduceMotion || !('IntersectionObserver' in window)) {
            for (var i = 0; i < sprintCards.length; i += 1) {
              sprintCards[i].classList.add('is-live');
            }
          } else {
            var sprintObserver = new IntersectionObserver(
              function (entries, observer) {
                for (var e = 0; e < entries.length; e += 1) {
                  if (!entries[e].isIntersecting) {
                    continue;
                  }
                  entries[e].target.classList.add('is-live');
                  observer.unobserve(entries[e].target);
                }
              },
              { threshold: 0.26, rootMargin: '0px 0px -10% 0px' }
            );

            for (var s = 0; s < sprintCards.length; s += 1) {
              sprintObserver.observe(sprintCards[s]);
            }
          }
        }

        var finePointer = window.matchMedia && window.matchMedia('(pointer:fine)').matches;
        if (reduceMotion || !finePointer) {
          return;
        }

      })();
    </script>
  </body>
</html>
