<!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/x-icon" href="/favicon.ico"><link rel="icon" href="data:image/svg+xml,<svg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 100 100%22><text y=%22.9em%22 font-size=%2290%22>JM</text></svg>"><meta name="generator" content="Astro v5.13.9"><!-- Privacy-friendly analytics by Plausible --><script async src="https://plausible.io/js/pa-7vX3ngYIdunLSOx8V01TS.js"></script><script>
  window.plausible=window.plausible||function(){(plausible.q=plausible.q||[]).push(arguments)},plausible.init=plausible.init||function(i){plausible.o=i||{}};
  plausible.init()
</script><!-- Canonical URL --><link rel="canonical" href="https://jmurphy.studio/"><!-- Primary Meta Tags --><title>Home | Justin Murphy</title><meta name="title" content="Home | Justin Murphy"><meta name="description" content="Writing by Justin Murphy on philosophy, social science, technology, and independent scholarship."><!-- Open Graph / Facebook --><meta property="og:type" content="website"><meta property="og:url" content="https://jmurphy.studio/"><meta property="og:title" content="Home | Justin Murphy"><meta property="og:description" content="Writing by Justin Murphy on philosophy, social science, technology, and independent scholarship."><meta property="og:image" content="https://jmurphy.studio/og-image.jpg"><!-- Twitter --><meta property="twitter:card" content="summary_large_image"><meta property="twitter:url" content="https://jmurphy.studio/"><meta property="twitter:title" content="Home | Justin Murphy"><meta property="twitter:description" content="Writing by Justin Murphy on philosophy, social science, technology, and independent scholarship."><meta property="twitter:image" content="https://jmurphy.studio/og-image.jpg"><!-- PageFind --><link href="/pagefind/pagefind-ui.css" rel="stylesheet"><script src="/pagefind/pagefind-ui.js"></script><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.B3vRBseb.js"></script><script>
  function init() {
    preloadTheme();
    onScroll();
    animate();
    updateThemeButtons();
    addCopyCodeButtons();
    setGiscusTheme();

    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 lightThemeButton = document.getElementById("light-theme-button");
    lightThemeButton?.addEventListener("click", () => {
      localStorage.setItem("theme", "light");
      toggleTheme(false);
      updateThemeButtons();
    });

    const darkThemeButton = document.getElementById("dark-theme-button");
    darkThemeButton?.addEventListener("click", () => {
      localStorage.setItem("theme", "dark");
      toggleTheme(true);
      updateThemeButtons();
    });

    const systemThemeButton = document.getElementById("system-theme-button");
    systemThemeButton?.addEventListener("click", () => {
      localStorage.setItem("theme", "system");
      toggleTheme(window.matchMedia("(prefers-color-scheme: dark)").matches);
      updateThemeButtons();
    });

    window
      .matchMedia("(prefers-color-scheme: dark)")
      .addEventListener("change", (event) => {
        if (localStorage.theme === "system") {
          toggleTheme(event.matches);
        }
      });

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

  function updateThemeButtons() {
    const theme = localStorage.getItem("theme");
    const lightThemeButton = document.getElementById("light-theme-button");
    const darkThemeButton = document.getElementById("dark-theme-button");
    const systemThemeButton = document.getElementById("system-theme-button");

    function removeActiveButtonTheme(button) {
      button?.classList.remove("bg-black/5");
      button?.classList.remove("dark:bg-white/5");
    }

    function addActiveButtonTheme(button) {
      button?.classList.add("bg-black/5");
      button?.classList.add("dark:bg-white/5");
    }

    removeActiveButtonTheme(lightThemeButton);
    removeActiveButtonTheme(darkThemeButton);
    removeActiveButtonTheme(systemThemeButton);

    if (theme === "light") {
      addActiveButtonTheme(lightThemeButton);
    } else if (theme === "dark") {
      addActiveButtonTheme(darkThemeButton);
    } else {
      addActiveButtonTheme(systemThemeButton);
    }
  }

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

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

  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);

    setGiscusTheme();
  }

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

    if (userTheme === "light" || userTheme === "dark") {
      toggleTheme(userTheme === "dark");
    } else {
      toggleTheme(window.matchMedia("(prefers-color-scheme: dark)").matches);
    }
  }

  function addCopyCodeButtons() {
    let copyButtonLabel = "📋";
    let codeBlocks = Array.from(document.querySelectorAll("pre"));

    async function copyCode(codeBlock, copyButton) {
      const codeText = codeBlock.innerText;
      const buttonText = copyButton.innerText;
      const textToCopy = codeText.replace(buttonText, "");

      await navigator.clipboard.writeText(textToCopy);
      copyButton.innerText = "✅";

      setTimeout(() => {
        copyButton.innerText = copyButtonLabel;
      }, 2000);
    }

    for (let codeBlock of codeBlocks) {
      const wrapper = document.createElement("div");
      wrapper.style.position = "relative";

      const copyButton = document.createElement("button");
      copyButton.innerText = copyButtonLabel;
      copyButton.classList = "copy-code";

      codeBlock.setAttribute("tabindex", "0");
      codeBlock.appendChild(copyButton);

      codeBlock.parentNode.insertBefore(wrapper, codeBlock);
      wrapper.appendChild(codeBlock);

      copyButton?.addEventListener("click", async () => {
        await copyCode(codeBlock, copyButton);
      });
    }
  }

  const setGiscusTheme = () => {
    const giscus = document.querySelector(".giscus-frame");

    const isDark = document.documentElement.classList.contains("dark");

    if (giscus) {
      const url = new URL(giscus.src);
      url.searchParams.set("theme", isDark ? "dark" : "light");
      giscus.src = url.toString();
    }
  };

  document.addEventListener("DOMContentLoaded", () => init());
  document.addEventListener("astro:after-swap", () => init());
  preloadTheme();
</script><link rel="stylesheet" href="/_astro/_slug_.Bnt4Scs3.css"></head> <body> <noscript> <style>
        .animate{
          opacity:1;
          translate: var(--tw-translate-x) calc(var(--spacing) * 0);
        }
      </style> </noscript> <header data-astro-transition-persist="astro-l7r54iwe-1"> <div class="mx-auto max-w-(--breakpoint-sm) px-3"> <div class="flex flex-wrap justify-between gap-y-2"> <a href="/" target="_self" class="inline-block decoration-black/30 dark:decoration-white/30 hover:decoration-black/50 focus-visible:decoration-black/50 dark:hover:decoration-white/50 dark:focus-visible:decoration-white/50 text-current hover:text-black focus-visible:text-black dark:hover:text-white dark:focus-visible:text-white transition-colors duration-300 ease-in-out">  <div class="font-semibold"> Justin Murphy </div>  </a> <nav class="flex items-center gap-1 text-sm"> <a href="/books" target="_self" class="inline-block decoration-black/30 dark:decoration-white/30 hover:decoration-black/50 focus-visible:decoration-black/50 dark:hover:decoration-white/50 dark:focus-visible:decoration-white/50 text-current hover:text-black focus-visible:text-black dark:hover:text-white dark:focus-visible:text-white transition-colors duration-300 ease-in-out underline underline-offset-[3px]"> Books </a> <span> / </span> <a href="/archive" target="_self" class="inline-block decoration-black/30 dark:decoration-white/30 hover:decoration-black/50 focus-visible:decoration-black/50 dark:hover:decoration-white/50 dark:focus-visible:decoration-white/50 text-current hover:text-black focus-visible:text-black dark:hover:text-white dark:focus-visible:text-white transition-colors duration-300 ease-in-out underline underline-offset-[3px]"> Archive </a> </nav> </div> </div> </header> <main>  <div class="mx-auto max-w-(--breakpoint-sm) px-3"> <aside data-pagefind-ignore> <div class="space-y-16"> <section> <article class="space-y-4"> <span class="animate"> <p>
I write about philosophy, social science, technology, and the
                independent life of the mind.
</p> </span> <span class="animate"> <p>
I was a professor of Political Science at the University of
                Southampton from 2014 to 2019. My academic and public writing
                has appeared in <em>International Studies Quarterly</em>, the
<em>British Journal of Political Science</em>, <em>Foreign Affairs</em>,
                and the <em>New Statesman</em>. I later founded Other Life and
                Indie Scholars.
</p> </span> <span class="animate"> <p>This site is the complete archive of my published writing.</p> </span> </article> </section> <section class="animate space-y-6"> <div class="flex flex-wrap items-center justify-between gap-y-2"> <h2 class="font-semibold text-black dark:text-white">
Latest writing
</h2> <a href="/archive" target="_self" class="inline-block decoration-black/30 dark:decoration-white/30 hover:decoration-black/50 focus-visible:decoration-black/50 dark:hover:decoration-white/50 dark:focus-visible:decoration-white/50 text-current hover:text-black focus-visible:text-black dark:hover:text-white dark:focus-visible:text-white transition-colors duration-300 ease-in-out underline underline-offset-[3px]">  See the archive  </a> </div> <ul class="not-prose flex flex-col gap-4"> <li> <a href="/supreme-court-ensemble-llms" class="not-prose group relative flex flex-nowrap rounded-lg border border-black/15 px-4 py-3 pr-10 transition-colors duration-300 ease-in-out hover:bg-black/5 hover:text-black focus-visible:bg-black/5 focus-visible:text-black dark:border-white/20 dark:hover:bg-white/5 dark:hover:text-white dark:focus-visible:bg-white/5 dark:focus-visible:text-white"> <div class="flex flex-1 flex-col truncate"> <div class="font-semibold"> The Supreme Court Should Be an Ensemble of LLMs </div> <div class="text-sm"> LLMs can process human language with formal rigor—the function of Supreme Court justices. </div> </div> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="absolute right-2 top-1/2 size-5 -translate-y-1/2 fill-none stroke-current stroke-2"> <line x1="5" y1="12" x2="19" y2="12" class="translate-x-3 scale-x-0 transition-transform duration-300 ease-in-out group-hover:translate-x-0 group-hover:scale-x-100 group-focus-visible:translate-x-0 group-focus-visible:scale-x-100"></line> <polyline points="12 5 19 12 12 19" class="-translate-x-1 transition-transform duration-300 ease-in-out group-hover:translate-x-0 group-focus-visible:translate-x-0"></polyline> </svg> </a> </li><li> <a href="/the-bari-weiss-strategy" class="not-prose group relative flex flex-nowrap rounded-lg border border-black/15 px-4 py-3 pr-10 transition-colors duration-300 ease-in-out hover:bg-black/5 hover:text-black focus-visible:bg-black/5 focus-visible:text-black dark:border-white/20 dark:hover:bg-white/5 dark:hover:text-white dark:focus-visible:bg-white/5 dark:focus-visible:text-white"> <div class="flex flex-1 flex-col truncate"> <div class="font-semibold"> The Bari Weiss Strategy </div> <div class="text-sm"> Notes on a $150M playbook that&#39;s never been written down </div> </div> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="absolute right-2 top-1/2 size-5 -translate-y-1/2 fill-none stroke-current stroke-2"> <line x1="5" y1="12" x2="19" y2="12" class="translate-x-3 scale-x-0 transition-transform duration-300 ease-in-out group-hover:translate-x-0 group-hover:scale-x-100 group-focus-visible:translate-x-0 group-focus-visible:scale-x-100"></line> <polyline points="12 5 19 12 12 19" class="-translate-x-1 transition-transform duration-300 ease-in-out group-hover:translate-x-0 group-focus-visible:translate-x-0"></polyline> </svg> </a> </li><li> <a href="/in-domestic-war-beware-the-rabble" class="not-prose group relative flex flex-nowrap rounded-lg border border-black/15 px-4 py-3 pr-10 transition-colors duration-300 ease-in-out hover:bg-black/5 hover:text-black focus-visible:bg-black/5 focus-visible:text-black dark:border-white/20 dark:hover:bg-white/5 dark:hover:text-white dark:focus-visible:bg-white/5 dark:focus-visible:text-white"> <div class="flex flex-1 flex-col truncate"> <div class="font-semibold"> In Domestic War, Beware the Rabble </div> <div class="text-sm"> Notes on an &quot;unfortunate season&quot; of civil conflict </div> </div> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="absolute right-2 top-1/2 size-5 -translate-y-1/2 fill-none stroke-current stroke-2"> <line x1="5" y1="12" x2="19" y2="12" class="translate-x-3 scale-x-0 transition-transform duration-300 ease-in-out group-hover:translate-x-0 group-hover:scale-x-100 group-focus-visible:translate-x-0 group-focus-visible:scale-x-100"></line> <polyline points="12 5 19 12 12 19" class="-translate-x-1 transition-transform duration-300 ease-in-out group-hover:translate-x-0 group-focus-visible:translate-x-0"></polyline> </svg> </a> </li><li> <a href="/karp" class="not-prose group relative flex flex-nowrap rounded-lg border border-black/15 px-4 py-3 pr-10 transition-colors duration-300 ease-in-out hover:bg-black/5 hover:text-black focus-visible:bg-black/5 focus-visible:text-black dark:border-white/20 dark:hover:bg-white/5 dark:hover:text-white dark:focus-visible:bg-white/5 dark:focus-visible:text-white"> <div class="flex flex-1 flex-col truncate"> <div class="font-semibold"> Alexander Karp&#39;s Iron Cage: A Review of The Technological Republic </div> <div class="text-sm"> I wanted to love it, but Alexander Karp&#39;s new book is a mess of contradictions and a bloody revenge by the Frankfurt School against the school of American Optimism. </div> </div> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="absolute right-2 top-1/2 size-5 -translate-y-1/2 fill-none stroke-current stroke-2"> <line x1="5" y1="12" x2="19" y2="12" class="translate-x-3 scale-x-0 transition-transform duration-300 ease-in-out group-hover:translate-x-0 group-hover:scale-x-100 group-focus-visible:translate-x-0 group-focus-visible:scale-x-100"></line> <polyline points="12 5 19 12 12 19" class="-translate-x-1 transition-transform duration-300 ease-in-out group-hover:translate-x-0 group-focus-visible:translate-x-0"></polyline> </svg> </a> </li><li> <a href="/plato-playbook" class="not-prose group relative flex flex-nowrap rounded-lg border border-black/15 px-4 py-3 pr-10 transition-colors duration-300 ease-in-out hover:bg-black/5 hover:text-black focus-visible:bg-black/5 focus-visible:text-black dark:border-white/20 dark:hover:bg-white/5 dark:hover:text-white dark:focus-visible:bg-white/5 dark:focus-visible:text-white"> <div class="flex flex-1 flex-col truncate"> <div class="font-semibold"> Plato&#39;s Playbook </div> <div class="text-sm"> Influence and Intellect in the Ancient World </div> </div> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="absolute right-2 top-1/2 size-5 -translate-y-1/2 fill-none stroke-current stroke-2"> <line x1="5" y1="12" x2="19" y2="12" class="translate-x-3 scale-x-0 transition-transform duration-300 ease-in-out group-hover:translate-x-0 group-hover:scale-x-100 group-focus-visible:translate-x-0 group-focus-visible:scale-x-100"></line> <polyline points="12 5 19 12 12 19" class="-translate-x-1 transition-transform duration-300 ease-in-out group-hover:translate-x-0 group-focus-visible:translate-x-0"></polyline> </svg> </a> </li> </ul> </section> <section class="animate space-y-4"> <ul class="not-prose flex flex-wrap gap-2"> <li class="flex gap-x-2 text-nowrap"> <a href="https://twitter.com/jmurphy" target="_blank" class="inline-block decoration-black/30 dark:decoration-white/30 hover:decoration-black/50 focus-visible:decoration-black/50 dark:hover:decoration-white/50 dark:focus-visible:decoration-white/50 text-current hover:text-black focus-visible:text-black dark:hover:text-white dark:focus-visible:text-white transition-colors duration-300 ease-in-out underline underline-offset-[3px]" aria-label="Justin Murphy on X (formerly Twitter)"> X (formerly Twitter) </a> / </li><li class="flex gap-x-2 text-nowrap"> <a href="https://www.youtube.com/@JustinMurphy" target="_blank" class="inline-block decoration-black/30 dark:decoration-white/30 hover:decoration-black/50 focus-visible:decoration-black/50 dark:hover:decoration-white/50 dark:focus-visible:decoration-white/50 text-current hover:text-black focus-visible:text-black dark:hover:text-white dark:focus-visible:text-white transition-colors duration-300 ease-in-out underline underline-offset-[3px]" aria-label="Justin Murphy on YouTube"> YouTube </a> / </li> <li class="line-clamp-1"> <a href="mailto:justin@otherlife.co" target="_self" class="inline-block decoration-black/30 dark:decoration-white/30 hover:decoration-black/50 focus-visible:decoration-black/50 dark:hover:decoration-white/50 dark:focus-visible:decoration-white/50 text-current hover:text-black focus-visible:text-black dark:hover:text-white dark:focus-visible:text-white transition-colors duration-300 ease-in-out underline underline-offset-[3px]" aria-label="Email Justin Murphy"> justin@otherlife.co </a> </li> </ul> </section> </div> </aside> </div>  </main> <footer class="animate"> <div class="mx-auto max-w-(--breakpoint-sm) px-3"> <div class="relative"> <div class="absolute -top-12 right-0"> <script type="module">typeof window<"u"&&window.addEventListener("DOMContentLoaded",()=>{const e=document.getElementById("back-to-top");e&&e.addEventListener("click",()=>{window.scrollTo({top:0,behavior:"smooth"})})});</script> <button id="back-to-top" class="group relative flex w-fit flex-nowrap rounded-sm border border-black/15 py-1.5 pl-8 pr-3 transition-colors duration-300 ease-in-out hover:bg-black/5 hover:text-black focus-visible:bg-black/5 focus-visible:text-black dark:border-white/20 dark:hover:bg-white/5 dark:hover:text-white dark:focus-visible:bg-white/5 dark:focus-visible:text-white"> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="absolute left-2 top-1/2 size-4 -translate-y-1/2 rotate-90 fill-none stroke-current stroke-2"> <line x1="5" y1="12" x2="19" y2="12" class="translate-x-2 scale-x-0 transition-transform duration-300 ease-in-out group-hover:translate-x-0 group-hover:scale-x-100 group-focus-visible:translate-x-0 group-focus-visible:scale-x-100"></line> <polyline points="12 5 5 12 12 19" class="translate-x-1 transition-transform duration-300 ease-in-out group-hover:translate-x-0 group-focus-visible:translate-x-0"></polyline> </svg> <div class="text-sm">Back to top</div> </button> </div> </div> <div class="flex items-center justify-between"> <div>&copy; 2026 • Justin Murphy</div> <div class="flex flex-wrap items-center gap-1.5"> <button id="light-theme-button" aria-label="Light theme" class="group flex size-9 items-center justify-center rounded-sm border border-black/15 hover:bg-black/5 focus-visible:bg-black/5 dark:border-white/20 dark:hover:bg-white/5 dark:focus-visible:bg-white/5"> <svg 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" class="transition-colors duration-300 ease-in-out group-hover:animate-pulse group-hover:stroke-black group-focus-visible:animate-pulse group-focus-visible:stroke-black dark:group-hover:stroke-white dark:group-focus-visible:stroke-white"> <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> </button> <button id="dark-theme-button" aria-label="Dark theme" class="group flex size-9 items-center justify-center rounded-sm border border-black/15 hover:bg-black/5 focus-visible:bg-black/5 dark:border-white/20 dark:hover:bg-white/5 dark:focus-visible:bg-white/5"> <svg 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" class="transition-colors duration-300 ease-in-out group-hover:animate-pulse group-hover:stroke-black group-focus-visible:animate-pulse group-focus-visible:stroke-black dark:group-hover:stroke-white dark:group-focus-visible:stroke-white"> <path d="M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z"></path> </svg> </button> <button id="system-theme-button" aria-label="System theme" class="group flex size-9 items-center justify-center rounded-sm border border-black/15 hover:bg-black/5 focus-visible:bg-black/5 dark:border-white/20 dark:hover:bg-white/5 dark:focus-visible:bg-white/5"> <svg 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" class="transition-colors duration-300 ease-in-out group-hover:animate-pulse group-hover:stroke-black group-focus-visible:animate-pulse group-focus-visible:stroke-black dark:group-hover:stroke-white dark:group-focus-visible:stroke-white"> <rect x="2" y="3" width="20" height="14" rx="2" ry="2"></rect> <line x1="8" y1="21" x2="16" y2="21"></line> <line x1="12" y1="17" x2="12" y2="21"></line> </svg> </button> </div> </div> </div> </footer> <aside data-pagefind-ignore> <div id="backdrop" class="bg-[rgba(0, 0, 0, 0.5] invisible fixed left-0 top-0 z-50 flex h-screen w-full justify-center p-6 backdrop-blur-xs" data-astro-transition-persist="astro-3snakcvo-2"> <div id="pagefind-container" class="m-0 flex h-fit max-h-[80%] w-full max-w-(--breakpoint-sm) flex-col overflow-auto rounded-sm border border-border bg-surface p-2 px-4 py-3 shadow-lg dark:border-white/20 dark:bg-neutral-900"> <div id="search" class="pagefind-ui pagefind-init" data-pagefind-ui data-bundle-path="/pagefind/" data-ui-options="{&#34;showImages&#34;:false,&#34;excerptLength&#34;:15,&#34;resetStyles&#34;:false}"></div> <script type="module" src="/_astro/Search.astro_astro_type_script_index_0_lang.DSe1Ey-Z.js"></script> <div class="mr-2 pb-1 pt-4 text-right text-xs dark:prose-invert">
Press <span class="prose text-xs dark:prose-invert"><kbd class="">Esc</kbd></span> or click anywhere to close
</div> </div> </div> </aside> <script>
  const magnifyingGlass = document.getElementById("magnifying-glass");
  const backdrop = document.getElementById("backdrop");

  function openPagefind() {
    const searchDiv = document.getElementById("search");
    const search = searchDiv.querySelector("input");
    setTimeout(() => {
      search.focus();
    }, 0);
    backdrop?.classList.remove("invisible");
    backdrop?.classList.add("visible");
  }

  function closePagefind() {
    const search = document.getElementById("search");
    search.value = "";
    backdrop?.classList.remove("visible");
    backdrop?.classList.add("invisible");
  }

  // open pagefind
  magnifyingGlass?.addEventListener("click", () => {
    openPagefind();
  });

  document.addEventListener("keydown", (e) => {
    if (e.key === "/") {
      e.preventDefault();
      openPagefind();
    } else if ((e.metaKey || e.ctrlKey) && e.key === "k") {
      e.preventDefault();
      openPagefind();
    }
  });

  // close pagefind
  document.addEventListener("keydown", (e) => {
    if (e.key === "Escape") {
      closePagefind();
    }
  });

  // close pagefind when searched result(link) clicked
  document.addEventListener("click", (event) => {
    if (event.target.classList.contains("pagefind-ui__result-link")) {
      closePagefind();
    }
  });

  backdrop?.addEventListener("click", (event) => {
    if (!event.target.closest("#pagefind-container")) {
      closePagefind();
    }
  });

  // prevent form submission
  const form = document.getElementById("form");
  form?.addEventListener("submit", (event) => {
    event.preventDefault();
  });
</script>  </body></html>