<!DOCTYPE html><html lang="en"> <head><!-- Global Metadata --><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><link rel="icon" type="image/png" sizes="32x32" href="/favicon-32.png?v=2"><link rel="icon" type="image/png" sizes="64x64" href="/favicon-64.png?v=2"><link rel="icon" type="image/png" sizes="256x256" href="/favicon-light.png?v=2"><link rel="apple-touch-icon" href="/favicon-light.png?v=2"><meta name="generator" content="Astro v5.18.1"><!-- Font preloads --><link rel="preload" href="/_astro/inter-latin-400-normal.C38fXH4l.woff2" as="font" type="font/woff2" crossorigin><link rel="preload" href="/_astro/inter-latin-600-normal.LgqL8muc.woff2" as="font" type="font/woff2" crossorigin><link rel="preload" href="/_astro/lora-latin-400-normal.DnxXpLNu.woff2" as="font" type="font/woff2" crossorigin><link rel="preload" href="/_astro/lora-latin-600-normal.B-3RcLOQ.woff2" as="font" type="font/woff2" crossorigin><!-- Canonical URL --><link rel="canonical" href="https://peterelst.com/"><!-- Primary Meta Tags --><title>Peter Elst</title><meta name="title" content="Peter Elst"><meta name="description" content="Senior software engineer, technology enthusiast, and Irish-language learner sharing thoughts, letters to the editor, and experiments with learning in public."><!-- Open Graph / Facebook --><meta property="og:type" content="website"><meta property="og:site_name" content="Peter Elst"><meta property="og:url" content="https://peterelst.com/"><meta property="og:title" content="Peter Elst"><meta property="og:description" content="Senior software engineer, technology enthusiast, and Irish-language learner sharing thoughts, letters to the editor, and experiments with learning in public."><meta property="og:image" content="https://peterelst.com/og-image.png"><!-- Twitter --><meta name="twitter:card" content="summary_large_image"><meta name="twitter:url" content="https://peterelst.com/"><meta name="twitter:title" content="Peter Elst"><meta name="twitter:description" content="Senior software engineer, technology enthusiast, and Irish-language learner sharing thoughts, letters to the editor, and experiments with learning in public."><meta name="twitter:image" content="https://peterelst.com/og-image.png"><meta name="astro-view-transitions-enabled" content="true"><meta name="astro-view-transitions-fallback" content="animate"><script type="module" src="/_astro/ClientRouter.astro_astro_type_script_index_0_lang.CDGfc0hd.js"></script><!-- RSS Link --><link rel="alternate" type="application/rss+xml" title="Peter Elst" href="https://peterelst.com/rss.xml"><!-- Google tag (gtag.js) --><script async src="https://www.googletagmanager.com/gtag/js?id=G-RR7E3HQSWF"></script><script>
  /** @type {any} */
  const analyticsWindow = window;
  analyticsWindow.dataLayer = analyticsWindow.dataLayer || [];
  analyticsWindow.gtag = function gtag() {
    analyticsWindow.dataLayer.push(arguments);
  };
  analyticsWindow.trackEvent = function trackEvent(name, params = {}) {
    if (typeof analyticsWindow.gtag !== "function") return;
    analyticsWindow.gtag("event", name, params);
  };
  analyticsWindow.gtag("js", new Date());
  analyticsWindow.gtag("config", "G-RR7E3HQSWF");
</script><script type="module">document.addEventListener("astro:before-swap",e=>[...e.newDocument.head.querySelectorAll('link[as="font"]')].forEach(o=>o.remove()));</script><script>
  function init() {
    preloadTheme();
    onScroll();
    animate();

    const backToTop = document.getElementById("back-to-top");
    backToTop?.addEventListener("click", (event) => scrollToTop(event));

    const backToPrev = document.getElementById("back-to-prev");
    backToPrev?.addEventListener("click", () => window.history.back());

    const themeToggleButton = document.getElementById("theme-toggle-button");
    themeToggleButton?.addEventListener("click", () => toggleThemeMode());

    document.addEventListener("scroll", onScroll);
  }

  function animate() {
    const animateElements = document.querySelectorAll(".animate");

    animateElements.forEach((element, index) => {
      setTimeout(() => {
        element.classList.add("show");
      }, index * 150);
    });
  }

  function onScroll() {
    if (window.scrollY > 0) {
      document.documentElement.classList.add("scrolled");
    } else {
      document.documentElement.classList.remove("scrolled");
    }
  }

  function scrollToTop(event) {
    event.preventDefault();
    window.scrollTo({
      top: 0,
      behavior: "smooth"
    });
  }

function toggleTheme(dark) {
    const css = document.createElement("style");

    css.appendChild(
      document.createTextNode(
        `* {
             -webkit-transition: none !important;
             -moz-transition: none !important;
             -o-transition: none !important;
             -ms-transition: none !important;
             transition: none !important;
          }
        `,
      )
    );

    document.head.appendChild(css);

    if (dark) {
      document.documentElement.classList.add("dark");
    } else {
      document.documentElement.classList.remove("dark");
    }

  window.getComputedStyle(css).opacity;
    document.head.removeChild(css);
  }

  function toggleThemeMode() {
    const dark = document.documentElement.classList.contains("dark");
    const nextDark = !dark;
    localStorage.setItem("theme", nextDark ? "dark" : "light");
    toggleTheme(nextDark);
  }

  function preloadTheme() {
    const userTheme = localStorage.theme;

    if (userTheme === "dark") {
      toggleTheme(true);
      return;
    }

    if (userTheme === "light") {
      toggleTheme(false);
      return;
    }

    localStorage.setItem("theme", "light");
    toggleTheme(false);
  }

  document.addEventListener("DOMContentLoaded", () => init());
  document.addEventListener("astro:after-swap", () => init());
  preloadTheme();
</script><link rel="stylesheet" href="/_astro/_slug_.xItHpESY.css"></head> <body> <header> <div class="mx-auto max-w-screen-sm px-5">  <div class="flex flex-wrap gap-y-2 justify-between"> <a href="/" target="_self" class="inline-block decoration-black/15 dark:decoration-white/30 hover:decoration-black/25 hover:dark:decoration-white/50 text-current hover:text-black hover:dark:text-white transition-colors duration-300 ease-in-out">  <span class="inline-flex items-center justify-center size-12 md:size-14" aria-hidden="true"> <img src="/logo-light.svg" alt="" class="size-full dark:hidden"> <img src="/logo-dark.svg" alt="" class="hidden size-full dark:block"> </span>  </a> </div>  </div> </header> <main>  <div class="mx-auto max-w-screen-sm px-5">  <h4 class="animate font-semibold text-black dark:text-white">
Haigh, a chairde <span class="text-xl">👋🏻</span> </h4> <section class="animate mt-4"> <div class="overflow-hidden rounded-2xl"> <img src="/_astro/peter-hero-portrait.D6AS_S3h_Z2i5zyR.webp" srcset="/_astro/peter-hero-portrait.D6AS_S3h_ZcvLHR.webp 640w, /_astro/peter-hero-portrait.D6AS_S3h_1OFohl.webp 960w, /_astro/peter-hero-portrait.D6AS_S3h_1KyaAl.webp 1280w, /_astro/peter-hero-portrait.D6AS_S3h_Z2i5zyR.webp 1536w" alt="Peter Elst smiling on a beach at sunset." sizes="(max-width: 768px) calc(100vw - 2.5rem), 640px" loading="lazy" decoding="async" fetchpriority="low" width="1536" height="1024" class="h-auto w-full object-cover"> </div> </section> <section class="mt-6"> <article class="space-y-4"> <p class="animate">
I’m Peter Elst, a senior software engineer and technology enthusiast with a passion
            for the Irish language. This is a space for some of my thoughts, <a href="/letters/" class="underline underline-offset-4">letters to the editor</a> and experiments with learning in public.
</p> <p class="animate">
I’d love to hear from you, so please don’t hesitate to <a href="#connect" class="underline underline-offset-4">get in touch</a> with ideas or suggestions. Míle buíochas!
</p> </article> </section> <div class="mt-16 space-y-16">  <section class="animate space-y-6"> <div class="flex flex-wrap gap-y-2 items-center justify-between"> <h5 class="text-lg font-semibold text-black dark:text-white">
Work experience
</h5> <a href="https://linkedin.com/in/peterelst" target="_blank" class="inline-block decoration-black/15 dark:decoration-white/30 hover:decoration-black/25 hover:dark:decoration-white/50 text-current hover:text-black hover:dark:text-white transition-colors duration-300 ease-in-out underline underline-offset-2"> 
See all work
 </a> </div> <ul class="flex flex-col divide-y divide-black/8 dark:divide-white/6"> <li class="py-3"> <div class="text-sm opacity-75"> January 2024 - Present </div> <div class="mt-1.5 font-semibold text-black dark:text-white"> HubSpot </div> <div class="text-sm opacity-75"> Senior Software Engineer II </div> <article class="mt-1.5 leading-snug [&>p]:m-0"> <p>I’m working on Multi-Account Management features for upmarket enterprise customers including cross-account asset copying, data sharing and reporting.</p> </article> </li><li class="py-3"> <div class="text-sm opacity-75"> June 2011 - August 2023 </div> <div class="mt-1.5 font-semibold text-black dark:text-white"> Google </div> <div class="text-sm opacity-75"> Senior Software Engineer </div> <article class="mt-1.5 leading-snug [&>p]:m-0"> <p>I’ve worked in solutions consulting and senior software engineering roles across business operations and YouTube, Google Home and Stadia teams.</p> </article> </li> </ul> </section> <section class="animate space-y-6"> <div class="flex flex-wrap gap-y-2 items-center"> <h5 class="text-lg font-semibold text-black dark:text-white">
Recent projects
</h5> </div> <ul class="flex flex-col gap-4"> <li> <div class="group rounded-lg border border-black/15 dark:border-white/20 transition-colors duration-300 ease-in-out hover:bg-black/5 dark:hover:bg-white/5 hover:text-black dark:hover:text-white"> <div class="flex items-center gap-3 py-3 px-4"> <div class="min-w-0 flex-1"> <div class="truncate font-semibold"> GaeilgeTime </div> <div class="truncate text-sm"> Irish language learning app. </div> </div> <div class="flex shrink-0 items-center gap-3"> <nav class="inline-flex items-center gap-3 text-black/45 dark:text-white/45"><a href="https://www.gaeilgetime.ie/android" target="_blank" class="inline-block decoration-black/15 dark:decoration-white/30 hover:decoration-black/25 hover:dark:decoration-white/50 text-current hover:text-black hover:dark:text-white transition-colors duration-300 ease-in-out" aria-label="Open Android app" data-project-platform-link="true" data-platform="android" data-project-title="GaeilgeTime" data-project-slug="gaeilgetime"> <span class="inline-flex size-6 items-center justify-center align-middle"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="translate-y-[0.16rem] stroke-[1.5] fill-none stroke-current transition-colors duration-300 ease-in-out hover:text-black dark:hover:text-white size-6 scale-y-[1.28]" aria-hidden="true"><path stroke="none" d="M0 0h24v24H0z" fill="none"></path><path d="M4 10l0 4"></path><path d="M20 10l0 4"></path><path d="M7 9h10v6a1 1 0 0 1 -1 1h-8a1 1 0 0 1 -1 -1v-6a5 5 0 0 1 10 0"></path><path d="M8 3l1 2"></path><path d="M16 3l-1 2"></path><path d="M8 16l0 2"></path><path d="M16 16l0 2"></path></svg></span> </a><a href="https://www.gaeilgetime.ie/iphone" target="_blank" class="inline-block decoration-black/15 dark:decoration-white/30 hover:decoration-black/25 hover:dark:decoration-white/50 text-current hover:text-black hover:dark:text-white transition-colors duration-300 ease-in-out" aria-label="Open iOS app" data-project-platform-link="true" data-platform="ios" data-project-title="GaeilgeTime" data-project-slug="gaeilgetime"> <span class="inline-flex size-6 items-center justify-center align-middle"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="-translate-y-[0.03rem] stroke-[1.5] fill-none stroke-current transition-colors duration-300 ease-in-out hover:text-black dark:hover:text-white size-6" aria-hidden="true"><path stroke="none" d="M0 0h24v24H0z" fill="none"></path><path d="M8.286 7.008c-3.216 0 -4.286 3.23 -4.286 5.92c0 3.229 2.143 8.072 4.286 8.072c1.165 -.05 1.799 -.538 3.214 -.538c1.406 0 1.607 .538 3.214 .538s4.286 -3.229 4.286 -5.381c-.03 -.011 -2.649 -.434 -2.679 -3.23c-.02 -2.335 2.589 -3.179 2.679 -3.228c-1.096 -1.606 -3.162 -2.113 -3.75 -2.153c-1.535 -.12 -3.032 1.077 -3.75 1.077c-.729 0 -2.036 -1.077 -3.214 -1.077"></path><path d="M12 4a2 2 0 0 0 2 -2a2 2 0 0 0 -2 2"></path></svg></span> </a></nav><script>
  (() => {
    /** @type {any} */
    const analyticsWindow = window;
    if (analyticsWindow.__projectPlatformAnalyticsReady) return;
    analyticsWindow.__projectPlatformAnalyticsReady = true;

    document.addEventListener("click", (event) => {
      const link = event.target instanceof Element
        ? event.target.closest("[data-project-platform-link]")
        : null;

      if (!(link instanceof HTMLAnchorElement)) return;
      if (typeof analyticsWindow.trackEvent !== "function") return;

      analyticsWindow.trackEvent("project_platform_click", {
        project_title: link.dataset.projectTitle,
        project_slug: link.dataset.projectSlug,
        platform: link.dataset.platform,
        destination_url: link.href,
        page_path: analyticsWindow.location.pathname,
      });
    });
  })();
</script> </div> </div> </div> </li><li> <div class="group rounded-lg border border-black/15 dark:border-white/20 transition-colors duration-300 ease-in-out hover:bg-black/5 dark:hover:bg-white/5 hover:text-black dark:hover:text-white"> <div class="flex items-center gap-3 py-3 px-4"> <div class="min-w-0 flex-1"> <div class="truncate font-semibold"> Seanchló </div> <div class="truncate text-sm"> Convert between modern and old Irish Gaelic typography. </div> </div> <div class="flex shrink-0 items-center gap-3"> <nav class="inline-flex items-center gap-3 text-black/45 dark:text-white/45"><a href="https://gaeil.ge/seanchlo" target="_blank" class="inline-block decoration-black/15 dark:decoration-white/30 hover:decoration-black/25 hover:dark:decoration-white/50 text-current hover:text-black hover:dark:text-white transition-colors duration-300 ease-in-out" aria-label="Open iOS app" data-project-platform-link="true" data-platform="ios" data-project-title="Seanchló" data-project-slug="seanchlo"> <span class="inline-flex size-6 items-center justify-center align-middle"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="-translate-y-[0.03rem] stroke-[1.5] fill-none stroke-current transition-colors duration-300 ease-in-out hover:text-black dark:hover:text-white size-6" aria-hidden="true"><path stroke="none" d="M0 0h24v24H0z" fill="none"></path><path d="M8.286 7.008c-3.216 0 -4.286 3.23 -4.286 5.92c0 3.229 2.143 8.072 4.286 8.072c1.165 -.05 1.799 -.538 3.214 -.538c1.406 0 1.607 .538 3.214 .538s4.286 -3.229 4.286 -5.381c-.03 -.011 -2.649 -.434 -2.679 -3.23c-.02 -2.335 2.589 -3.179 2.679 -3.228c-1.096 -1.606 -3.162 -2.113 -3.75 -2.153c-1.535 -.12 -3.032 1.077 -3.75 1.077c-.729 0 -2.036 -1.077 -3.214 -1.077"></path><path d="M12 4a2 2 0 0 0 2 -2a2 2 0 0 0 -2 2"></path></svg></span> </a></nav><script>
  (() => {
    /** @type {any} */
    const analyticsWindow = window;
    if (analyticsWindow.__projectPlatformAnalyticsReady) return;
    analyticsWindow.__projectPlatformAnalyticsReady = true;

    document.addEventListener("click", (event) => {
      const link = event.target instanceof Element
        ? event.target.closest("[data-project-platform-link]")
        : null;

      if (!(link instanceof HTMLAnchorElement)) return;
      if (typeof analyticsWindow.trackEvent !== "function") return;

      analyticsWindow.trackEvent("project_platform_click", {
        project_title: link.dataset.projectTitle,
        project_slug: link.dataset.projectSlug,
        platform: link.dataset.platform,
        destination_url: link.href,
        page_path: analyticsWindow.location.pathname,
      });
    });
  })();
</script> </div> </div> </div> </li><li> <div class="group rounded-lg border border-black/15 dark:border-white/20 transition-colors duration-300 ease-in-out hover:bg-black/5 dark:hover:bg-white/5 hover:text-black dark:hover:text-white"> <div class="flex items-center gap-3 py-3 px-4"> <div class="min-w-0 flex-1"> <div class="truncate font-semibold"> Ogham </div> <div class="truncate text-sm"> Convert modern Irish into ancient Ogham script. </div> </div> <div class="flex shrink-0 items-center gap-3"> <nav class="inline-flex items-center gap-3 text-black/45 dark:text-white/45"><a href="https://gaeil.ge/ogham" target="_blank" class="inline-block decoration-black/15 dark:decoration-white/30 hover:decoration-black/25 hover:dark:decoration-white/50 text-current hover:text-black hover:dark:text-white transition-colors duration-300 ease-in-out" aria-label="Open iOS app" data-project-platform-link="true" data-platform="ios" data-project-title="Ogham" data-project-slug="ogham"> <span class="inline-flex size-6 items-center justify-center align-middle"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="-translate-y-[0.03rem] stroke-[1.5] fill-none stroke-current transition-colors duration-300 ease-in-out hover:text-black dark:hover:text-white size-6" aria-hidden="true"><path stroke="none" d="M0 0h24v24H0z" fill="none"></path><path d="M8.286 7.008c-3.216 0 -4.286 3.23 -4.286 5.92c0 3.229 2.143 8.072 4.286 8.072c1.165 -.05 1.799 -.538 3.214 -.538c1.406 0 1.607 .538 3.214 .538s4.286 -3.229 4.286 -5.381c-.03 -.011 -2.649 -.434 -2.679 -3.23c-.02 -2.335 2.589 -3.179 2.679 -3.228c-1.096 -1.606 -3.162 -2.113 -3.75 -2.153c-1.535 -.12 -3.032 1.077 -3.75 1.077c-.729 0 -2.036 -1.077 -3.214 -1.077"></path><path d="M12 4a2 2 0 0 0 2 -2a2 2 0 0 0 -2 2"></path></svg></span> </a></nav><script>
  (() => {
    /** @type {any} */
    const analyticsWindow = window;
    if (analyticsWindow.__projectPlatformAnalyticsReady) return;
    analyticsWindow.__projectPlatformAnalyticsReady = true;

    document.addEventListener("click", (event) => {
      const link = event.target instanceof Element
        ? event.target.closest("[data-project-platform-link]")
        : null;

      if (!(link instanceof HTMLAnchorElement)) return;
      if (typeof analyticsWindow.trackEvent !== "function") return;

      analyticsWindow.trackEvent("project_platform_click", {
        project_title: link.dataset.projectTitle,
        project_slug: link.dataset.projectSlug,
        platform: link.dataset.platform,
        destination_url: link.href,
        page_path: analyticsWindow.location.pathname,
      });
    });
  })();
</script> </div> </div> </div> </li><li> <div class="group rounded-lg border border-black/15 dark:border-white/20 transition-colors duration-300 ease-in-out hover:bg-black/5 dark:hover:bg-white/5 hover:text-black dark:hover:text-white"> <div class="flex items-center gap-3 py-3 px-4"> <div class="min-w-0 flex-1"> <div class="truncate font-semibold"> Gaeil.ge </div> <div class="truncate text-sm"> URL shortener for Irish language resources. </div> </div> <div class="flex shrink-0 items-center gap-3"> <nav class="inline-flex items-center gap-3 text-black/45 dark:text-white/45"><a href="https://gaeil.ge" target="_blank" class="inline-block decoration-black/15 dark:decoration-white/30 hover:decoration-black/25 hover:dark:decoration-white/50 text-current hover:text-black hover:dark:text-white transition-colors duration-300 ease-in-out" aria-label="Open web app" data-project-platform-link="true" data-platform="web" data-project-title="Gaeil.ge" data-project-slug="gaeil-ge"> <span class="inline-flex size-6 items-center justify-center align-middle"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="stroke-[1.5] fill-none stroke-current transition-colors duration-300 ease-in-out hover:text-black dark:hover:text-white size-6" aria-hidden="true"><path stroke="none" d="M0 0h24v24H0z" fill="none"></path><path d="M3 12a9 9 0 1 0 18 0a9 9 0 0 0 -18 0"></path><path d="M3.6 9h16.8"></path><path d="M3.6 15h16.8"></path><path d="M11.5 3a17 17 0 0 0 0 18"></path><path d="M12.5 3a17 17 0 0 1 0 18"></path></svg></span> </a></nav><script>
  (() => {
    /** @type {any} */
    const analyticsWindow = window;
    if (analyticsWindow.__projectPlatformAnalyticsReady) return;
    analyticsWindow.__projectPlatformAnalyticsReady = true;

    document.addEventListener("click", (event) => {
      const link = event.target instanceof Element
        ? event.target.closest("[data-project-platform-link]")
        : null;

      if (!(link instanceof HTMLAnchorElement)) return;
      if (typeof analyticsWindow.trackEvent !== "function") return;

      analyticsWindow.trackEvent("project_platform_click", {
        project_title: link.dataset.projectTitle,
        project_slug: link.dataset.projectSlug,
        platform: link.dataset.platform,
        destination_url: link.href,
        page_path: analyticsWindow.location.pathname,
      });
    });
  })();
</script> </div> </div> </div> </li><li> <div class="group rounded-lg border border-black/15 dark:border-white/20 transition-colors duration-300 ease-in-out hover:bg-black/5 dark:hover:bg-white/5 hover:text-black dark:hover:text-white"> <div class="flex items-center gap-3 py-3 px-4"> <div class="min-w-0 flex-1"> <div class="truncate font-semibold"> Poet3 </div> <div class="truncate text-sm"> AI assisted creative writing app with daily poetry prompts. </div> </div> <div class="flex shrink-0 items-center gap-3"> <nav class="inline-flex items-center gap-3 text-black/45 dark:text-white/45"><a href="https://apps.apple.com/ie/app/poet3/id6751746017" target="_blank" class="inline-block decoration-black/15 dark:decoration-white/30 hover:decoration-black/25 hover:dark:decoration-white/50 text-current hover:text-black hover:dark:text-white transition-colors duration-300 ease-in-out" aria-label="Open iOS app" data-project-platform-link="true" data-platform="ios" data-project-title="Poet3" data-project-slug="poet3"> <span class="inline-flex size-6 items-center justify-center align-middle"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="-translate-y-[0.03rem] stroke-[1.5] fill-none stroke-current transition-colors duration-300 ease-in-out hover:text-black dark:hover:text-white size-6" aria-hidden="true"><path stroke="none" d="M0 0h24v24H0z" fill="none"></path><path d="M8.286 7.008c-3.216 0 -4.286 3.23 -4.286 5.92c0 3.229 2.143 8.072 4.286 8.072c1.165 -.05 1.799 -.538 3.214 -.538c1.406 0 1.607 .538 3.214 .538s4.286 -3.229 4.286 -5.381c-.03 -.011 -2.649 -.434 -2.679 -3.23c-.02 -2.335 2.589 -3.179 2.679 -3.228c-1.096 -1.606 -3.162 -2.113 -3.75 -2.153c-1.535 -.12 -3.032 1.077 -3.75 1.077c-.729 0 -2.036 -1.077 -3.214 -1.077"></path><path d="M12 4a2 2 0 0 0 2 -2a2 2 0 0 0 -2 2"></path></svg></span> </a></nav><script>
  (() => {
    /** @type {any} */
    const analyticsWindow = window;
    if (analyticsWindow.__projectPlatformAnalyticsReady) return;
    analyticsWindow.__projectPlatformAnalyticsReady = true;

    document.addEventListener("click", (event) => {
      const link = event.target instanceof Element
        ? event.target.closest("[data-project-platform-link]")
        : null;

      if (!(link instanceof HTMLAnchorElement)) return;
      if (typeof analyticsWindow.trackEvent !== "function") return;

      analyticsWindow.trackEvent("project_platform_click", {
        project_title: link.dataset.projectTitle,
        project_slug: link.dataset.projectSlug,
        platform: link.dataset.platform,
        destination_url: link.href,
        page_path: analyticsWindow.location.pathname,
      });
    });
  })();
</script> </div> </div> </div> </li> </ul> </section> <section id="connect" class="animate space-y-5"> <h5 class="text-lg font-semibold text-black dark:text-white">
Get in touch
</h5> <nav class="flex items-center gap-5 text-black/45 dark:text-white/45"> <a href="https://instagram.com/peterelst" target="_blank" class="inline-block decoration-black/15 dark:decoration-white/30 hover:decoration-black/25 hover:dark:decoration-white/50 text-current hover:text-black hover:dark:text-white transition-colors duration-300 ease-in-out" aria-label="Instagram">  <svg xmlns="http://www.w3.org/2000/svg" class="size-6 stroke-[1.7] fill-none stroke-current transition-colors duration-300 ease-in-out hover:text-black dark:hover:text-white" viewBox="0 0 24 24" aria-hidden="true"> <path stroke="none" d="M0 0h24v24H0z" fill="none"></path> <path d="M4 8a4 4 0 0 1 4 -4h8a4 4 0 0 1 4 4v8a4 4 0 0 1 -4 4h-8a4 4 0 0 1 -4 -4l0 -8"></path> <path d="M9 12a3 3 0 1 0 6 0a3 3 0 0 0 -6 0"></path> <path d="M16.5 7.5v.01"></path> </svg>  </a> <a href="https://www.threads.com/@peterelst" target="_blank" class="inline-block decoration-black/15 dark:decoration-white/30 hover:decoration-black/25 hover:dark:decoration-white/50 text-current hover:text-black hover:dark:text-white transition-colors duration-300 ease-in-out" aria-label="Threads">  <svg xmlns="http://www.w3.org/2000/svg" class="size-6 stroke-[1.7] fill-none stroke-current transition-colors duration-300 ease-in-out hover:text-black dark:hover:text-white" viewBox="0 0 24 24" aria-hidden="true"> <path stroke="none" d="M0 0h24v24H0z" fill="none"></path> <path d="M19 7.5c-1.333 -3 -3.667 -4.5 -7 -4.5c-5 0 -8 2.5 -8 9s3.5 9 8 9s7 -3 7 -5s-1 -5 -7 -5c-2.5 0 -3 1.25 -3 2.5c0 1.5 1 2.5 2.5 2.5c2.5 0 3.5 -1.5 3.5 -5s-2 -4 -3 -4s-1.833 .333 -2.5 1"></path> </svg>  </a> <a href="https://linkedin.com/in/peterelst" target="_blank" class="inline-block decoration-black/15 dark:decoration-white/30 hover:decoration-black/25 hover:dark:decoration-white/50 text-current hover:text-black hover:dark:text-white transition-colors duration-300 ease-in-out" aria-label="LinkedIn">  <svg xmlns="http://www.w3.org/2000/svg" class="size-6 stroke-[1.7] fill-none stroke-current transition-colors duration-300 ease-in-out hover:text-black dark:hover:text-white" viewBox="0 0 24 24" aria-hidden="true"> <path stroke="none" d="M0 0h24v24H0z" fill="none"></path> <path d="M8 11v5"></path> <path d="M8 8v.01"></path> <path d="M12 16v-5"></path> <path d="M16 16v-3a2 2 0 1 0 -4 0"></path> <path d="M3 7a4 4 0 0 1 4 -4h10a4 4 0 0 1 4 4v10a4 4 0 0 1 -4 4h-10a4 4 0 0 1 -4 -4l0 -10"></path> </svg>  </a> <a href="https://www.facebook.com/peterelst" target="_blank" class="inline-block decoration-black/15 dark:decoration-white/30 hover:decoration-black/25 hover:dark:decoration-white/50 text-current hover:text-black hover:dark:text-white transition-colors duration-300 ease-in-out" aria-label="Facebook">  <svg xmlns="http://www.w3.org/2000/svg" class="size-6 stroke-[1.7] fill-none stroke-current transition-colors duration-300 ease-in-out hover:text-black dark:hover:text-white" viewBox="0 0 24 24" aria-hidden="true"> <path stroke="none" d="M0 0h24v24H0z" fill="none"></path> <path d="M7 10v4h3v7h4v-7h3l1 -4h-4v-2a1 1 0 0 1 1 -1h3v-4h-3a5 5 0 0 0 -5 5v2h-3"></path> </svg>  </a> <a href="https://github.com/peterelst" target="_blank" class="inline-block decoration-black/15 dark:decoration-white/30 hover:decoration-black/25 hover:dark:decoration-white/50 text-current hover:text-black hover:dark:text-white transition-colors duration-300 ease-in-out" aria-label="GitHub">  <svg xmlns="http://www.w3.org/2000/svg" class="size-6 stroke-[1.7] fill-none stroke-current transition-colors duration-300 ease-in-out hover:text-black dark:hover:text-white" viewBox="0 0 24 24" aria-hidden="true"> <path stroke="none" d="M0 0h24v24H0z" fill="none"></path> <path d="M9 19c-4.3 1.4 -4.3 -2.5 -6 -3m12 6v-3.87a3.37 3.37 0 0 0 -.94 -2.61c3.14 -.35 6.44 -1.54 6.44 -7a5.44 5.44 0 0 0 -1.5 -3.75a5.07 5.07 0 0 0 -.09 -3.77s-1.18 -.35 -3.91 1.48a13.38 13.38 0 0 0 -7 0c-2.73 -1.83 -3.91 -1.48 -3.91 -1.48a5.07 5.07 0 0 0 -.09 3.77a5.44 5.44 0 0 0 -1.5 3.75c0 5.42 3.3 6.61 6.44 7a3.37 3.37 0 0 0 -.94 2.61v3.87"></path> </svg>  </a> <a href="/cdn-cgi/l/email-protection#a7d7c2d3c2d589c2cbd4d3e7c0cac6cecb89c4c8ca" target="_self" class="inline-block decoration-black/15 dark:decoration-white/30 hover:decoration-black/25 hover:dark:decoration-white/50 text-current hover:text-black hover:dark:text-white transition-colors duration-300 ease-in-out" aria-label="Email">  <svg xmlns="http://www.w3.org/2000/svg" class="size-6 stroke-[1.7] fill-none stroke-current transition-colors duration-300 ease-in-out hover:text-black dark:hover:text-white" viewBox="0 0 24 24" aria-hidden="true"> <path stroke="none" d="M0 0h24v24H0z" fill="none"></path> <path d="M3 7a2 2 0 0 1 2 -2h14a2 2 0 0 1 2 2v10a2 2 0 0 1 -2 2h-14a2 2 0 0 1 -2 -2v-10z"></path> <path d="M3 7l9 6l9 -6"></path> </svg>  </a> </nav> </section> </div>  </div>  </main> <footer class="animate"> <div class="mx-auto max-w-screen-sm px-5">  <div class="relative"> <div class="absolute right-0 -top-20"> <button id="back-to-top" class="relative group w-fit flex pl-8 pr-3 py-1.5 flex-nowrap rounded border border-black/15 dark:border-white/20 hover:bg-black/5 dark:hover:bg-white/5 hover:text-black dark:hover:text-white transition-colors duration-300 ease-in-out"> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="absolute top-1/2 left-2 -translate-y-1/2 size-4 stroke-2 fill-none stroke-current rotate-90"> <line x1="5" y1="12" x2="19" y2="12" class="translate-x-2 group-hover:translate-x-0 scale-x-0 group-hover:scale-x-100 transition-transform duration-300 ease-in-out"></line> <polyline points="12 5 5 12 12 19" class="translate-x-1 group-hover:translate-x-0 transition-transform duration-300 ease-in-out"></polyline> </svg> <div class="text-sm">
Back to top
</div> </button> </div> </div> <div class="relative flex items-center"> <div class="text-[clamp(0.64rem,2.1vw,0.88rem)] leading-tight whitespace-nowrap">
&copy; 2026 Peter Elst | Ar scáth a chéile a mhaireann na daoine 💚
</div> <div class="absolute right-0 flex flex-wrap gap-1 items-center"> <button id="theme-toggle-button" aria-label="Toggle theme" class="group size-8 flex items-center justify-center rounded-full"> <svg class="hidden dark:block group-hover:stroke-white transition-colors duration-300 ease-in-out" xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"> <circle cx="12" cy="12" r="5"></circle> <line x1="12" y1="1" x2="12" y2="3"></line> <line x1="12" y1="21" x2="12" y2="23"></line> <line x1="4.22" y1="4.22" x2="5.64" y2="5.64"></line> <line x1="18.36" y1="18.36" x2="19.78" y2="19.78"></line> <line x1="1" y1="12" x2="3" y2="12"></line> <line x1="21" y1="12" x2="23" y2="12"></line> <line x1="4.22" y1="19.78" x2="5.64" y2="18.36"></line> <line x1="18.36" y1="5.64" x2="19.78" y2="4.22"></line> </svg> <svg class="dark:hidden group-hover:stroke-black transition-colors duration-300 ease-in-out" xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"> <path d="M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z"></path> </svg> </button> </div> </div>  </div> </footer> <script data-cfasync="false" src="/cdn-cgi/scripts/5c5dd728/cloudflare-static/email-decode.min.js"></script></body></html>