Files
Portfolioo/src/layouts/Layout.astro
T

104 lines
3.7 KiB
Plaintext

---
import '../styles/global.css';
import BackToTop from '../components/BackToTop';
import Background from '../components/Background';
import SpotlightLens from '../components/SpotlightLens';
import PortfolioAssistantFAB from '../components/PortfolioAssistantFAB';
import Analytics from '@vercel/analytics/astro';
import SEO from '../components/SEO.astro';
interface Props {
title?: string;
description?: string;
image?: string;
type?: 'website' | 'article' | 'profile';
}
const {
title = "Cris Charles Garcia | Full-Stack Developer Portfolio",
description = "Personal portfolio website of Cris Charles Garcia, showcasing projects, skills, experience, and custom AI chatbot assistant.",
image = "/logo.png",
type = "website"
} = Astro.props;
const isRootPage = Astro.url.pathname === '/';
---
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="icon" type="image/png" href="/logo.png" />
<link rel="apple-touch-icon" href="/logo.png" />
<meta name="generator" content={Astro.generator} />
<!-- SEO & Structured Data -->
<SEO title={title} description={description} image={image} type={type} />
<!-- Theme Initialization Script (Prevents FOUC) -->
<script is:inline>
(function() {
const storedTheme = localStorage.getItem('theme');
if (storedTheme === 'dark' || (!storedTheme && window.matchMedia('(prefers-color-scheme: dark)').matches)) {
document.documentElement.classList.add('dark');
} else {
document.documentElement.classList.remove('dark');
}
})();
</script>
<!-- Orientation Stamp Script (Prevents nav layout shift) -->
<script is:inline>
(function() {
function setOrientation() {
const isPortrait = window.matchMedia('(orientation: portrait)').matches;
const isNarrowLandscape = !isPortrait && window.innerWidth < 1024;
document.documentElement.dataset.orientation = isPortrait
? 'portrait'
: isNarrowLandscape
? 'landscape-compact'
: 'landscape';
}
setOrientation();
window.addEventListener('resize', setOrientation, { passive: true });
window.addEventListener('orientationchange', setOrientation, { passive: true });
})();
</script>
<!-- Performance Tier & Lite Mode Detection -->
<script is:inline>
(function() {
var manualLite = localStorage.getItem('liteMode');
var tier = 'mid';
if (manualLite === 'true') {
tier = 'low';
} else if (manualLite === 'false') {
tier = (navigator.hardwareConcurrency >= 8 && window.devicePixelRatio >= 2) ? 'high' : 'mid';
} else {
var cores = navigator.hardwareConcurrency || 2;
var conn = navigator.connection || navigator.mozConnection || navigator.webkitConnection;
var saveData = conn && conn.saveData;
var slowConn = conn && (conn.effectiveType === '2g' || conn.effectiveType === 'slow-2g' || conn.effectiveType === '3g' || (conn.downlink && conn.downlink < 1.0));
if (cores <= 4 || saveData || slowConn) {
tier = 'low';
} else if (cores >= 8 && window.devicePixelRatio >= 2) {
tier = 'high';
}
}
document.documentElement.dataset.tier = tier;
})();
</script>
</head>
<body class="bg-background-custom text-foreground-custom bg-gradient-mesh min-h-screen flex flex-col selection:bg-primary-custom/30">
<Background client:load />
<div id="magnify-content">
<div class="hidden glass-card glass-nav text-glow glow-effect reveal-fade-up reveal-fade-down reveal-fade-left reveal-fade-right reveal-scale-up"></div>
<slot />
</div>
<BackToTop client:idle />
<PortfolioAssistantFAB client:idle />
<SpotlightLens client:load />
<Analytics />
</body>
</html>