98 lines
3.1 KiB
Plaintext
98 lines
3.1 KiB
Plaintext
---
|
|
import '../styles/global.css';
|
|
import { defaultLang, languages } from '../i18n/ui';
|
|
|
|
// Get current language from URL
|
|
const { pathname } = Astro.url;
|
|
// Extract the first path segment
|
|
const pathSegments = pathname.split('/').filter(Boolean);
|
|
const langCode = pathSegments[0];
|
|
// Check if the first segment is a valid language code
|
|
const currentLang = langCode && Object.keys(languages).includes(langCode)
|
|
? langCode
|
|
: defaultLang;
|
|
|
|
// Init AOS animation library on client-side
|
|
---
|
|
<!DOCTYPE html>
|
|
<html lang={currentLang} class="dark scroll-smooth">
|
|
<head>
|
|
<meta charset="UTF-8" />
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
<meta name="description" content="JPM Security & Services: Professional, Discreet, Dependable. Security, Concierge, and Food Services tailored to your needs." />
|
|
|
|
<!-- Favicon -->
|
|
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
|
|
<link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png">
|
|
|
|
<!-- Preloads -->
|
|
<link rel="preload" href="/fonts/Inter.woff2" as="font" type="font/woff2" crossorigin />
|
|
<link rel="preconnect" href="https://fonts.googleapis.com">
|
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
|
|
|
<!-- AOS animations -->
|
|
<link href="https://unpkg.com/aos@next/dist/aos.css" rel="stylesheet">
|
|
|
|
<title>JPM Security & Services | Professional, Discreet, Dependable</title>
|
|
|
|
<!-- Prevent infinite redirects -->
|
|
<script is:inline>
|
|
// Reset redirect count once the page is fully loaded
|
|
document.addEventListener('DOMContentLoaded', () => {
|
|
if (typeof sessionStorage !== 'undefined') {
|
|
sessionStorage.setItem('redirectCount', '0');
|
|
}
|
|
});
|
|
</script>
|
|
<style is:global>
|
|
/* Ensure section ids have proper spacing for anchor navigation */
|
|
section[id] {
|
|
scroll-margin-top: 2rem;
|
|
}
|
|
|
|
/* Ensure proper z-index layering */
|
|
.relative {
|
|
position: relative;
|
|
}
|
|
|
|
/* Fix for AOS animations that might create layers blocking interaction */
|
|
[data-aos] {
|
|
pointer-events: none;
|
|
}
|
|
|
|
[data-aos] * {
|
|
pointer-events: auto;
|
|
}
|
|
|
|
/* Ensure links are always clickable */
|
|
a, button {
|
|
position: relative;
|
|
z-index: 5;
|
|
}
|
|
</style>
|
|
</head>
|
|
<body class="min-h-screen bg-black-deep text-silver-light font-sans antialiased selection:bg-accent-blue selection:text-silver-light">
|
|
<slot />
|
|
|
|
<!-- Initialize AOS -->
|
|
<script is:inline src="https://unpkg.com/aos@next/dist/aos.js"></script>
|
|
<script is:inline>
|
|
document.addEventListener('DOMContentLoaded', () => {
|
|
AOS.init({
|
|
duration: 800,
|
|
easing: 'ease-out-cubic',
|
|
once: true,
|
|
offset: 50,
|
|
disableMutationObserver: false
|
|
});
|
|
|
|
// Ensure AOS doesn't block interactions
|
|
document.querySelectorAll('[data-aos]').forEach(el => {
|
|
el.addEventListener('animationend', () => {
|
|
el.style.pointerEvents = 'auto';
|
|
});
|
|
});
|
|
});
|
|
</script>
|
|
</body>
|
|
</html> |