103 lines
3.5 KiB
Plaintext
103 lines
3.5 KiB
Plaintext
---
|
|
import "@/style/globals.css";
|
|
|
|
import { ClientRouter } from "astro:transitions";
|
|
|
|
import Header from "@/components/header";
|
|
import Footer from "@/components/footer";
|
|
import Background from "@/components/background";
|
|
import ThemeSwitcher from "@/components/theme-switcher";
|
|
import AnimationSwitcher from "@/components/animation-switcher";
|
|
import VercelAnalytics from "@/components/analytics";
|
|
import MobileNav from "@/components/mobile-nav";
|
|
import { THEME_LOADER_SCRIPT, THEME_NAV_SCRIPT } from "@/lib/themes/loader";
|
|
import { ANIMATION_LOADER_SCRIPT, ANIMATION_NAV_SCRIPT } from "@/lib/animations/loader";
|
|
|
|
export interface Props {
|
|
title: string;
|
|
description: string;
|
|
}
|
|
|
|
const { title, description } = Astro.props;
|
|
const ogImage = "https://timmypidashev.dev/og-image.jpg";
|
|
---
|
|
|
|
<html lang="en">
|
|
<head>
|
|
<title>{title}</title>
|
|
<meta charset="utf-8" />
|
|
<meta name="viewport" content="width=device-width" />
|
|
<meta property="og:image" content={ogImage} />
|
|
<meta property="og:image:width" content="1200" />
|
|
<meta property="og:image:height" content="630" />
|
|
<meta name="twitter:card" content="summary_large_image" />
|
|
<meta name="twitter:image" content={ogImage} />
|
|
<meta name="twitter:description" content={description} />
|
|
<meta name="description" content={description} />
|
|
<meta property="og:description" content={description} />
|
|
<link rel="icon" type="image/jpeg" href="/me.jpeg" />
|
|
<link rel="sitemap" href="/sitemap-index.xml" />
|
|
<ClientRouter />
|
|
<style>
|
|
::view-transition-new(:root),
|
|
::view-transition-old(:root) {
|
|
animation: none;
|
|
}
|
|
#nav-mask {
|
|
position: fixed;
|
|
inset: 0;
|
|
z-index: 9999;
|
|
background: rgb(var(--color-background));
|
|
pointer-events: none;
|
|
opacity: 0;
|
|
transition: none;
|
|
}
|
|
#nav-mask.active {
|
|
opacity: 1;
|
|
}
|
|
</style>
|
|
<script is:inline set:html={THEME_LOADER_SCRIPT} />
|
|
<script is:inline set:html={ANIMATION_LOADER_SCRIPT} />
|
|
<script is:inline>
|
|
(function() {
|
|
function getMask() {
|
|
var m = document.getElementById('nav-mask');
|
|
if (!m) {
|
|
m = document.createElement('div');
|
|
m.id = 'nav-mask';
|
|
document.documentElement.appendChild(m);
|
|
}
|
|
return m;
|
|
}
|
|
document.addEventListener('astro:before-preparation', function() {
|
|
getMask().classList.add('active');
|
|
});
|
|
document.addEventListener('astro:after-swap', function() {
|
|
var m = getMask();
|
|
// Wait longer for canvas + overlays to hydrate on index page
|
|
setTimeout(function() { m.classList.remove('active'); }, 150);
|
|
});
|
|
// Mark SPA navigations so AnimateIn can detect them
|
|
document.addEventListener('astro:after-swap', function() {
|
|
window.__astroNavigation = true;
|
|
});
|
|
})();
|
|
</script>
|
|
</head>
|
|
<body class="bg-background text-foreground overflow-hidden h-screen">
|
|
<div id="nav-mask"></div>
|
|
<Header client:load transparent />
|
|
<main>
|
|
<Background layout="index" client:only="react" transition:persist />
|
|
<slot />
|
|
</main>
|
|
<Footer client:load transition:persist fixed=true />
|
|
<ThemeSwitcher client:only="react" transition:persist />
|
|
<AnimationSwitcher client:only="react" transition:persist />
|
|
<VercelAnalytics client:load />
|
|
<MobileNav client:load transparent />
|
|
<script is:inline set:html={THEME_NAV_SCRIPT} />
|
|
<script is:inline set:html={ANIMATION_NAV_SCRIPT} />
|
|
</body>
|
|
</html>
|