111 lines
3.5 KiB
Text
111 lines
3.5 KiB
Text
---
|
|
import { Font } from 'astro:assets';
|
|
import { ClientRouter } from 'astro:transitions';
|
|
|
|
import BaseHead from '@/components/BaseHead.astro';
|
|
import Banner from '@/components/layout/banner';
|
|
import Footer from '@/components/layout/footer';
|
|
import Navbar from '@/components/layout/navbar';
|
|
|
|
const { title, description } = Astro.props;
|
|
const currentPath = Astro.url.pathname;
|
|
---
|
|
|
|
<html lang="en">
|
|
<head>
|
|
<ClientRouter />
|
|
<BaseHead title={title} description={description} />
|
|
<Font cssVariable="--font-imprima" preload />
|
|
<Font cssVariable="--font-rubik" preload />
|
|
<Font cssVariable="--font-eb-garamond" preload />
|
|
<meta name="view-transition" content="same-origin" />
|
|
</head>
|
|
<body class="h-screen antialiased flex flex-col">
|
|
<div
|
|
id="route-preloader"
|
|
class="pointer-events-none fixed inset-0 z-[1000] place-items-center bg-background/75 backdrop-blur-sm"
|
|
style="display: none; opacity: 0; transition: opacity 160ms ease;"
|
|
role="status"
|
|
aria-hidden="true"
|
|
aria-live="polite"
|
|
>
|
|
<div class="flex items-center gap-3 rounded-lg border bg-background px-4 py-3 shadow-lg">
|
|
<img
|
|
src="/images/publications-preloader.gif"
|
|
alt=""
|
|
width="48"
|
|
height="48"
|
|
class="size-8"
|
|
decoding="async"
|
|
/>
|
|
<span class="text-sm text-muted-foreground">Loading page...</span>
|
|
</div>
|
|
</div>
|
|
<Banner client:only="react" />
|
|
<Navbar currentPage={currentPath} client:only="react" />
|
|
<main class="flex-1" style="view-transition-name: main;">
|
|
<slot />
|
|
</main>
|
|
<Footer client:only="react" />
|
|
<script is:inline>
|
|
(() => {
|
|
if (window.__routePreloaderInitialized) return;
|
|
|
|
window.__routePreloaderInitialized = true;
|
|
|
|
const reducedMotionQuery = window.matchMedia(
|
|
"(prefers-reduced-motion: reduce)",
|
|
);
|
|
let showTimer;
|
|
let hideTimer;
|
|
let fallbackTimer;
|
|
|
|
const getRoutePreloader = () =>
|
|
document.getElementById("route-preloader");
|
|
|
|
const show = () => {
|
|
const routePreloader = getRoutePreloader();
|
|
|
|
if (!routePreloader) return;
|
|
|
|
window.clearTimeout(hideTimer);
|
|
routePreloader.style.display = "grid";
|
|
routePreloader.setAttribute("aria-hidden", "false");
|
|
requestAnimationFrame(() => {
|
|
routePreloader.style.opacity = "1";
|
|
});
|
|
};
|
|
|
|
const hide = () => {
|
|
const routePreloader = getRoutePreloader();
|
|
|
|
window.clearTimeout(showTimer);
|
|
window.clearTimeout(fallbackTimer);
|
|
if (!routePreloader) return;
|
|
|
|
routePreloader.style.opacity = "0";
|
|
routePreloader.setAttribute("aria-hidden", "true");
|
|
hideTimer = window.setTimeout(
|
|
() => {
|
|
getRoutePreloader()?.style.setProperty("display", "none");
|
|
},
|
|
reducedMotionQuery.matches ? 0 : 160,
|
|
);
|
|
};
|
|
|
|
const queue = () => {
|
|
window.clearTimeout(showTimer);
|
|
window.clearTimeout(fallbackTimer);
|
|
showTimer = window.setTimeout(show, 450);
|
|
fallbackTimer = window.setTimeout(hide, 8000);
|
|
};
|
|
|
|
document.addEventListener("astro:before-preparation", queue);
|
|
document.addEventListener("astro:after-swap", hide);
|
|
document.addEventListener("astro:page-load", hide);
|
|
window.addEventListener("load", hide);
|
|
window.addEventListener("pageshow", hide);
|
|
})();
|
|
</script>
|
|
</body>
|
|
</html>
|