Compare commits

...

2 Commits

6 changed files with 3344 additions and 1247 deletions

View File

@ -1,10 +1,6 @@
<!DOCTYPE html>
<html lang="en">
<head>
<script>
console.log("DEBUG: ansible-docs.html is being loaded");
// You can check this in your browser's developer console
</script>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Ansible Sandbox Documentation | Argobox</title>
@ -44,7 +40,6 @@
--card-hover-bg: rgba(30, 41, 59, 0.95);
--card-shadow: 0 10px 25px -5px rgba(0, 0, 0, 0.3);
--transition-normal: 0.3s ease;
--glass-effect: blur(10px);
}
* {
@ -63,255 +58,346 @@
radial-gradient(circle at 75% 60%, rgba(14, 165, 233, 0.1) 0%, transparent 50%);
}
.navbar {
background-color: rgba(15, 23, 42, 0.9);
backdrop-filter: var(--glass-effect);
-webkit-backdrop-filter: var(--glass-effect);
.docs-container {
display: flex;
min-height: 100vh;
}
.sidebar {
width: 280px;
background-color: var(--sidebar-bg);
border-right: 1px solid var(--border);
position: fixed;
top: 0;
left: 0;
right: 0;
z-index: 1000;
padding: 1.25rem 0;
height: 100vh;
overflow-y: auto;
scrollbar-width: thin;
scrollbar-color: var(--border) transparent;
padding: 2rem 0;
z-index: 10;
}
.sidebar::-webkit-scrollbar {
width: 6px;
}
.sidebar::-webkit-scrollbar-track {
background: transparent;
}
.sidebar::-webkit-scrollbar-thumb {
background-color: var(--border);
border-radius: 3px;
}
.sidebar-header {
padding: 0 1.5rem;
margin-bottom: 2rem;
}
.sidebar-title {
font-size: 1.25rem;
font-weight: 600;
margin-bottom: 0.5rem;
}
.back-link {
display: flex;
align-items: center;
gap: 0.5rem;
color: var(--accent);
font-weight: 500;
font-size: 0.9rem;
padding: 0.5rem 0;
transition: all var(--transition-normal);
}
.back-link:hover {
color: var(--accent-darker);
transform: translateX(-3px);
}
.sidebar-section {
margin-bottom: 1.5rem;
}
.sidebar-section-title {
font-weight: 600;
font-size: 0.85rem;
text-transform: uppercase;
color: var(--text-secondary);
letter-spacing: 0.05em;
padding: 0 1.5rem;
margin-bottom: 0.75rem;
}
.sidebar-nav {
list-style: none;
}
.sidebar-nav-item {
transition: all var(--transition-normal);
}
.sidebar-nav-link {
display: block;
padding: 0.5rem 1.5rem;
color: var(--text-secondary);
text-decoration: none;
transition: all var(--transition-normal);
position: relative;
font-size: 0.95rem;
}
.sidebar-nav-link:hover {
color: var(--text-primary);
background-color: rgba(255, 255, 255, 0.05);
}
.sidebar-nav-link.active {
color: var(--accent);
background-color: rgba(59, 130, 246, 0.1);
}
.sidebar-nav-link.active::before {
content: '';
position: absolute;
top: 0;
left: 0;
height: 100%;
width: 3px;
background: var(--accent-gradient);
}
.main-content {
flex: 1;
margin-left: 280px;
padding: 3rem;
max-width: 1000px;
}
.docs-header {
margin-bottom: 3rem;
}
.docs-title {
font-size: 2.5rem;
font-weight: 700;
margin-bottom: 1rem;
}
.docs-subtitle {
color: var(--text-secondary);
font-size: 1.2rem;
}
.docs-section {
margin-bottom: 3rem;
scroll-margin-top: 2rem;
}
.docs-section-title {
font-size: 1.75rem;
font-weight: 600;
margin-bottom: 1.5rem;
color: var(--text-primary);
position: relative;
padding-bottom: 0.75rem;
border-bottom: 1px solid var(--border);
}
.navbar .container {
display: flex;
justify-content: space-between;
align-items: center;
max-width: 1400px;
margin: 0 auto;
padding: 0 1.5rem;
.docs-subsection {
margin-bottom: 2rem;
}
.logo a {
color: var(--text-primary);
text-decoration: none;
display: flex;
align-items: center;
gap: 0.25rem;
}
.logo-text {
background: var(--accent-gradient);
-webkit-background-clip: text;
background-clip: text;
color: transparent;
font-size: 1.5rem;
.docs-subsection-title {
font-size: 1.25rem;
font-weight: 600;
}
.logo-dot {
color: var(--text-secondary);
font-size: 1.5rem;
font-weight: 600;
}
.nav-menu {
display: flex;
gap: 2.5rem;
}
.nav-link {
color: var(--text-secondary);
text-decoration: none;
font-size: 0.95rem;
font-weight: 500;
transition: all var(--transition-normal);
position: relative;
}
.nav-link.active,
.nav-link:hover {
margin-bottom: 1rem;
color: var(--accent);
}
.nav-buttons {
display: flex;
align-items: center;
gap: 1.25rem;
.docs-text {
color: var(--text-secondary);
margin-bottom: 1.5rem;
}
.dashboard-link {
display: flex;
align-items: center;
gap: 0.75rem;
padding: 0.625rem 1.25rem;
font-size: 0.95rem;
font-weight: 500;
color: var(--text-primary);
background-color: rgba(59, 130, 246, 0.1);
border: 1px solid rgba(59, 130, 246, 0.2);
.docs-list {
list-style-type: disc;
margin-left: 1.5rem;
margin-bottom: 1.5rem;
color: var(--text-secondary);
}
.docs-list li {
margin-bottom: 0.5rem;
}
.docs-code {
font-family: 'JetBrains Mono', monospace;
background-color: var(--sidebar-bg);
padding: 1.5rem;
border-radius: 0.5rem;
overflow-x: auto;
margin-bottom: 1.5rem;
border: 1px solid var(--border);
font-size: 0.9rem;
line-height: 1.5;
}
.docs-code pre {
margin: 0;
}
.docs-table {
width: 100%;
border-collapse: collapse;
margin-bottom: 1.5rem;
}
.docs-table th {
text-align: left;
padding: 0.75rem 1rem;
background-color: var(--sidebar-bg);
color: var(--text-primary);
font-weight: 600;
border-bottom: 2px solid var(--border);
}
.docs-table td {
padding: 0.75rem 1rem;
border-bottom: 1px solid var(--border);
color: var(--text-secondary);
}
.docs-note {
background-color: rgba(59, 130, 246, 0.1);
border-left: 4px solid var(--accent);
padding: 1rem 1.5rem;
border-radius: 0 0.5rem 0.5rem 0;
margin-bottom: 1.5rem;
}
.docs-note-title {
font-weight: 600;
color: var(--accent);
display: flex;
align-items: center;
gap: 0.5rem;
margin-bottom: 0.5rem;
}
.docs-warning {
background-color: rgba(245, 158, 11, 0.1);
border-left: 4px solid var(--warning);
padding: 1rem 1.5rem;
border-radius: 0 0.5rem 0.5rem 0;
margin-bottom: 1.5rem;
}
.docs-warning-title {
font-weight: 600;
color: var(--warning);
display: flex;
align-items: center;
gap: 0.5rem;
margin-bottom: 0.5rem;
}
.docs-button {
display: inline-flex;
align-items: center;
gap: 0.5rem;
background-color: var(--accent);
color: white;
padding: 0.75rem 1.25rem;
border-radius: 0.5rem;
font-weight: 500;
text-decoration: none;
transition: all var(--transition-normal);
margin-bottom: 1.5rem;
}
.dashboard-link:hover {
.docs-button:hover {
background-color: var(--accent-darker);
transform: translateY(-2px);
box-shadow: var(--card-shadow);
}
.navbar .menu-toggle {
background: none;
border: none;
color: var(--text-primary);
font-size: 1.5rem;
cursor: pointer;
}
.navbar .menu-toggle i {
transition: transform var(--transition-normal);
}
.navbar .nav-menu.show {
display: block;
}
.footer {
background-color: var(--secondary-bg);
padding: 2rem;
color: var(--text-secondary);
.docs-footer {
border-top: 1px solid var(--border);
}
.footer .container {
display: flex;
flex-direction: column;
align-items: center;
gap: 1rem;
}
.footer .footer-content {
display: flex;
justify-content: space-between;
align-items: center;
width: 100%;
}
.footer .footer-logo {
display: flex;
align-items: center;
}
.footer .footer-logo .logo-text {
font-size: 1.5rem;
font-weight: 700;
color: var(--accent);
}
.footer .footer-logo .logo-dot {
font-size: 1.5rem;
font-weight: 700;
color: var(--text-primary);
}
.footer .footer-links {
display: flex;
gap: 1rem;
}
.footer .footer-links a {
margin-top: 3rem;
padding-top: 2rem;
color: var(--text-secondary);
text-decoration: none;
font-size: 0.9rem;
transition: color var(--transition-normal);
}
.footer .footer-links a:hover {
color: var(--accent);
}
.footer .footer-social {
display: flex;
gap: 1rem;
}
.footer .footer-social a {
color: var(--text-secondary);
font-size: 1.2rem;
transition: color var(--transition-normal);
}
.footer .footer-social a:hover {
color: var(--accent);
}
.footer .footer-bottom {
text-align: center;
font-size: 0.9rem;
.mobile-menu-toggle {
display: none;
position: fixed;
bottom: 1.5rem;
right: 1.5rem;
background: var(--accent-gradient);
color: white;
width: 50px;
height: 50px;
border-radius: 50%;
border: none;
cursor: pointer;
display: none;
position: fixed;
bottom: 1.5rem;
right: 1.5rem;
background: var(--accent-gradient);
color: white;
width: 50px;
height: 50px;
border-radius: 50%;
border: none;
cursor: pointer;
font-size: 1.5rem;
align-items: center;
justify-content: center;
z-index: 20;
box-shadow: var(--card-shadow);
}
@media (max-width: 992px) {
.navbar .nav-menu {
display: none;
flex-direction: column;
gap: 0.5rem;
background-color: var(--secondary-bg);
position: absolute;
top: 100%;
right: 0;
width: 200px;
padding: 1rem;
border: 1px solid var(--border);
border-radius: 0.5rem;
.sidebar {
transform: translateX(-100%);
transition: transform var(--transition-normal);
}
.navbar .nav-menu.show {
.sidebar.active {
transform: translateX(0);
}
.main-content {
margin-left: 0;
padding: 2rem 1.5rem;
}
.mobile-menu-toggle {
display: flex;
}
}
.contact-info {
margin-top: 2rem;
}
.contact-info p {
margin-bottom: 0.5rem;
}
.contact-email {
color: #60a5fa; /* Lighter blue color for better readability */
font-weight: 600;
}
</style>
</head>
<body>
<!-- Navigation Bar -->
<nav class="navbar">
<div class="container">
<div class="logo">
<a href="#home">
<span class="logo-text-glow">ArgoBox</span><span class="logo-dot-glow">.com</span>
</a>
</div>
<div class="nav-menu">
<a href="#home" class="nav-link active">Home</a>
<a href="#services" class="nav-link">Services</a>
<a href="#lab" class="nav-link">Live Lab</a>
<a href="#projects" class="nav-link">Projects</a>
<a href="#experience" class="nav-link">Experience</a>
<a href="#contact" class="nav-link">Contact</a>
</div>
<div class="nav-buttons">
<a href="https://dashboard.argobox.com" class="dashboard-link" target="_blank">
<span class="live-indicator"></span>
<span>Live Dashboard</span>
</a>
<button class="menu-toggle" aria-label="Toggle menu">
<i class="fas fa-bars"></i>
</button>
</div>
</div>
</nav>
<!-- Top Links -->
<div class="top-links">
<a href="https://laforceit.com" class="laforceit-link">
<span class="logo-text-glow">LaForceIT</span><span class="logo-dot-glow">.com</span>
</a>
<a href="https://login.argobox.com" class="signin-button" target="_blank">
<i class="fas fa-sign-in-alt"></i>
<span>Sign In</span>
</a>
</div>
<!-- Under Construction Warning -->
<div class="construction-warning">
<div class="warning-content">
<i class="fas fa-hard-hat"></i>
<h2>Under Construction</h2>
<p>This page is currently being developed. Some features may not be fully functional.</p>
</div>
</div>
<div class="docs-container">
<aside class="sidebar">
<div class="sidebar-header">
@ -764,30 +850,49 @@ web-server/
</ul>
</div>
</section>
</main>
</div>
<!-- Footer -->
<footer class="footer">
<div class="container">
<div class="footer-content">
<div class="footer-info">
<div class="footer-logo">
<span class="logo-text">Argobox</span>
<span class="logo-dot">.com</span>
<span class="logo-text-glow">ArgoBox</span>
<span class="logo-dot-glow">.com</span>
</div>
<p class="footer-description">
Enterprise-grade home lab environment for DevOps experimentation, infrastructure automation, and containerized application deployment.
</p>
<div class="footer-evolution">
<i class="fas fa-code-branch evolution-icon"></i>
<span>Continuously evolving since 2011</span>
</div>
</div>
<div class="footer-links">
<a href="index.html#home">Home</a>
<a href="index.html#services">Services</a>
<a href="index.html#lab">Live Lab</a>
<a href="index.html#projects">Projects</a>
<a href="index.html#contact">Contact</a>
<div class="footer-links-column">
<h3 class="footer-heading">Platforms</h3>
<a href="https://dashboard.argobox.com" class="footer-link">Dashboard</a>
<a href="ansible-sandbox.html" class="footer-link">Ansible Sandbox</a>
<a href="https://git.argobox.com" class="footer-link">Gitea</a>
<a href="https://ai.argobox.com" class="footer-link">OpenWebUI</a>
</div>
<div class="footer-social">
<a href="https://github.com/keyargo" target="_blank" aria-label="GitHub"><i class="fab fa-github"></i></a>
<a href="https://www.linkedin.com/in/danlaforce" target="_blank" aria-label="LinkedIn"><i class="fab fa-linkedin"></i></a>
<a href="mailto:daniel.laforce@argobox.com" aria-label="Email"><i class="fas fa-envelope"></i></a>
<div class="footer-links-column">
<h3 class="footer-heading">Documentation</h3>
<a href="construction.html" class="footer-link">Architecture</a>
<a href="construction.html" class="footer-link">Kubernetes</a>
<a href="construction.html" class="footer-link">Ansible</a>
<a href="construction.html" class="footer-link">Network</a>
</div>
<div class="footer-links-column">
<h3 class="footer-heading">Resources</h3>
<a href="construction.html" class="footer-link">Ansible Playbooks</a>
<a href="construction.html" class="footer-link">K8s Manifests</a>
<a href="construction.html" class="footer-link">Shell Scripts</a>
<a href="construction.html" class="footer-link">Configuration Files</a>
</div>
</div>
</div>
@ -796,6 +901,8 @@ web-server/
</div>
</div>
</footer>
</main>
</div>
<button class="mobile-menu-toggle">
<i class="fas fa-bars"></i>
@ -882,23 +989,6 @@ web-server/
}
});
});
// Add mobile menu toggle functionality
const menuToggleNav = document.querySelector('.menu-toggle');
const navMenu = document.querySelector('.nav-menu');
menuToggleNav.addEventListener('click', function() {
navMenu.classList.toggle('show');
const icon = menuToggleNav.querySelector('i');
if (navMenu.classList.contains('show')) {
icon.classList.remove('fa-bars');
icon.classList.add('fa-times');
} else {
icon.classList.remove('fa-times');
icon.classList.add('fa-bars');
}
});
});
</script>
</body>

View File

@ -392,6 +392,81 @@
text-align: center;
font-size: 0.9rem;
}
.live-indicator {
width: 8px;
height: 8px;
background-color: var(--success);
border-radius: 50%;
position: relative;
}
.live-indicator.offline {
background-color: var(--error);
}
.live-indicator::after {
content: '';
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
border-radius: 50%;
background-color: var(--success);
animation: pulse 2s infinite;
z-index: -1;
}
.live-indicator.offline::after {
background-color: var(--error);
}
.logo-text-glow, .logo-dot-glow {
transition: all var(--transition-normal);
}
.logo-text-glow {
text-shadow: 0 0 10px rgba(59, 130, 246, 0.5);
color: var(--accent);
}
.logo-dot-glow {
color: var(--text-primary);
}
.top-links {
position: fixed;
top: 0;
right: 0;
padding: 0.75rem 1.5rem;
display: flex;
gap: 1.5rem;
align-items: center;
z-index: 1001;
}
.laforceit-link {
font-size: 0.9rem;
font-weight: 600;
}
.signin-button {
display: flex;
align-items: center;
gap: 0.5rem;
padding: 0.25rem 0.75rem;
background: rgba(30, 41, 59, 0.8);
border: 1px solid var(--border);
border-radius: 4px;
font-size: 0.85rem;
transition: all var(--transition-normal);
}
.signin-button:hover {
background: rgba(30, 41, 59, 1);
border-color: var(--accent);
}
</style>
</head>
<body>
@ -400,21 +475,20 @@
<div class="container">
<div class="logo">
<a href="index.html">
<span class="logo-text">Argobox</span>
<span class="logo-dot">.com</span>
<span class="logo-text-glow">ArgoBox</span><span class="logo-dot-glow">.com</span>
</a>
</div>
<div class="nav-menu">
<a href="index.html#home" class="nav-link">Home</a>
<a href="index.html#technologies" class="nav-link">Technologies</a>
<a href="index.html#services" class="nav-link">Services</a>
<a href="index.html#lab" class="nav-link active">Live Lab</a>
<a href="index.html#projects" class="nav-link">Projects</a>
<a href="index.html#experience" class="nav-link">Experience</a>
<a href="index.html#dashboards" class="nav-link">Dashboards</a>
<a href="index.html#contact" class="nav-link">Contact</a>
</div>
<div class="nav-buttons">
<a href="dashboard.html" class="dashboard-link" target="_blank">
<span class="live-indicator"></span>
<a href="https://dashboard.argobox.com" class="dashboard-link" target="_blank">
<span class="live-indicator offline"></span>
<span>Live Dashboard</span>
</a>
<button class="menu-toggle" aria-label="Toggle menu">
@ -424,6 +498,17 @@
</div>
</nav>
<!-- Top Links -->
<div class="top-links">
<a href="https://laforceit.com" class="laforceit-link">
<span class="logo-text-glow">LaForceIT</span><span class="logo-dot-glow">.com</span>
</a>
<a href="construction.html" class="signin-button" target="_blank">
<i class="fas fa-sign-in-alt"></i>
<span>Sign In</span>
</a>
</div>
<div class="container">
<div class="help-header">
<a href="ansible-sandbox.html" class="back-link">
@ -603,23 +688,44 @@
<footer class="footer">
<div class="container">
<div class="footer-content">
<div class="footer-info">
<div class="footer-logo">
<span class="logo-text">Argobox</span>
<span class="logo-dot">.com</span>
<span class="logo-text-glow">ArgoBox</span>
<span class="logo-dot-glow">.com</span>
</div>
<p class="footer-description">
Enterprise-grade home lab environment for DevOps experimentation, infrastructure automation, and containerized application deployment.
</p>
<div class="footer-evolution">
<i class="fas fa-code-branch evolution-icon"></i>
<span>Continuously evolving since 2011</span>
</div>
</div>
<div class="footer-links">
<a href="index.html#home">Home</a>
<a href="index.html#services">Services</a>
<a href="index.html#lab">Live Lab</a>
<a href="index.html#projects">Projects</a>
<a href="index.html#contact">Contact</a>
<div class="footer-links-column">
<h3 class="footer-heading">Platforms</h3>
<a href="https://dashboard.argobox.com" class="footer-link">Dashboard</a>
<a href="ansible-sandbox.html" class="footer-link">Ansible Sandbox</a>
<a href="https://git.argobox.com" class="footer-link">Gitea</a>
<a href="https://ai.argobox.com" class="footer-link">OpenWebUI</a>
</div>
<div class="footer-social">
<a href="https://github.com/keyargo" target="_blank" aria-label="GitHub"><i class="fab fa-github"></i></a>
<a href="https://www.linkedin.com/in/danlaforce" target="_blank" aria-label="LinkedIn"><i class="fab fa-linkedin"></i></a>
<a href="mailto:daniel.laforce@argobox.com" aria-label="Email"><i class="fas fa-envelope"></i></a>
<div class="footer-links-column">
<h3 class="footer-heading">Documentation</h3>
<a href="construction.html" class="footer-link">Architecture</a>
<a href="construction.html" class="footer-link">Kubernetes</a>
<a href="construction.html" class="footer-link">Ansible</a>
<a href="construction.html" class="footer-link">Network</a>
</div>
<div class="footer-links-column">
<h3 class="footer-heading">Resources</h3>
<a href="construction.html" class="footer-link">Ansible Playbooks</a>
<a href="construction.html" class="footer-link">K8s Manifests</a>
<a href="construction.html" class="footer-link">Shell Scripts</a>
<a href="construction.html" class="footer-link">Configuration Files</a>
</div>
</div>
</div>

File diff suppressed because it is too large Load Diff

View File

@ -187,6 +187,10 @@
position: relative;
}
.live-indicator.offline {
background-color: var(--error);
}
.live-indicator::after {
content: '';
position: absolute;
@ -200,6 +204,10 @@
z-index: -1;
}
.live-indicator.offline::after {
background-color: var(--error);
}
.menu-toggle {
display: none;
background: none;
@ -989,6 +997,250 @@
grid-template-columns: 1fr;
}
}
/* Simulation toggle */
.simulation-toggle {
display: flex;
align-items: center;
gap: 0.75rem;
margin-left: 1rem;
}
.toggle-switch {
position: relative;
display: inline-block;
width: 46px;
height: 24px;
pointer-events: none; /* Make toggle non-interactive */
}
.toggle-switch input {
opacity: 0;
width: 0;
height: 0;
}
.toggle-slider {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: rgba(148, 163, 184, 0.2);
transition: .4s;
border-radius: 24px;
}
.toggle-slider:before {
position: absolute;
content: "";
height: 18px;
width: 18px;
left: 3px;
bottom: 3px;
background-color: var(--text-secondary);
transition: .4s;
border-radius: 50%;
}
input:checked + .toggle-slider {
background-color: rgba(59, 130, 246, 0.3);
}
input:checked + .toggle-slider:before {
transform: translateX(22px);
background-color: var(--accent);
}
.toggle-label {
font-size: 0.85rem;
color: var(--text-secondary);
font-weight: 500;
}
.toggle-status {
font-weight: 600;
color: var(--text-secondary);
}
/* Status indicators - including offline state */
.live-indicator.offline {
background-color: var(--error);
}
.live-indicator.offline::after {
background-color: var(--error);
}
.live-indicator-label.offline {
background-color: rgba(239, 68, 68, 0.1);
color: var(--error);
}
/* System offline notice */
.offline-notice {
background-color: rgba(239, 68, 68, 0.1);
border: 1px solid rgba(239, 68, 68, 0.3);
border-radius: 0.75rem;
padding: 1rem 1.5rem;
margin-bottom: 2rem;
display: flex;
align-items: center;
gap: 1.5rem;
}
.offline-notice-icon {
font-size: 1.5rem;
color: var(--error);
}
.offline-notice-text h3 {
font-size: 1.1rem;
font-weight: 600;
margin-bottom: 0.25rem;
color: var(--error);
}
.offline-notice-text p {
font-size: 0.9rem;
color: var(--text-secondary);
margin: 0;
}
/* Popup styles for settings and alerts */
.popup-overlay {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: rgba(15, 23, 42, 0.8);
backdrop-filter: blur(5px);
-webkit-backdrop-filter: blur(5px);
z-index: 1001;
display: none;
align-items: center;
justify-content: center;
}
.popup-container {
background-color: var(--secondary-bg);
border-radius: 0.75rem;
box-shadow: var(--card-shadow);
width: 90%;
max-width: 500px;
max-height: 90vh;
overflow-y: auto;
}
.popup-header {
display: flex;
align-items: center;
justify-content: space-between;
padding: 1.25rem 1.5rem;
border-bottom: 1px solid var(--border);
}
.popup-title {
font-size: 1.25rem;
font-weight: 600;
}
.popup-close {
font-size: 1.5rem;
cursor: pointer;
color: var(--text-secondary);
transition: color var(--transition-normal);
}
.popup-close:hover {
color: var(--text-primary);
}
.popup-content {
padding: 1.5rem;
}
/* Settings popup */
.settings-section {
margin-bottom: 1.5rem;
}
.settings-section:last-child {
margin-bottom: 0;
}
.settings-title {
font-size: 1rem;
font-weight: 600;
margin-bottom: 1rem;
color: var(--text-primary);
}
.settings-option {
display: flex;
justify-content: space-between;
align-items: center;
padding: 0.75rem 0;
border-bottom: 1px solid var(--border);
}
.settings-option:last-child {
border-bottom: none;
}
.settings-label {
font-size: 0.95rem;
color: var(--text-secondary);
}
/* Alerts popup */
.alert-list {
display: flex;
flex-direction: column;
gap: 1rem;
}
.alert-item {
background-color: rgba(30, 41, 59, 0.5);
border-radius: 0.5rem;
padding: 1rem;
border-left: 3px solid var(--accent);
}
.alert-item.error {
border-left-color: var(--error);
}
.alert-item.warning {
border-left-color: var(--warning);
}
.alert-item.success {
border-left-color: var(--success);
}
.alert-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 0.5rem;
}
.alert-title {
font-weight: 600;
font-size: 0.95rem;
}
.alert-time {
font-size: 0.8rem;
color: var(--text-secondary);
}
.alert-message {
font-size: 0.9rem;
color: var(--text-secondary);
}
</style>
</head>
<body>
@ -997,21 +1249,20 @@
<div class="container">
<div class="logo">
<a href="index.html">
<span class="logo-text">Argobox</span>
<span class="logo-dot">.com</span>
<span class="logo-text-glow">ArgoBox</span><span class="logo-dot-glow">.com</span>
</a>
</div>
<div class="nav-menu">
<a href="index.html#home" class="nav-link">Home</a>
<a href="index.html#technologies" class="nav-link">Technologies</a>
<a href="index.html#services" class="nav-link">Services</a>
<a href="index.html#lab" class="nav-link">Live Lab</a>
<a href="index.html#projects" class="nav-link">Projects</a>
<a href="index.html#experience" class="nav-link">Experience</a>
<a href="index.html#dashboards" class="nav-link">Dashboards</a>
<a href="index.html#contact" class="nav-link">Contact</a>
</div>
<div class="nav-buttons">
<a href="dashboard.html" class="dashboard-link" target="_blank">
<span class="live-indicator"></span>
<a href="https://dashboard.argobox.com" class="dashboard-link" target="_blank">
<span class="live-indicator offline"></span>
<span>Live Dashboard</span>
</a>
<button class="menu-toggle" aria-label="Toggle menu">
@ -1021,6 +1272,28 @@
</div>
</nav>
<!-- Top Links -->
<div class="top-links">
<a href="https://laforceit.com" class="laforceit-link">
<span class="logo-text-glow">LaForceIT</span><span class="logo-dot-glow">.com</span>
</a>
<a href="construction.html" class="signin-button" target="_blank">
<i class="fas fa-sign-in-alt"></i>
<span>Sign In</span>
</a>
</div>
<!-- Add offline notice banner after the top links but push it down below the navbar -->
<div class="offline-notice" id="offline-notice" style="display: block; margin-top: 8rem;">
<div class="offline-notice-icon">
<i class="fas fa-exclamation-triangle"></i>
</div>
<div class="offline-notice-text">
<h3>Dashboard is Currently Offline</h3>
<p>The live dashboard is currently in simulation mode. You can explore the interface, but real-time data is not available. We're working to restore full functionality soon.</p>
</div>
</div>
<div class="dashboard-container">
<div class="container">
<div class="dashboard-header">
@ -1030,18 +1303,26 @@
<span class="live-dot"></span>
<span>Live</span>
</div>
<div class="simulation-toggle">
<span class="toggle-label">Simulation Mode:</span>
<label class="toggle-switch">
<input type="checkbox" id="simulation-toggle">
<span class="toggle-slider"></span>
</label>
<span class="toggle-status">Inactive</span>
</div>
</div>
<div class="dashboard-actions">
<button class="dashboard-btn">
<button class="dashboard-btn" id="refresh-btn">
<i class="fas fa-sync-alt"></i>
<span>Refresh</span>
</button>
<button class="dashboard-btn">
<button class="dashboard-btn" id="alerts-btn">
<i class="fas fa-bell"></i>
<span>Alerts</span>
</button>
<button class="dashboard-btn">
<button class="dashboard-btn" id="settings-btn">
<i class="fas fa-cog"></i>
<span>Settings</span>
</button>
@ -1386,27 +1667,186 @@
</div>
</div>
<!-- Settings Popup -->
<div class="popup-overlay" id="settings-popup">
<div class="popup-container">
<div class="popup-header">
<h3 class="popup-title">Dashboard Settings</h3>
<div class="popup-close" id="close-settings">&times;</div>
</div>
<div class="popup-content">
<div class="settings-section">
<h4 class="settings-title">Display Options</h4>
<div class="settings-option">
<span class="settings-label">Dark mode</span>
<label class="toggle-switch">
<input type="checkbox" checked>
<span class="toggle-slider"></span>
</label>
</div>
<div class="settings-option">
<span class="settings-label">Auto-refresh</span>
<label class="toggle-switch">
<input type="checkbox" checked>
<span class="toggle-slider"></span>
</label>
</div>
<div class="settings-option">
<span class="settings-label">Refresh interval</span>
<select class="settings-select">
<option value="30">30 seconds</option>
<option value="60" selected>1 minute</option>
<option value="300">5 minutes</option>
<option value="600">10 minutes</option>
</select>
</div>
</div>
<div class="settings-section">
<h4 class="settings-title">Data Visualization</h4>
<div class="settings-option">
<span class="settings-label">Show metrics in header</span>
<label class="toggle-switch">
<input type="checkbox" checked>
<span class="toggle-slider"></span>
</label>
</div>
<div class="settings-option">
<span class="settings-label">Chart animation</span>
<label class="toggle-switch">
<input type="checkbox" checked>
<span class="toggle-slider"></span>
</label>
</div>
</div>
<div class="settings-section">
<h4 class="settings-title">Notifications</h4>
<div class="settings-option">
<span class="settings-label">Email alerts</span>
<label class="toggle-switch">
<input type="checkbox">
<span class="toggle-slider"></span>
</label>
</div>
<div class="settings-option">
<span class="settings-label">Browser notifications</span>
<label class="toggle-switch">
<input type="checkbox" checked>
<span class="toggle-slider"></span>
</label>
</div>
<div class="settings-option">
<span class="settings-label">Notify on system events</span>
<label class="toggle-switch">
<input type="checkbox" checked>
<span class="toggle-slider"></span>
</label>
</div>
</div>
</div>
</div>
</div>
<!-- Alerts Popup -->
<div class="popup-overlay" id="alerts-popup">
<div class="popup-container">
<div class="popup-header">
<h3 class="popup-title">System Alerts</h3>
<div class="popup-close" id="close-alerts">&times;</div>
</div>
<div class="popup-content">
<div class="alert-list">
<div class="alert-item warning">
<div class="alert-header">
<div class="alert-title">Memory usage above 70%</div>
<div class="alert-time">20 minutes ago</div>
</div>
<div class="alert-message">
The system memory usage has exceeded 70% threshold. Consider optimizing applications or adding more memory.
</div>
</div>
<div class="alert-item error">
<div class="alert-header">
<div class="alert-title">Container restart detected</div>
<div class="alert-time">35 minutes ago</div>
</div>
<div class="alert-message">
The "nginx-proxy" container has been restarted unexpectedly. Check the logs for more information.
</div>
</div>
<div class="alert-item info">
<div class="alert-header">
<div class="alert-title">System update available</div>
<div class="alert-time">1 hour ago</div>
</div>
<div class="alert-message">
A new system update is available for your server. Consider scheduling a maintenance window.
</div>
</div>
<div class="alert-item success">
<div class="alert-header">
<div class="alert-title">Backup completed successfully</div>
<div class="alert-time">2 hours ago</div>
</div>
<div class="alert-message">
Daily backup has been completed successfully. 12.3 GB of data has been backed up.
</div>
</div>
<div class="alert-item warning">
<div class="alert-header">
<div class="alert-title">Disk space running low</div>
<div class="alert-time">3 hours ago</div>
</div>
<div class="alert-message">
The "/data" partition is at 85% capacity. Consider cleaning up unused files or expanding storage.
</div>
</div>
</div>
</div>
</div>
</div>
<!-- Footer -->
<footer class="footer">
<div class="container">
<div class="footer-content">
<div class="footer-info">
<div class="footer-logo">
<span class="logo-text">Argobox</span>
<span class="logo-dot">.com</span>
<span class="logo-text-glow">ArgoBox</span>
<span class="logo-dot-glow">.com</span>
</div>
<p class="footer-description">
Enterprise-grade home lab environment for DevOps experimentation, infrastructure automation, and containerized application deployment.
</p>
<div class="footer-evolution">
<i class="fas fa-code-branch evolution-icon"></i>
<span>Continuously evolving since 2011</span>
</div>
</div>
<div class="footer-links">
<a href="index.html">Home</a>
<a href="index.html#services">Services</a>
<a href="index.html#lab">Live Lab</a>
<a href="index.html#projects">Projects</a>
<a href="index.html#experience">Experience</a>
<a href="index.html#contact">Contact</a>
<div class="footer-links-column">
<h3 class="footer-heading">Platforms</h3>
<a href="https://dashboard.argobox.com" class="footer-link">Dashboard</a>
<a href="ansible-sandbox.html" class="footer-link">Ansible Sandbox</a>
<a href="https://git.argobox.com" class="footer-link">Gitea</a>
<a href="https://ai.argobox.com" class="footer-link">OpenWebUI</a>
</div>
<div class="footer-social">
<a href="https://linkedin.com/in/danlaforce" target="_blank"><i class="fab fa-linkedin"></i></a>
<a href="https://github.com/keyargo" target="_blank"><i class="fab fa-github"></i></a>
<div class="footer-links-column">
<h3 class="footer-heading">Documentation</h3>
<a href="construction.html" class="footer-link">Architecture</a>
<a href="construction.html" class="footer-link">Kubernetes</a>
<a href="construction.html" class="footer-link">Ansible</a>
<a href="construction.html" class="footer-link">Network</a>
</div>
<div class="footer-links-column">
<h3 class="footer-heading">Resources</h3>
<a href="construction.html" class="footer-link">Ansible Playbooks</a>
<a href="construction.html" class="footer-link">K8s Manifests</a>
<a href="construction.html" class="footer-link">Shell Scripts</a>
<a href="construction.html" class="footer-link">Configuration Files</a>
</div>
</div>
</div>
@ -1466,12 +1906,117 @@
});
// Refresh button functionality
const refreshBtn = document.querySelector('.dashboard-btn');
const refreshBtn = document.getElementById('refresh-btn');
refreshBtn.addEventListener('click', function() {
simulateRefresh();
});
// Initialize simulation toggle based on system status
const toggleInput = document.getElementById('simulation-toggle');
const toggleStatus = document.querySelector('.toggle-status');
const liveIndicator = document.querySelector('.live-dot');
const liveLabel = document.querySelector('.live-indicator-label');
// System status is set to offline by default
if (liveIndicator) {
liveIndicator.classList.add('offline');
}
if (liveLabel) {
liveLabel.textContent = 'Offline';
liveLabel.classList.add('offline');
}
// Set simulation toggle to checked and non-interactive
if (toggleInput) {
toggleInput.checked = true;
toggleStatus.textContent = 'Active';
}
// Simulate a ping check to determine if system is online
// In a real implementation, this would be an actual API call
function checkSystemStatus() {
// For demonstration, we'll hardcode to offline (true)
// In a real implementation, this would check connectivity
const isOffline = true;
if (isOffline) {
// System is offline
if (toggleInput) {
toggleInput.checked = true;
toggleStatus.textContent = 'Active';
}
document.querySelector('.offline-notice').style.display = 'block';
if (liveIndicator) {
liveIndicator.classList.add('offline');
}
if (liveLabel) {
liveLabel.textContent = 'Offline';
liveLabel.classList.add('offline');
}
} else {
// System is online
if (toggleInput) {
toggleInput.checked = false;
toggleStatus.textContent = 'Inactive';
}
document.querySelector('.offline-notice').style.display = 'none';
if (liveIndicator) {
liveIndicator.classList.remove('offline');
}
if (liveLabel) {
liveLabel.textContent = 'Online';
liveLabel.classList.remove('offline');
}
}
}
// Check system status on page load
checkSystemStatus();
// Periodically check system status (every 30 seconds)
setInterval(checkSystemStatus, 30000);
// Set up settings and alerts popup functionality
const settingsBtn = document.getElementById('settings-btn');
const alertsBtn = document.getElementById('alerts-btn');
const settingsPopup = document.getElementById('settings-popup');
const alertsPopup = document.getElementById('alerts-popup');
const closeSettings = document.getElementById('close-settings');
const closeAlerts = document.getElementById('close-alerts');
settingsBtn.addEventListener('click', function() {
settingsPopup.style.display = 'flex';
});
alertsBtn.addEventListener('click', function() {
alertsPopup.style.display = 'flex';
});
closeSettings.addEventListener('click', function() {
settingsPopup.style.display = 'none';
});
closeAlerts.addEventListener('click', function() {
alertsPopup.style.display = 'none';
});
// Close popups when clicking outside
window.addEventListener('click', function(e) {
if (e.target === settingsPopup) {
settingsPopup.style.display = 'none';
}
if (e.target === alertsPopup) {
alertsPopup.style.display = 'none';
}
});
// Set up simulation of real-time data
function simulateRefresh() {
// Update metrics with random variations
@ -1481,7 +2026,7 @@
updateOverviewCard('Network', 15, 40);
// Update last refresh time
document.getElementById('last-refresh').textContent = 'Just now';
document.querySelector('.services-refresh span').textContent = 'Last updated: Just now';
// Add a new log entry
addLogEntry();
@ -1523,8 +2068,11 @@
function addLogEntry() {
const logsContent = document.querySelector('.logs-content');
// Get current time in MST (UTC-7)
const now = new Date();
const timeString = `${now.getHours().toString().padStart(2, '0')}:${now.getMinutes().toString().padStart(2, '0')}:${now.getSeconds().toString().padStart(2, '0')}`;
const mstTime = new Date(now.getTime() - (7 * 60 * 60 * 1000)); // Convert to MST
const timeString = `${mstTime.getHours().toString().padStart(2, '0')}:${mstTime.getMinutes().toString().padStart(2, '0')}:${mstTime.getSeconds().toString().padStart(2, '0')}`;
const logTypes = ['info', 'success', 'warning', 'error'];
const logType = logTypes[Math.floor(Math.random() * logTypes.length)];
@ -1537,7 +2085,13 @@
'Disk space cleanup completed',
'User session timeout',
'API rate limit approaching',
'Security scan completed'
'Security scan completed',
'Database connection pool refreshed',
'Cache invalidation triggered',
'SSL certificate validity verified',
'User authentication succeeded',
'Scheduled task executed',
'Configuration updated'
];
const logMessage = logMessages[Math.floor(Math.random() * logMessages.length)];
@ -1551,15 +2105,96 @@
`;
logsContent.insertBefore(logEntry, logsContent.firstChild);
// Keep only the last 20 log entries
const allEntries = logsContent.querySelectorAll('.log-entry');
if (allEntries.length > 20) {
for (let i = 20; i < allEntries.length; i++) {
logsContent.removeChild(allEntries[i]);
}
}
}
// Mobile menu toggle
const menuToggle = document.querySelector('.menu-toggle');
const navMenu = document.querySelector('.nav-menu');
if (menuToggle && navMenu) {
menuToggle.addEventListener('click', function() {
navMenu.classList.toggle('active');
});
}
// Generate initial log entries with timestamps ranging from 30-40 minutes ago to now
function generateInitialLogs() {
const logsContent = document.querySelector('.logs-content');
if (!logsContent) return;
// Clear existing logs
logsContent.innerHTML = '';
// Get current time in MST
const now = new Date();
const mstNow = new Date(now.getTime() - (7 * 60 * 60 * 1000)); // Convert to MST
// Generate entries from 40 minutes ago to now
for (let i = 0; i < 15; i++) {
const minutesAgo = Math.floor(Math.random() * 40) + 1; // 1-40 minutes ago
const logTime = new Date(mstNow.getTime() - (minutesAgo * 60 * 1000));
const timeString = `${logTime.getHours().toString().padStart(2, '0')}:${logTime.getMinutes().toString().padStart(2, '0')}:${logTime.getSeconds().toString().padStart(2, '0')}`;
const logTypes = ['info', 'success', 'warning', 'error'];
const logType = logTypes[Math.floor(Math.random() * logTypes.length)];
const logMessages = [
'System health check completed',
'Container restarted automatically',
'Network traffic spike detected',
'Backup process initiated',
'Disk space cleanup completed',
'User session timeout',
'API rate limit approaching',
'Security scan completed',
'Database connection pool refreshed',
'Cache invalidation triggered',
'SSL certificate validity verified',
'User authentication succeeded',
'Scheduled task executed',
'Configuration updated'
];
const logMessage = logMessages[Math.floor(Math.random() * logMessages.length)];
const logEntry = document.createElement('div');
logEntry.className = 'log-entry';
logEntry.innerHTML = `
<span class="log-time">${timeString}</span>
<span class="log-level log-level-${logType}">${logType.toUpperCase()}</span>
<span class="log-message">${logMessage}</span>
`;
// Sort logs by time (most recent at the top)
if (logsContent.children.length === 0) {
logsContent.appendChild(logEntry);
} else {
let inserted = false;
for (let j = 0; j < logsContent.children.length; j++) {
const existingTime = logsContent.children[j].querySelector('.log-time').textContent;
if (timeString > existingTime) {
logsContent.insertBefore(logEntry, logsContent.children[j]);
inserted = true;
break;
}
}
if (!inserted) {
logsContent.appendChild(logEntry);
}
}
}
}
// Generate initial logs
generateInitialLogs();
// Auto refresh every 60 seconds
setInterval(function() {

View File

@ -27,6 +27,17 @@
<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=Inter:wght@300;400;500;600;700&family=JetBrains+Mono:wght@400;500&display=swap" rel="stylesheet">
<style>
/* Add the CSS for the offline indicator */
.live-indicator.offline {
background-color: #ef4444 !important; /* Red color */
}
.live-indicator.offline::after {
background-color: #ef4444 !important;
}
</style>
</head>
<body>
<!-- Navigation Bar -->
@ -47,7 +58,7 @@
</div>
<div class="nav-buttons">
<a href="https://dashboard.argobox.com" class="dashboard-link" target="_blank">
<span class="live-indicator"></span>
<span class="live-indicator offline"></span>
<span>Live Dashboard</span>
</a>
<button class="menu-toggle" aria-label="Toggle menu">
@ -111,9 +122,10 @@
</div>
</div>
<div class="cta-buttons">
<a href="ansible-sandbox.html" class="btn btn-primary" target="_blank">
<a href="ansible-sandbox.html" class="btn btn-danger" target="_blank" id="ansible-sandbox-btn">
<i class="fab fa-ansible btn-icon"></i>
<span class="btn-text">Try Ansible Sandbox</span>
<span class="offline-badge">Offline</span>
</a>
<a href="#architecture" class="btn btn-outline">
<i class="fas fa-network-wired btn-icon"></i>
@ -468,9 +480,9 @@
<h4 class="service-name">Ansible Sandbox</h4>
<p class="service-description">Interactive environment for infrastructure automation</p>
</div>
<div class="service-status live">
<div class="service-status offline">
<span class="status-dot"></span>
<span class="status-text">Public</span>
<span class="status-text">Offline</span>
</div>
</a>
<div class="service-item">
@ -894,7 +906,7 @@
</p>
<div class="footer-evolution">
<i class="fas fa-code-branch evolution-icon"></i>
<span>Continuously evolving since 2013</span>
<span>Continuously evolving since 2011</span>
</div>
</div>

View File

@ -2759,137 +2759,140 @@ section {
}
/* Enhanced Mobile Optimizations */
@media (max-width: 480px) {
section {
padding: 3rem 0;
@media (max-width: 768px) {
/* Improve readability on mobile */
body {
font-size: 16px;
}
.section-title {
font-size: 1.75rem;
/* Make buttons more tappable */
.btn, .nav-link, .service-item, .tech-card, .project-card {
padding: 0.8rem;
}
.section-description {
font-size: 0.95rem;
}
.container {
padding: 0 1rem;
}
/* Architecture section mobile optimization */
.architecture-diagram {
flex-direction: column;
}
.diagram-wrapper {
width: 100%;
/* Better spacing for section headers on mobile */
.section-header {
margin-bottom: 2rem;
}
.architecture-details {
width: 100%;
.section-title {
font-size: 1.8rem;
}
/* Improved mobile tech grid */
.tech-grid {
/* Improved hero section for mobile */
.hero {
padding: 6rem 0 3rem;
}
.hero-title {
font-size: 2rem;
line-height: 1.3;
}
.hero-description {
font-size: 1rem;
margin-bottom: 1.5rem;
}
.cta-buttons {
flex-wrap: wrap;
gap: 1rem;
}
/* Improved card layouts for touch */
.tech-grid, .services-grid, .projects-grid, .dashboard-grid {
grid-template-columns: 1fr;
gap: 1rem;
}
.tech-card {
padding: 1.5rem;
.tech-card, .service-item, .project-card {
padding: 1.25rem;
}
/* Services optimization */
.services-grid {
grid-template-columns: 1fr;
}
.service-items {
grid-template-columns: 1fr;
}
/* Contact form mobile friendly */
.contact-grid {
grid-template-columns: 1fr;
}
.contact-form {
padding: 1.5rem;
}
/* Top links mobile optimization */
.top-links {
padding: 0.5rem 1rem;
justify-content: center;
}
.laforceit-link, .signin-button {
font-size: 0.85rem;
}
/* Projects section mobile */
.projects-grid {
grid-template-columns: 1fr;
}
/* Dashboard section mobile */
.dashboard-grid {
grid-template-columns: 1fr;
}
}
/* Touch-friendly adjustments */
@media (hover: none) {
.btn:hover::before {
display: none;
}
.btn:active {
transform: scale(0.98);
}
.service-item, .tech-card, .project-card, .dashboard-card {
transition: transform 0.2s ease;
/* Enhanced tap targets for touch */
.service-item, .tech-card, .project-card, .dashboard-card, .footer-link {
transition: transform 0.2s ease, box-shadow 0.2s ease;
}
.service-item:active, .tech-card:active, .project-card:active, .dashboard-card:active {
transform: scale(0.98);
}
.nav-link:active::after {
width: 100%;
}
}
/* Improved scrolling for mobile */
@media (max-width: 768px) {
html {
scroll-padding-top: var(--mobile-nav-height);
/* Tablet-specific optimizations */
@media (min-width: 481px) and (max-width: 1024px) {
/* Two-column layouts for tablets */
.tech-grid, .services-grid, .projects-grid {
grid-template-columns: repeat(2, 1fr);
}
/* Handle form inputs better on mobile */
input, textarea, select, button {
font-size: 16px !important; /* Prevents zoom on focus in iOS */
/* Balanced spacing for tablets */
section {
padding: 4rem 0;
}
/* Optimized footer for mobile */
.footer-content {
flex-direction: column;
}
.footer-info {
margin-bottom: 2rem;
text-align: center;
width: 100%;
}
.footer-links {
width: 100%;
grid-template-columns: 1fr;
/* Hero layout adjustments */
.hero-content {
gap: 2rem;
}
.footer-links-column {
text-align: center;
/* Architecture diagram adjustments */
.architecture-diagram {
flex-direction: column;
}
/* Footer improvements */
.footer-content {
flex-wrap: wrap;
}
}
/* Phone-specific optimizations */
@media (max-width: 480px) {
.hero-stats {
grid-template-columns: repeat(2, 1fr);
gap: 1rem;
}
.stat-item {
padding: 0.75rem;
}
.stat-value {
font-size: 1.25rem;
}
/* Single column layouts for phones */
.contact-grid, .architecture-details {
grid-template-columns: 1fr;
}
/* Improved form elements for touch */
input, textarea, button {
font-size: 16px; /* Prevents zoom on input focus on iOS */
padding: 0.8rem;
}
/* Navbar adjustments */
.navbar .container {
padding: 0 1rem;
}
}
/* Touch optimizations */
@media (hover: none) {
/* Disable hover effects on touch devices */
.btn::before, .service-item:hover, .tech-card:hover {
transform: none;
}
/* Use active states instead */
.btn:active, .nav-link:active, .service-item:active {
opacity: 0.8;
}
/* Larger tap targets */
.nav-link, .footer-link, .dashboard-link {
padding: 0.6rem;
}
}