---
import '../styles/global.css';
interface Props {
title?: string;
description?: string;
pageClass?: string;
}
const {
title = 'dotstate — a calmer home for the files that configure everything',
description = 'dotstate is a dotfile manager for people who\'d rather stop thinking about dotfiles. Keeps your shell, editor, and terminal configs synced across every machine — through profiles, inheritance, and one command to sync.',
pageClass = '',
} = Astro.props;
---
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{title}</title>
<meta name="title" content={title}>
<meta name="description" content={description}>
<meta name="keywords" content="dotfile manager, dotfiles, rust, dotfile sync, github dotfiles, configuration management, dotfile backup, symlink manager, terminal ui, tui, rust cli, dotfile tool, config sync, profile management, dotfile organizer">
<meta name="author" content="Serkan Yersen">
<meta name="robots" content="index, follow">
<meta name="language" content="English">
<link rel="canonical" href="https://dotstate.serkan.dev">
<meta property="og:type" content="website">
<meta property="og:url" content="https://dotstate.serkan.dev">
<meta property="og:title" content={title}>
<meta property="og:description" content={description}>
<meta property="og:image" content="https://dotstate.serkan.dev/og-image.png">
<meta property="og:site_name" content="dotstate">
<meta property="twitter:card" content="summary_large_image">
<meta property="twitter:url" content="https://dotstate.serkan.dev">
<meta property="twitter:title" content={title}>
<meta property="twitter:description" content={description}>
<meta property="twitter:image" content="https://dotstate.serkan.dev/og-image.png">
<meta property="twitter:creator" content="@serkanyersen">
<meta name="theme-color" content="#3e5b3c">
<link rel="icon" type="image/svg+xml" href="data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'><circle cx='50' cy='50' r='40' fill='%233e5b3c'/></svg>">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Fraunces:opsz,wght@9..144,300;9..144,400;9..144,500&family=Inter+Tight:wght@300;400;500;600&family=JetBrains+Mono:wght@400;500&display=swap" rel="stylesheet">
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "SoftwareApplication",
"name": "dotstate",
"applicationCategory": "DeveloperApplication",
"operatingSystem": "Linux, macOS, Windows",
"offers": { "@type": "Offer", "price": "0", "priceCurrency": "USD" },
"description": "A modern, secure dotfile manager built with Rust.",
"url": "https://dotstate.serkan.dev",
"downloadUrl": "https://crates.io/crates/dotstate",
"programmingLanguage": "Rust",
"license": "https://opensource.org/licenses/MIT",
"author": { "@type": "Person", "name": "Serkan Yersen" }
}
</script>
</head>
<body class={pageClass}>
<slot />
<script>
(function () {
function init() {
const els = Array.from(document.querySelectorAll<HTMLElement>('.reveal'));
if (!els.length) return;
const reduce = window.matchMedia && window.matchMedia('(prefers-reduced-motion: reduce)').matches;
if (reduce) return;
els.forEach((el) => el.classList.add('pre'));
if (!('IntersectionObserver' in window)) {
els.forEach((el) => el.classList.add('on'));
return;
}
requestAnimationFrame(() => { requestAnimationFrame(() => {
const io = new IntersectionObserver((entries) => {
entries.forEach((entry) => {
if (entry.isIntersecting) {
entry.target.classList.add('on');
io.unobserve(entry.target);
}
});
}, { threshold: 0.05, rootMargin: '0px 0px -20px 0px' });
els.forEach((el) => io.observe(el));
}); });
setTimeout(() => els.forEach((el) => el.classList.add('on')), 2000);
}
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', init);
} else {
init();
}
})();
</script>
<script>
import { inject } from '@vercel/analytics';
import { injectSpeedInsights } from '@vercel/speed-insights';
inject();
injectSpeedInsights();
</script>
</body>
</html>