112 lines
4.2 KiB
Plaintext
112 lines
4.2 KiB
Plaintext
---
|
|
import '../styles/global.css';
|
|
import Header from '../components/Header.astro';
|
|
import Footer from '../components/Footer.astro';
|
|
|
|
interface Props {
|
|
title: string;
|
|
description?: string;
|
|
}
|
|
|
|
const { title, description = "LaForce IT - Home Lab & DevOps Insights" } = 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="description" content={description}>
|
|
<link rel="icon" type="image/svg+xml" href="/favicon.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=JetBrains+Mono:wght@400;500;700&family=Space+Grotesk:wght@300;400;500;600;700&display=swap" rel="stylesheet">
|
|
|
|
<!-- Open Graph / Social Media Meta Tags -->
|
|
<meta property="og:title" content={title} />
|
|
<meta property="og:description" content={description} />
|
|
<meta property="og:type" content="website" />
|
|
<meta property="og:url" content={Astro.url} />
|
|
<meta property="og:image" content="/blog/images/placeholders/default.jpg" />
|
|
|
|
<!-- Twitter Meta Tags -->
|
|
<meta name="twitter:card" content="summary_large_image" />
|
|
<meta property="twitter:domain" content="laforceit.blog" />
|
|
<meta property="twitter:url" content={Astro.url} />
|
|
<meta name="twitter:title" content={title} />
|
|
<meta name="twitter:description" content={description} />
|
|
<meta name="twitter:image" content="/blog/images/placeholders/default.jpg" />
|
|
</head>
|
|
<body>
|
|
<!-- Neural network nodes - Added via JavaScript -->
|
|
<div id="neural-network"></div>
|
|
|
|
<!-- Floating shapes for background effect -->
|
|
<div class="floating-shapes">
|
|
<div class="floating-shape shape-1"></div>
|
|
<div class="floating-shape shape-2"></div>
|
|
<div class="floating-shape shape-3"></div>
|
|
</div>
|
|
|
|
<Header />
|
|
|
|
<slot />
|
|
|
|
<Footer />
|
|
|
|
<script>
|
|
// Create neural network nodes
|
|
document.addEventListener('DOMContentLoaded', () => {
|
|
const neuralNetwork = document.getElementById('neural-network');
|
|
if (!neuralNetwork) return;
|
|
|
|
const nodeCount = Math.min(window.innerWidth / 20, 70); // Responsive node count
|
|
|
|
for (let i = 0; i < nodeCount; i++) {
|
|
const node = document.createElement('div');
|
|
node.classList.add('neural-node');
|
|
|
|
// Random position
|
|
node.style.left = `${Math.random() * 100}%`;
|
|
node.style.top = `${Math.random() * 100}%`;
|
|
|
|
// Random animation delay
|
|
node.style.animationDelay = `${Math.random() * 4}s`;
|
|
|
|
neuralNetwork.appendChild(node);
|
|
}
|
|
});
|
|
|
|
// Terminal typing effect
|
|
document.addEventListener('DOMContentLoaded', () => {
|
|
const terminalTyping = document.querySelector('.terminal-typing');
|
|
if (!terminalTyping) return;
|
|
|
|
const typingCommands = [
|
|
'cloudflared tunnel status',
|
|
'kubectl get pods -A',
|
|
'helm list -n monitoring',
|
|
'flux reconcile kustomization --all'
|
|
];
|
|
|
|
let currentCommandIndex = 0;
|
|
|
|
function typeCommand(command: string, element: Element, index = 0) {
|
|
if (index < command.length) {
|
|
element.textContent = command.substring(0, index + 1);
|
|
setTimeout(() => typeCommand(command, element, index + 1), 100);
|
|
} else {
|
|
// Move to next command after delay
|
|
setTimeout(() => {
|
|
currentCommandIndex = (currentCommandIndex + 1) % typingCommands.length;
|
|
typeCommand(typingCommands[currentCommandIndex], element, 0);
|
|
}, 3000);
|
|
}
|
|
}
|
|
|
|
typeCommand(typingCommands[currentCommandIndex], terminalTyping);
|
|
});
|
|
</script>
|
|
</body>
|
|
</html> |