Update website with new features: - Restored live dashboard layout - Moved sign-in button to top right - Updated documentation links to construction.html - Added Ansible Sandbox icon - Renamed Dev Environment to VS Code Powered - Updated AI Assistant description - Added GitHub Actions service - Replaced NextCloud with Synology Drive

This commit is contained in:
Daniel LaForce 2025-04-09 20:39:14 -06:00
parent e4abc52092
commit d606b4018e
10 changed files with 2522 additions and 2231 deletions

View File

@ -40,6 +40,7 @@
--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);
}
* {
@ -58,333 +59,236 @@
radial-gradient(circle at 75% 60%, rgba(14, 165, 233, 0.1) 0%, transparent 50%);
}
.docs-container {
display: flex;
min-height: 100vh;
}
.sidebar {
width: 280px;
background-color: var(--sidebar-bg);
border-right: 1px solid var(--border);
.navbar {
background-color: rgba(15, 23, 42, 0.9);
backdrop-filter: var(--glass-effect);
-webkit-backdrop-filter: var(--glass-effect);
position: fixed;
top: 0;
left: 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;
right: 0;
z-index: 1000;
padding: 1.25rem 0;
border-bottom: 1px solid var(--border);
}
.docs-subsection {
margin-bottom: 2rem;
.navbar .container {
display: flex;
justify-content: space-between;
align-items: center;
max-width: 1400px;
margin: 0 auto;
padding: 0 1.5rem;
}
.docs-subsection-title {
font-size: 1.25rem;
font-weight: 600;
margin-bottom: 1rem;
color: var(--accent);
}
.docs-text {
color: var(--text-secondary);
margin-bottom: 1.5rem;
}
.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);
.logo a {
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;
display: flex;
align-items: center;
gap: 0.25rem;
}
.docs-button:hover {
background-color: var(--accent-darker);
transform: translateY(-2px);
box-shadow: var(--card-shadow);
}
.docs-footer {
border-top: 1px solid var(--border);
margin-top: 3rem;
padding-top: 2rem;
color: var(--text-secondary);
font-size: 0.9rem;
}
.mobile-menu-toggle {
display: none;
position: fixed;
bottom: 1.5rem;
right: 1.5rem;
.logo-text {
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;
-webkit-background-clip: text;
background-clip: text;
color: transparent;
font-size: 1.5rem;
align-items: center;
justify-content: center;
z-index: 20;
box-shadow: var(--card-shadow);
font-weight: 600;
}
@media (max-width: 992px) {
.sidebar {
transform: translateX(-100%);
.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 {
color: var(--accent);
}
.nav-buttons {
display: flex;
align-items: center;
gap: 1.25rem;
}
.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);
border-radius: 0.5rem;
text-decoration: none;
transition: all var(--transition-normal);
}
.dashboard-link:hover {
background-color: var(--accent-darker);
}
.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);
}
.sidebar.active {
transform: translateX(0);
.navbar .nav-menu.show {
display: block;
}
.main-content {
margin-left: 0;
padding: 2rem 1.5rem;
.footer {
background-color: var(--secondary-bg);
padding: 2rem;
color: var(--text-secondary);
border-top: 1px solid var(--border);
}
.mobile-menu-toggle {
.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 {
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;
}
@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;
}
.navbar .nav-menu.show {
display: flex;
}
}
</style>
</head>
<body>
<!-- Navigation Bar -->
<nav class="navbar">
<div class="container">
<div class="logo">
<a href="index.html">
<span class="logo-text">Argobox</span>
<span class="logo-dot">.com</span>
</a>
</div>
<div class="nav-menu">
<a href="index.html#home" class="nav-link">Home</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#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>
<span>Live Dashboard</span>
</a>
<button class="menu-toggle" aria-label="Toggle menu">
<i class="fas fa-bars"></i>
</button>
</div>
</div>
</nav>
<div class="docs-container">
<aside class="sidebar">
<div class="sidebar-header">
@ -837,18 +741,39 @@ web-server/
</ul>
</div>
</section>
<footer class="docs-footer">
<p>
For questions or suggestions about the Ansible Sandbox, please contact <a href="mailto:contact@argobox.com">contact@argobox.com</a>.
</p>
<p>
&copy; <span id="current-year">2025</span> Argobox.com. All rights reserved.
</p>
</footer>
</main>
</div>
<!-- Footer -->
<footer class="footer">
<div class="container">
<div class="footer-content">
<div class="footer-logo">
<span class="logo-text">Argobox</span>
<span class="logo-dot">.com</span>
</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>
<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>
</div>
<div class="footer-bottom">
<p>&copy; <span id="current-year"></span> All rights reserved. Inovin LLC</p>
</div>
</div>
</footer>
<button class="mobile-menu-toggle">
<i class="fas fa-bars"></i>
</button>
@ -934,6 +859,23 @@ 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

@ -39,6 +39,7 @@
--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);
}
* {
@ -245,9 +246,184 @@
grid-column: 1;
}
}
.navbar {
background-color: rgba(15, 23, 42, 0.9);
backdrop-filter: var(--glass-effect);
-webkit-backdrop-filter: var(--glass-effect);
position: fixed;
top: 0;
left: 0;
right: 0;
z-index: 1000;
padding: 1.25rem 0;
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;
}
.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;
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-buttons {
display: flex;
align-items: center;
gap: 1.25rem;
}
.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);
border-radius: 0.5rem;
text-decoration: none;
transition: all var(--transition-normal);
}
.menu-toggle {
background: none;
border: none;
color: var(--text-primary);
font-size: 1.5rem;
cursor: pointer;
}
.menu-toggle i {
transition: transform var(--transition-normal);
}
.nav-menu.show {
display: block;
}
.footer {
background-color: var(--secondary-bg);
padding: 2rem 0;
color: var(--text-secondary);
}
.footer-content {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 1rem;
}
.footer-logo {
font-size: 1.5rem;
font-weight: 700;
color: var(--accent);
}
.footer-links {
display: flex;
gap: 1rem;
}
.footer-links a {
color: var(--text-secondary);
text-decoration: none;
transition: color var(--transition-normal);
}
.footer-links a:hover {
color: var(--accent);
}
.footer-social a {
color: var(--text-secondary);
font-size: 1.2rem;
margin-right: 0.5rem;
transition: color var(--transition-normal);
}
.footer-social a:hover {
color: var(--accent);
}
.footer-bottom {
text-align: center;
font-size: 0.9rem;
}
</style>
</head>
<body>
<!-- Navigation Bar -->
<nav class="navbar">
<div class="container">
<div class="logo">
<a href="index.html">
<span class="logo-text">Argobox</span>
<span class="logo-dot">.com</span>
</a>
</div>
<div class="nav-menu">
<a href="index.html#home" class="nav-link">Home</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#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>
<span>Live Dashboard</span>
</a>
<button class="menu-toggle" aria-label="Toggle menu">
<i class="fas fa-bars"></i>
</button>
</div>
</div>
</nav>
<div class="container">
<div class="help-header">
<a href="ansible-sandbox.html" class="back-link">
@ -421,11 +597,60 @@
<span class="key-term">Template</span> - A text file that uses variables to create dynamic configuration files.
</p>
</div>
</div>
<div class="help-footer">
<p>Need more detailed information? Check out the <a href="ansible-docs.html">Ansible Sandbox Documentation</a>.</p>
<p>For questions about this sandbox, contact me at <a href="mailto:contact@argobox.com">contact@argobox.com</a>.</p>
<!-- Footer -->
<footer class="footer">
<div class="container">
<div class="footer-content">
<div class="footer-logo">
<span class="logo-text">Argobox</span>
<span class="logo-dot">.com</span>
</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>
<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>
</div>
<div class="footer-bottom">
<p>&copy; <span id="current-year"></span> All rights reserved. Inovin LLC</p>
</div>
</div>
</footer>
<script>
document.addEventListener('DOMContentLoaded', function() {
// Set current year in footer
document.getElementById('current-year').textContent = new Date().getFullYear();
// Mobile menu toggle
const menuToggle = document.querySelector('.menu-toggle');
const navMenu = document.querySelector('.nav-menu');
menuToggle.addEventListener('click', function() {
navMenu.classList.toggle('show');
const icon = menuToggle.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>
</html>

View File

@ -95,7 +95,7 @@
left: 0;
right: 0;
z-index: 1000;
padding: 1rem 0;
padding: 1.25rem 0;
border-bottom: 1px solid var(--border);
}
@ -105,16 +105,12 @@
align-items: center;
}
.logo {
font-weight: 600;
font-size: 1.5rem;
}
.logo a {
color: var(--text-primary);
text-decoration: none;
display: flex;
align-items: center;
gap: 0.25rem;
}
.logo-text {
@ -122,15 +118,19 @@
-webkit-background-clip: text;
background-clip: text;
color: transparent;
font-size: 1.5rem;
font-weight: 600;
}
.logo-dot {
color: var(--text-secondary);
font-size: 1.5rem;
font-weight: 600;
}
.nav-menu {
display: flex;
gap: 2rem;
gap: 2.5rem;
}
.nav-link {
@ -172,15 +172,15 @@
.nav-buttons {
display: flex;
align-items: center;
gap: 1rem;
gap: 1.25rem;
}
.dashboard-link {
display: flex;
align-items: center;
gap: 0.5rem;
padding: 0.5rem 1rem;
font-size: 0.9rem;
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);
@ -1469,11 +1469,11 @@
</div>
<div class="footer-links">
<a href="#home">Home</a>
<a href="#services">Services</a>
<a href="#lab">Live Lab</a>
<a href="#projects">Projects</a>
<a href="#contact">Contact</a>
<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>
<div class="footer-social">

170
construction.html Normal file
View File

@ -0,0 +1,170 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Under Construction | ArgoBox</title>
<link rel="stylesheet" href="styles.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.2/css/all.min.css">
<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&display=swap" rel="stylesheet">
<style>
.construction-container {
min-height: 100vh;
display: flex;
align-items: center;
justify-content: center;
background: linear-gradient(135deg, #0a0a0a 0%, #1a1a1a 100%);
position: relative;
overflow: hidden;
}
.construction-content {
text-align: center;
z-index: 1;
padding: 2rem;
max-width: 800px;
}
.construction-title {
font-size: 3rem;
color: #00ff9d;
margin-bottom: 1rem;
text-shadow: 0 0 10px rgba(0, 255, 157, 0.5);
font-family: 'JetBrains Mono', monospace;
}
.construction-subtitle {
font-size: 1.5rem;
color: #ffffff;
margin-bottom: 2rem;
opacity: 0.8;
}
.construction-status {
background: rgba(0, 255, 157, 0.1);
border: 1px solid rgba(0, 255, 157, 0.3);
padding: 1rem;
border-radius: 8px;
margin-bottom: 2rem;
font-family: 'JetBrains Mono', monospace;
}
.status-line {
color: #00ff9d;
margin: 0.5rem 0;
text-align: left;
}
.status-line::before {
content: '> ';
color: #00ff9d;
}
.construction-progress {
width: 100%;
height: 4px;
background: rgba(255, 255, 255, 0.1);
border-radius: 2px;
margin: 2rem 0;
overflow: hidden;
}
.progress-bar {
height: 100%;
background: linear-gradient(90deg, #00ff9d, #00b8ff);
width: 0;
animation: progress 2s ease-in-out infinite;
}
@keyframes progress {
0% { width: 0; }
50% { width: 100%; }
100% { width: 0; }
}
.construction-back {
color: #ffffff;
text-decoration: none;
display: inline-flex;
align-items: center;
gap: 0.5rem;
transition: color 0.3s ease;
}
.construction-back:hover {
color: #00ff9d;
}
.binary-rain {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: 0;
opacity: 0.1;
}
</style>
</head>
<body>
<div class="construction-container">
<div class="binary-rain" id="binary-rain"></div>
<div class="construction-content">
<h1 class="construction-title">UNDER CONSTRUCTION</h1>
<p class="construction-subtitle">This service is currently being deployed and configured</p>
<div class="construction-status">
<div class="status-line">Initializing deployment sequence...</div>
<div class="status-line">Configuring infrastructure components...</div>
<div class="status-line">Deploying service containers...</div>
<div class="status-line">Establishing secure connections...</div>
<div class="status-line">Optimizing performance parameters...</div>
</div>
<div class="construction-progress">
<div class="progress-bar"></div>
</div>
<a href="https://argobox.com" class="construction-back">
<i class="fas fa-arrow-left"></i>
Return to ArgoBox
</a>
</div>
</div>
<script>
// Create binary rain effect
const binaryRain = document.getElementById('binary-rain');
const chars = '01';
function createBinaryRain() {
const span = document.createElement('span');
span.textContent = chars.charAt(Math.floor(Math.random() * chars.length));
span.style.position = 'absolute';
span.style.left = Math.random() * 100 + '%';
span.style.top = '-20px';
span.style.color = '#00ff9d';
span.style.opacity = Math.random() * 0.5 + 0.5;
span.style.fontSize = Math.random() * 10 + 10 + 'px';
span.style.fontFamily = 'JetBrains Mono, monospace';
binaryRain.appendChild(span);
let pos = -20;
const fall = setInterval(() => {
pos += 2;
span.style.top = pos + 'px';
if (pos > window.innerHeight) {
clearInterval(fall);
span.remove();
}
}, 50);
}
setInterval(createBinaryRain, 100);
</script>
</body>
</html>

View File

@ -996,18 +996,18 @@
<nav class="navbar">
<div class="container">
<div class="logo">
<a href="#home">
<a href="index.html">
<span class="logo-text">Argobox</span>
<span class="logo-dot">.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>
<a href="index.html#home" class="nav-link">Home</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#contact" class="nav-link">Contact</a>
</div>
<div class="nav-buttons">
<a href="dashboard.html" class="dashboard-link" target="_blank">
@ -1400,13 +1400,13 @@
<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>
<div class="footer-social">
<a href="https://www.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>
<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>
</div>

Binary file not shown.

1172
index.html

File diff suppressed because it is too large Load Diff

View File

@ -1,836 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Daniel LaForce | Resume</title>
<!-- SEO Meta Tags -->
<meta name="description" content="Professional resume of Daniel LaForce - Systems & Infrastructure Engineer specializing in virtualization, containerization, and secure network architecture.">
<!-- Favicon -->
<link rel="icon" type="image/svg+xml" href="data:image/svg+xml,<svg xmlns=%22http://www.w3.org/2000/svg%22 width=%22256%22 height=%22256%22 viewBox=%220 0 100 100%22><rect width=%22100%22 height=%22100%22 rx=%2220%22 fill=%22%230f172a%22></rect><path fill=%22%233b82f6%22 d=%22M30 40L50 20L70 40L50 60L30 40Z%22></path><path fill=%22%233b82f6%22 d=%22M50 60L70 40L70 70L50 90L30 70L30 40L50 60Z%22 fill-opacity=%220.6%22></path></svg>">
<!-- Google Fonts -->
<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">
<!-- FontAwesome -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.2/css/all.min.css">
<!-- CSS -->
<link rel="stylesheet" href="styles.css">
<style>
/* Resume-specific styles */
body {
margin: 0;
padding: 0;
min-height: 100vh;
display: flex;
flex-direction: column;
}
.resume-container {
max-width: 1000px;
margin: 6rem auto 4rem;
padding: 0 1.5rem;
flex: 1;
}
.resume-header {
text-align: center;
margin-bottom: 3rem;
}
.resume-name {
font-size: 2.5rem;
margin-bottom: 0.5rem;
}
.resume-title {
font-size: 1.5rem;
color: var(--accent);
margin-bottom: 1.5rem;
}
.resume-contact {
display: flex;
justify-content: center;
flex-wrap: wrap;
gap: 1.5rem;
margin-bottom: 2rem;
}
.resume-contact-item {
display: flex;
align-items: center;
color: var(--text-secondary);
}
.resume-contact-item i {
margin-right: 0.5rem;
color: var(--accent);
}
.resume-section {
margin-bottom: 2.5rem;
background-color: var(--card-bg);
border-radius: 1rem;
padding: 2rem;
border: 1px solid var(--border);
}
.resume-section-title {
font-size: 1.5rem;
margin-bottom: 1.5rem;
color: var(--accent);
position: relative;
padding-bottom: 0.75rem;
}
.resume-section-title::after {
content: '';
position: absolute;
bottom: 0;
left: 0;
width: 50px;
height: 3px;
background: var(--accent-gradient);
border-radius: 3px;
}
.resume-job {
margin-bottom: 2rem;
}
.resume-job:last-child {
margin-bottom: 0;
}
.resume-job-header {
margin-bottom: 1rem;
}
.resume-job-title {
font-size: 1.25rem;
margin-bottom: 0.25rem;
}
.resume-job-company {
font-weight: 600;
color: var(--accent);
margin-bottom: 0.25rem;
}
.resume-job-period {
color: var(--text-secondary);
font-size: 0.9rem;
}
.resume-job-description {
color: var(--text-secondary);
margin-bottom: 1rem;
}
.resume-job-achievements {
list-style: none;
}
.resume-job-achievement {
display: flex;
margin-bottom: 0.75rem;
align-items: flex-start;
}
.resume-job-achievement i {
color: var(--accent);
margin-right: 0.75rem;
margin-top: 0.25rem;
flex-shrink: 0;
}
.resume-skills {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
gap: 1.5rem;
}
.resume-skill-category {
margin-bottom: 1.5rem;
}
.resume-skill-title {
font-size: 1.1rem;
font-weight: 600;
margin-bottom: 0.75rem;
color: var(--accent);
}
.resume-skill-list {
display: flex;
flex-wrap: wrap;
gap: 0.5rem;
}
.resume-skill {
background-color: rgba(59, 130, 246, 0.1);
border: 1px solid rgba(59, 130, 246, 0.3);
color: var(--accent);
font-size: 0.85rem;
font-weight: 500;
padding: 0.25rem 0.75rem;
border-radius: 9999px;
}
.resume-education {
margin-bottom: 1.5rem;
}
.resume-education-title {
font-size: 1.1rem;
font-weight: 600;
margin-bottom: 0.25rem;
}
.resume-education-institution {
color: var(--accent);
margin-bottom: 0.25rem;
}
.resume-education-period {
color: var(--text-secondary);
font-size: 0.9rem;
margin-bottom: 0.5rem;
}
.resume-education-grade {
color: var(--text-secondary);
font-size: 0.9rem;
margin-bottom: 0.5rem;
}
.resume-education-skills {
margin-top: 0.5rem;
color: var(--text-secondary);
}
.resume-projects {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
gap: 1.5rem;
}
.resume-project {
background-color: rgba(59, 130, 246, 0.1);
border-radius: 0.75rem;
padding: 1.5rem;
border: 1px solid rgba(59, 130, 246, 0.3);
}
.resume-project-title {
font-size: 1.1rem;
font-weight: 600;
margin-bottom: 0.75rem;
color: var(--accent);
}
.resume-project-tech {
display: flex;
flex-wrap: wrap;
gap: 0.5rem;
margin-top: 0.75rem;
}
.resume-project-tech-item {
font-size: 0.8rem;
color: var(--text-secondary);
background-color: rgba(255, 255, 255, 0.1);
padding: 0.15rem 0.5rem;
border-radius: 0.25rem;
}
.resume-awards {
list-style: none;
}
.resume-award {
display: flex;
margin-bottom: 0.75rem;
}
.resume-award i {
color: var(--accent);
margin-right: 0.75rem;
}
.resume-download {
text-align: center;
margin-top: 3rem;
}
.footer {
width: 100%;
left: 0;
right: 0;
bottom: 0;
background: var(--dark-bg);
border-top: 1px solid var(--border);
padding: 2rem 0;
margin-top: auto;
}
@media (max-width: 768px) {
.resume-skills, .resume-projects {
grid-template-columns: 1fr;
}
}
</style>
</head>
<body>
<!-- Navigation -->
<nav class="navbar">
<div class="container">
<div class="logo">
<a href="index.html">
<span class="logo-text">Argobox</span>
<span class="logo-dot">.com</span>
</a>
</div>
<div class="nav-menu">
<a href="index.html#home" class="nav-link">Home</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#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>
<span>Live Dashboard</span>
</a>
<button class="menu-toggle" aria-label="Toggle menu">
<i class="fas fa-bars"></i>
</button>
</div>
</div>
</nav>
<!-- Resume Content -->
<div class="resume-container">
<div class="resume-header">
<h1 class="resume-name">Daniel LaForce</h1>
<h2 class="resume-title">Infrastructure & Systems Engineer</h2>
<div class="resume-contact">
<div class="resume-contact-item">
<i class="fas fa-map-marker-alt"></i>
<span>Colorado Springs, Colorado</span>
</div>
<div class="resume-contact-item">
<i class="fas fa-phone"></i>
<a href="tel:7203100064">720-310-0064</a>
</div>
<div class="resume-contact-item">
<i class="fas fa-envelope"></i>
<a href="mailto:daniel.laforce@argobox.com">daniel.laforce@argobox.com</a>
</div>
<div class="resume-contact-item">
<i class="fab fa-linkedin"></i>
<a href="https://www.linkedin.com/in/danlaforce" target="_blank">linkedin.com/in/danlaforce</a>
</div>
<div class="resume-contact-item">
<i class="fab fa-github"></i>
<a href="https://github.com/keyargo" target="_blank">github.com/keyargo</a>
</div>
</div>
</div>
<!-- Experience Section -->
<div class="resume-section">
<h2 class="resume-section-title">Professional Experience</h2>
<div class="resume-job">
<div class="resume-job-header">
<h3 class="resume-job-title">Freelance Consultant GIS, Infrastructure & Security Solutions</h3>
<div class="resume-job-company">Inovin LLC</div>
<div class="resume-job-period">April 2023 Present | Colorado Springs, CO</div>
</div>
<div class="resume-job-achievements">
<div class="resume-job-achievement">
<i class="fas fa-check-circle"></i>
<span>Developed TerraTracer, a GIS mapping platform used by independent mining claim prospectors to automate boundary plotting, terrain-informed site selection, and BLM/state compliance, reducing manual research by 85%.</span>
</div>
<div class="resume-job-achievement">
<i class="fas fa-check-circle"></i>
<span>Consulted on virtualization and DevOps projects for SMB clients, implementing Proxmox/VMware solutions, containerizing legacy apps with Docker, and orchestrating microservices with Kubernetes.</span>
</div>
<div class="resume-job-achievement">
<i class="fas fa-check-circle"></i>
<span>Built secure cloud environments integrating Azure AD, SSO, and VPN/firewall solutions, increasing operational resilience while aligning with HIPAA and zero-trust principles.</span>
</div>
<div class="resume-job-achievement">
<i class="fas fa-check-circle"></i>
<span>Automated infrastructure tasks via PowerShell, Python, and Bash, optimizing system deployment, backup routines, and monitoring pipelines.</span>
</div>
</div>
</div>
<div class="resume-job">
<div class="resume-job-header">
<h3 class="resume-job-title">Project Engineer</h3>
<div class="resume-job-company">Anchor Point IT Solutions</div>
<div class="resume-job-period">December 2023 - June 2024</div>
</div>
<div class="resume-job-achievements">
<div class="resume-job-achievement">
<i class="fas fa-check-circle"></i>
<span>Executed 5 Microsoft 365 and SharePoint migrations with downtime reduced by 60%.</span>
</div>
<div class="resume-job-achievement">
<i class="fas fa-check-circle"></i>
<span>Implemented comprehensive security stack including BlueMira & DUO (Identity), SentinelOne (Endpoint), ConnectSecure (Network), and Email Mesh Security.</span>
</div>
<div class="resume-job-achievement">
<i class="fas fa-check-circle"></i>
<span>Reduced security incidents by 83% through security implementations and improved system updates by 60%.</span>
</div>
<div class="resume-job-achievement">
<i class="fas fa-check-circle"></i>
<span>Managed approximately 235 clients with environment sizes ranging from 30 to 1000 people.</span>
</div>
</div>
</div>
<div class="resume-job">
<div class="resume-job-header">
<h3 class="resume-job-title">Interim Virtual Chief Security Officer</h3>
<div class="resume-job-company">Technology Response Team, LLC</div>
<div class="resume-job-period">August 2023 - September 2023</div>
</div>
<div class="resume-job-achievements">
<div class="resume-job-achievement">
<i class="fas fa-check-circle"></i>
<span>Served as temporary VCSO for ~120 clients, conducting penetration testing using BURP Professional.</span>
</div>
<div class="resume-job-achievement">
<i class="fas fa-check-circle"></i>
<span>Managed enterprise security stack deployment including Blackpoint & Webroot (Endpoint), DNSFilter (Network), and ThreatLocker (Application Control).</span>
</div>
<div class="resume-job-achievement">
<i class="fas fa-check-circle"></i>
<span>Administered Azure AD security policies and MFA enforcement, reducing monthly vulnerabilities by at least 20%.</span>
</div>
</div>
</div>
<div class="resume-job">
<div class="resume-job-header">
<h3 class="resume-job-title">Network Engineer II</h3>
<div class="resume-job-company">NOVUS Professional Services, Inc.</div>
<div class="resume-job-period">August 2022 - March 2023</div>
</div>
<div class="resume-job-achievements">
<div class="resume-job-achievement">
<i class="fas fa-check-circle"></i>
<span>Designed and implemented a WiFi testing cage for remote firmware testing of router models (Wave2, WiFi6).</span>
</div>
<div class="resume-job-achievement">
<i class="fas fa-check-circle"></i>
<span>Developed Python automation for Plume device registration and Ansible scripts for network tasks.</span>
</div>
<div class="resume-job-achievement">
<i class="fas fa-check-circle"></i>
<span>Managed RF testing and signal verification across 9 headends and maintained network connectivity for ~100 routers across two sites.</span>
</div>
</div>
</div>
<div class="resume-job">
<div class="resume-job-header">
<h3 class="resume-job-title">Field Engineer</h3>
<div class="resume-job-company">COMPUTEK Dental Systems</div>
<div class="resume-job-period">December 2021 - August 2022</div>
</div>
<div class="resume-job-achievements">
<div class="resume-job-achievement">
<i class="fas fa-check-circle"></i>
<span>Managed IT infrastructure for 300+ dental practices (3700+ workstations, ~300 Windows Servers).</span>
</div>
<div class="resume-job-achievement">
<i class="fas fa-check-circle"></i>
<span>Developed VSA Deployer application (Kaseya VSA RMM) for agent installation, reducing deployment time by 80%.</span>
</div>
<div class="resume-job-achievement">
<i class="fas fa-check-circle"></i>
<span>Maintained server, Hyper-V VM, and MySQL/MSSQL backups using N-Able Backups, Windows Server Backups and AIS.</span>
</div>
</div>
</div>
<div class="resume-job">
<div class="resume-job-header">
<h3 class="resume-job-title">End-to-End Systems Engineer</h3>
<div class="resume-job-company">Lockheed Martin</div>
<div class="resume-job-period">June 2018 - December 2019</div>
</div>
<div class="resume-job-achievements">
<div class="resume-job-achievement">
<i class="fas fa-check-circle"></i>
<span>Maintained 2 IRON databases (AIMS and RAPID) with ~1800 configurations each, ensuring 100% database accuracy.</span>
</div>
<div class="resume-job-achievement">
<i class="fas fa-check-circle"></i>
<span>Collaborated with engineering team to implement Remote Tracking Station (RTS) configurations.</span>
</div>
<div class="resume-job-achievement">
<i class="fas fa-check-circle"></i>
<span>Identified and documented an average of 27 critical defects every month.</span>
</div>
</div>
</div>
</div>
<!-- Skills Section -->
<div class="resume-section">
<h2 class="resume-section-title">Technical Skills</h2>
<div class="resume-skills">
<div class="resume-skill-category">
<h3 class="resume-skill-title">Cloud & Infrastructure</h3>
<div class="resume-skill-list">
<span class="resume-skill">Microsoft Azure</span>
<span class="resume-skill">Azure AD</span>
<span class="resume-skill">SharePoint</span>
<span class="resume-skill">Teams</span>
<span class="resume-skill">AWS</span>
<span class="resume-skill">EC2</span>
<span class="resume-skill">S3</span>
<span class="resume-skill">GCP</span>
<span class="resume-skill">VMware ESXi/vSphere</span>
<span class="resume-skill">Hyper-V</span>
<span class="resume-skill">Docker</span>
<span class="resume-skill">Kubernetes (K3s)</span>
<span class="resume-skill">ProxMox</span>
<span class="resume-skill">Traefik</span>
<span class="resume-skill">CI/CD</span>
</div>
</div>
<div class="resume-skill-category">
<h3 class="resume-skill-title">Networking</h3>
<div class="resume-skill-list">
<span class="resume-skill">LAN/WAN</span>
<span class="resume-skill">VPN</span>
<span class="resume-skill">OSPF</span>
<span class="resume-skill">EIGRP</span>
<span class="resume-skill">STP</span>
<span class="resume-skill">HSRP</span>
<span class="resume-skill">VTP</span>
<span class="resume-skill">IPv4/IPv6</span>
<span class="resume-skill">ACLs</span>
<span class="resume-skill">NAT/PAT</span>
<span class="resume-skill">DNS/DHCP</span>
<span class="resume-skill">VLANs</span>
<span class="resume-skill">QoS</span>
<span class="resume-skill">Cisco Routers</span>
<span class="resume-skill">Catalyst Switches</span>
<span class="resume-skill">ASA Firewalls</span>
<span class="resume-skill">UniFi Systems</span>
<span class="resume-skill">pfSense</span>
<span class="resume-skill">OPNsense</span>
</div>
</div>
<div class="resume-skill-category">
<h3 class="resume-skill-title">Programming/Scripting</h3>
<div class="resume-skill-list">
<span class="resume-skill">Python</span>
<span class="resume-skill">JavaScript (Node.js)</span>
<span class="resume-skill">PowerShell</span>
<span class="resume-skill">Bash</span>
<span class="resume-skill">C/C++</span>
<span class="resume-skill">SQL</span>
<span class="resume-skill">MySQL/MSSQL</span>
<span class="resume-skill">AutoHotkey</span>
<span class="resume-skill">Ansible</span>
</div>
</div>
<div class="resume-skill-category">
<h3 class="resume-skill-title">Security</h3>
<div class="resume-skill-list">
<span class="resume-skill">Penetration Testing</span>
<span class="resume-skill">BURP Professional</span>
<span class="resume-skill">SentinelOne</span>
<span class="resume-skill">Blackpoint</span>
<span class="resume-skill">Webroot</span>
<span class="resume-skill">ThreatLocker</span>
<span class="resume-skill">Zero-Trust Architecture</span>
<span class="resume-skill">HIPAA Compliance</span>
<span class="resume-skill">BlueMira</span>
<span class="resume-skill">DUO</span>
<span class="resume-skill">DNSFilter</span>
<span class="resume-skill">Email Mesh Security</span>
<span class="resume-skill">MFA</span>
</div>
</div>
<div class="resume-skill-category">
<h3 class="resume-skill-title">Operating Systems</h3>
<div class="resume-skill-list">
<span class="resume-skill">Windows Server</span>
<span class="resume-skill">Active Directory</span>
<span class="resume-skill">Group Policy</span>
<span class="resume-skill">Exchange Server</span>
<span class="resume-skill">Linux</span>
<span class="resume-skill">Ubuntu</span>
<span class="resume-skill">CentOS</span>
<span class="resume-skill">Debian</span>
<span class="resume-skill">Fedora</span>
<span class="resume-skill">Kali Linux</span>
<span class="resume-skill">Cisco IOS</span>
</div>
</div>
<div class="resume-skill-category">
<h3 class="resume-skill-title">GIS & Data Science</h3>
<div class="resume-skill-list">
<span class="resume-skill">Geospatial Mapping</span>
<span class="resume-skill">GeoPandas</span>
<span class="resume-skill">GDAL/OGR</span>
<span class="resume-skill">KML Generation</span>
<span class="resume-skill">Data Visualization</span>
<span class="resume-skill">Machine Learning</span>
<span class="resume-skill">TensorFlow</span>
<span class="resume-skill">PyTorch</span>
<span class="resume-skill">Scikit-learn</span>
<span class="resume-skill">Pandas</span>
<span class="resume-skill">NumPy</span>
<span class="resume-skill">Matplotlib</span>
<span class="resume-skill">Seaborn</span>
</div>
</div>
<div class="resume-skill-category">
<h3 class="resume-skill-title">Management & PSA Tools</h3>
<div class="resume-skill-list">
<span class="resume-skill">N-able N-central</span>
<span class="resume-skill">Kaseya VSA</span>
<span class="resume-skill">ConnectWise Automate</span>
<span class="resume-skill">ConnectWise PSA</span>
<span class="resume-skill">PRTG</span>
<span class="resume-skill">SolarWinds</span>
<span class="resume-skill">Addigy</span>
<span class="resume-skill">ImmyBot</span>
<span class="resume-skill">Commit Ticket CRM</span>
</div>
</div>
</div>
</div>
<!-- Education Section -->
<div class="resume-section">
<h2 class="resume-section-title">Education</h2>
<div class="resume-education">
<h3 class="resume-education-title">Bachelor of Science, Computer Science</h3>
<div class="resume-education-institution">Western Governors University</div>
<div class="resume-education-period">June 2019 - April 2023</div>
<div class="resume-job-achievements">
<div class="resume-job-achievement">
<i class="fas fa-award"></i>
<span>Activities and societies: Sigma Alpha Pi Honors Society (The National Society of Leadership and Success)</span>
</div>
</div>
<div class="resume-education-skills">
<strong>Skills:</strong> Python (Programming Language) · Project Management · Machine Learning · Team Leadership
</div>
</div>
<div class="resume-education">
<h3 class="resume-education-title">Cyber Ops</h3>
<div class="resume-education-institution">Cisco Networking Academy</div>
<div class="resume-education-period">2018</div>
<div class="resume-education-skills">
<strong>Skills:</strong> Networking · Cyber-security · Cisco Technologies
</div>
</div>
<div class="resume-education">
<h3 class="resume-education-title">Computer Science and Innovation</h3>
<div class="resume-education-institution">University of Colorado Colorado Springs (UCCS)</div>
<div class="resume-education-period">January 2017 - December 2017</div>
<div class="resume-education-grade">Grade: 4.0</div>
<div class="resume-education-skills">
<strong>Skills:</strong> C++ · Team Leadership
</div>
</div>
<div class="resume-education">
<h3 class="resume-education-title">Associate's degree, General Studies</h3>
<div class="resume-education-institution">Pikes Peak State College</div>
<div class="resume-education-period">2015 - 2018</div>
<div class="resume-education-grade">Grade: 4.0</div>
<div class="resume-job-achievements">
<div class="resume-job-achievement">
<i class="fas fa-award"></i>
<span>Activities and societies: Phi Theta Kappa Honor Society</span>
</div>
</div>
<div class="resume-education-skills">
<strong>Skills:</strong> Linux · Virtual Server · C++ · System Administration · Wireless
</div>
</div>
<div class="resume-education">
<h3 class="resume-education-title">Associate's Degree, Computer Wide Area Networks</h3>
<div class="resume-education-institution">Front Range Community College</div>
<div class="resume-education-period">2014 - 2016</div>
<div class="resume-education-grade">Grade: 3.87</div>
<div class="resume-job-achievements">
<div class="resume-job-achievement">
<i class="fas fa-award"></i>
<span>Activities and societies: Phi Theta Kappa Honor Society</span>
</div>
<div class="resume-job-achievement">
<i class="fas fa-award"></i>
<span>Magna Cum Laude honors</span>
</div>
</div>
<div class="resume-education-skills">
<strong>Skills:</strong> Virtual Server · C++ · Networking · Wireless
</div>
</div>
</div>
<!-- Certifications Section -->
<div class="resume-section">
<h2 class="resume-section-title">Certifications</h2>
<div class="resume-job-achievements">
<div class="resume-job-achievement">
<i class="fas fa-certificate"></i>
<span>Project+ (CompTIA)</span>
</div>
<div class="resume-job-achievement">
<i class="fas fa-certificate"></i>
<span>Network+ (FRCC)</span>
</div>
<div class="resume-job-achievement">
<i class="fas fa-certificate"></i>
<span>A+ (FRCC)</span>
</div>
<div class="resume-job-achievement">
<i class="fas fa-certificate"></i>
<span>CCNA Cyber Ops (2021)</span>
</div>
<div class="resume-job-achievement">
<i class="fas fa-certificate"></i>
<span>CCNA Routing & Switching (2021)</span>
</div>
<div class="resume-job-achievement">
<i class="fas fa-certificate"></i>
<span>Virtual Cyber Security Officer Training (vCSO Advanced)</span>
</div>
</div>
</div>
<!-- Projects Section -->
<div class="resume-section">
<h2 class="resume-section-title">Notable Projects</h2>
<div class="resume-projects">
<div class="resume-project">
<h3 class="resume-project-title">Full-Access Wi-Fi Testing Cage</h3>
<p>Designed and implemented a comprehensive testing environment for router firmware validation with remote access capabilities. Engineered cable modem/SONU configurations for MAP-T and dual-stack testing with automated relay and RF switcher control.</p>
<div class="resume-project-tech">
<span class="resume-project-tech-item">RF Engineering</span>
<span class="resume-project-tech-item">Network Testing</span>
<span class="resume-project-tech-item">CAD Prototyping</span>
<span class="resume-project-tech-item">Serial Interface</span>
<span class="resume-project-tech-item">Automation</span>
</div>
</div>
<div class="resume-project">
<h3 class="resume-project-title">TerraTracer GIS Platform</h3>
<p>A GIS mapping platform used by mining claim prospectors to automate boundary plotting and compliance verification, reducing manual research by 85% and improving claim success rates by 40%.</p>
<div class="resume-project-tech">
<span class="resume-project-tech-item">Python</span>
<span class="resume-project-tech-item">Node.js</span>
<span class="resume-project-tech-item">GeoPandas</span>
<span class="resume-project-tech-item">KML</span>
<span class="resume-project-tech-item">GDAL/OGR</span>
</div>
</div>
<div class="resume-project">
<h3 class="resume-project-title">VSA Deployer</h3>
<p>Custom application for streamlining Kaseya VSA RMM agent installation, reducing deployment time by 80% across dental practice environments. Implemented for 300+ practices with 3700+ workstations.</p>
<div class="resume-project-tech">
<span class="resume-project-tech-item">PowerShell</span>
<span class="resume-project-tech-item">AutoHotkey</span>
<span class="resume-project-tech-item">RMM</span>
<span class="resume-project-tech-item">Kaseya VSA</span>
</div>
</div>
<div class="resume-project">
<h3 class="resume-project-title">AI-Driven Car Price Prediction</h3>
<p>Developed machine learning model for predicting used car prices with over 90% accuracy using Random Forest Regression and comprehensive feature engineering.</p>
<div class="resume-project-tech">
<span class="resume-project-tech-item">Python</span>
<span class="resume-project-tech-item">Scikit-learn</span>
<span class="resume-project-tech-item">Pandas</span>
<span class="resume-project-tech-item">Random Forest</span>
<span class="resume-project-tech-item">Jupyter</span>
</div>
</div>
</div>
</div>
<div class="resume-download">
<a href="files/daniel-laforce-resume.pdf" class="btn btn-primary" download>
<i class="fas fa-download btn-icon"></i>
Download Full Resume (PDF)
</a>
</div>
</div>
<!-- Footer -->
<footer class="footer">
<div class="container">
<div class="footer-content">
<div class="footer-logo">
<span class="logo-text">Argobox</span>
<span class="logo-dot">.com</span>
</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#experience">Experience</a>
<a href="index.html#contact">Contact</a>
</div>
<div class="footer-social">
<a href="https://www.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>
</div>
<div class="footer-bottom">
<p>&copy; <span id="current-year"></span> All rights reserved. Inovin LLC</p>
</div>
</div>
</footer>
<!-- JavaScript -->
<script src="script.js"></script>
</body>
</html>

412
script.js
View File

@ -7,78 +7,51 @@ document.addEventListener('DOMContentLoaded', function() {
// Initialize all website functionality
initNavigation();
initParticlesAndIcons();
initRoleRotation();
initTerminalTyping();
initSolutionsCarousel();
initScrollReveal();
updateMetrics();
updateYear();
// Initialize form handling
const contactForm = document.getElementById('contact-form');
if (contactForm) {
initFormHandling(contactForm);
}
});
/**
* Set up navigation functionality - mobile menu and scroll spy
*/
function initNavigation() {
// 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');
menuToggle.setAttribute('aria-expanded',
menuToggle.getAttribute('aria-expanded') === 'true' ? 'false' : 'true');
menuToggle.addEventListener('click', () => {
navMenu.classList.toggle('show');
const icon = menuToggle.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');
}
});
}
// Navigation scroll spy
const sections = document.querySelectorAll('section[id]');
// Scroll spy for navigation
window.addEventListener('scroll', () => {
const sections = document.querySelectorAll('section');
const navLinks = document.querySelectorAll('.nav-link');
function updateActiveNavLink() {
let scrollPosition = window.scrollY + 100;
let current = '';
sections.forEach(section => {
const sectionTop = section.offsetTop;
const sectionHeight = section.offsetHeight;
const sectionId = section.getAttribute('id');
if (window.scrollY >= sectionTop - 100) {
current = section.getAttribute('id');
}
});
if (scrollPosition >= sectionTop && scrollPosition < sectionTop + sectionHeight) {
navLinks.forEach(link => {
link.classList.remove('active');
if (link.getAttribute('href') === `#${sectionId}`) {
if (link.getAttribute('href').substring(1) === current) {
link.classList.add('active');
}
});
}
});
}
// Navbar style change on scroll
const navbar = document.querySelector('.navbar');
function updateNavbarStyle() {
if (window.scrollY > 50) {
navbar?.classList.add('scrolled');
} else {
navbar?.classList.remove('scrolled');
}
}
window.addEventListener('scroll', () => {
updateActiveNavLink();
updateNavbarStyle();
});
// Initial call to set correct states
updateActiveNavLink();
updateNavbarStyle();
}
/**
@ -97,334 +70,44 @@ function createBackgroundParticles() {
if (!particlesContainer) return;
// Clear existing particles
particlesContainer.innerHTML = '';
for (let i = 0; i < 40; i++) {
// Create particles
for (let i = 0; i < 50; i++) {
const particle = document.createElement('div');
particle.classList.add('particle');
// Random size, opacity, and position
const size = Math.random() * 4 + 1;
const opacity = Math.random() * 0.3 + 0.1;
// Random size between 2 and 6px
const size = Math.random() * 4 + 2;
particle.style.width = `${size}px`;
particle.style.height = `${size}px`;
particle.style.opacity = opacity;
// Position randomly with some clustering toward top areas
const xPos = Math.random() * 100;
const yPos = Math.random() * 100;
// Random position
particle.style.left = `${Math.random() * 100}%`;
particle.style.top = `${Math.random() * 100}%`;
particle.style.left = `${xPos}%`;
particle.style.top = `${yPos}%`;
// Random opacity between 0.1 and 0.3
particle.style.opacity = (Math.random() * 0.2 + 0.1).toString();
// Animation properties
particle.style.animationDuration = `${Math.random() * 20 + 10}s`;
particle.style.animationDelay = `${Math.random() * 5}s`;
// Add particle animation
particle.style.animation = `particle-float ${Math.random() * 20 + 10}s linear infinite`;
particle.style.animation = `float-particle ${Math.random() * 20 + 10}s linear infinite`;
particle.style.animationDelay = `${Math.random() * 10}s`;
particlesContainer.appendChild(particle);
}
}
/**
* Create floating tech icons in the background
*/
function createFloatingIcons() {
const iconContainer = document.getElementById('floating-icons');
if (!iconContainer) return;
iconContainer.innerHTML = '';
// Tech-related unicode symbols and fontawesome classes
const icons = [
'⚙️', '💻', '🔒', '🔌', '🌐', '☁️', '📊',
'fa-server', 'fa-network-wired', 'fa-database',
'fa-code-branch', 'fa-cloud', 'fa-shield-alt'
];
for (let i = 0; i < 12; i++) {
const icon = document.createElement('div');
icon.classList.add('floating-icon');
const iconType = icons[Math.floor(Math.random() * icons.length)];
// Handle both unicode and font awesome
if (iconType.startsWith('fa-')) {
const faIcon = document.createElement('i');
faIcon.className = `fas ${iconType}`;
icon.appendChild(faIcon);
} else {
icon.textContent = iconType;
}
// Random size and position
const size = Math.random() * 24 + 16;
icon.style.fontSize = `${size}px`;
// Position
icon.style.left = `${Math.random() * 100}%`;
icon.style.bottom = `-50px`;
// Animation
icon.style.animationDuration = `${Math.random() * 30 + 20}s`;
icon.style.animationDelay = `${Math.random() * 10}s`;
iconContainer.appendChild(icon);
}
}
/**
* Initialize role rotation in the hero section
*/
function initRoleRotation() {
const roles = document.querySelectorAll('.role');
const descriptionElement = document.getElementById('role-description');
if (roles.length === 0 || !descriptionElement) return;
let currentRole = 0;
function rotateRoles() {
// Hide current role
roles[currentRole].classList.remove('active');
// Move to next role
currentRole = (currentRole + 1) % roles.length;
// Show new role
roles[currentRole].classList.add('active');
// Update description text
const newDescription = roles[currentRole].getAttribute('data-description');
if (newDescription) {
descriptionElement.textContent = newDescription;
// Animate the description change
descriptionElement.style.opacity = '0';
descriptionElement.style.transform = 'translateY(10px)';
setTimeout(() => {
descriptionElement.style.opacity = '1';
descriptionElement.style.transform = 'translateY(0)';
}, 50);
}
}
// Set initial role to active
roles[0].classList.add('active');
// Initialize with the first description
const initialDescription = roles[0].getAttribute('data-description');
if (initialDescription && descriptionElement) {
descriptionElement.textContent = initialDescription;
}
// Start rotation with delay
setInterval(rotateRoles, 5000);
}
/**
* Initialize terminal typing animation in the hero section
* Initialize terminal typing animation
*/
function initTerminalTyping() {
const terminalText = document.getElementById('terminal-text');
if (!terminalText) return;
const terminalMessages = [
"> Ready for deployment...",
"> Reducing operational costs by 30%",
"> Improving system reliability to 99.9%",
"> Accelerating digital transformation",
"> Enhancing security compliance",
"> Streamlining IT workflows",
"> Optimizing infrastructure performance",
"> Implementing best practices",
"> Supporting business objectives"
];
let currentMessage = 0;
function typeMessage(message, index = 0) {
if (index < message.length) {
terminalText.textContent = message.substring(0, index + 1);
setTimeout(() => typeMessage(message, index + 1), 50 + Math.random() * 50);
} else {
// Wait before clearing and typing next message
setTimeout(clearAndTypeNext, 3000);
const cursor = document.querySelector('.cursor');
if (cursor) {
setInterval(() => {
cursor.style.opacity = cursor.style.opacity === '0' ? '1' : '0';
}, 600);
}
}
function clearAndTypeNext() {
// Clear the current text with a backspace effect
const currentText = terminalText.textContent;
function backspace(length = currentText.length) {
if (length > 0) {
terminalText.textContent = currentText.substring(0, length - 1);
setTimeout(() => backspace(length - 1), 20);
} else {
// Move to next message
currentMessage = (currentMessage + 1) % terminalMessages.length;
setTimeout(() => typeMessage(terminalMessages[currentMessage]), 500);
}
}
backspace();
}
// Start the typing animation with the first message
typeMessage(terminalMessages[0]);
}
/**
* Initialize the solutions carousel
*/
function initSolutionsCarousel() {
const slides = document.querySelectorAll('.solution-slide');
const dots = document.querySelectorAll('.slider-dot');
if (slides.length === 0 || dots.length === 0) return;
let currentSlide = 0;
let slideInterval;
function showSlide(index) {
// Hide all slides
slides.forEach(slide => slide.classList.remove('active'));
dots.forEach(dot => dot.classList.remove('active'));
// Show selected slide
slides[index].classList.add('active');
dots[index].classList.add('active');
currentSlide = index;
}
function nextSlide() {
const next = (currentSlide + 1) % slides.length;
showSlide(next);
}
// Add click events to dots
dots.forEach((dot, index) => {
dot.addEventListener('click', () => {
clearInterval(slideInterval);
showSlide(index);
// Restart automatic rotation
slideInterval = setInterval(nextSlide, 5000);
});
});
// Start automatic rotation
slideInterval = setInterval(nextSlide, 5000);
// Show first slide initially
showSlide(0);
}
/**
* Add scroll reveal animations to elements
*/
function initScrollReveal() {
const revealElements = document.querySelectorAll('.section-header, .service-card, .project-card, .lab-card, .timeline-item, .contact-item');
revealElements.forEach(element => {
element.classList.add('reveal');
});
function checkReveal() {
revealElements.forEach(element => {
const elementTop = element.getBoundingClientRect().top;
const elementVisible = 150;
if (elementTop < window.innerHeight - elementVisible) {
element.classList.add('active');
}
});
}
// Initial check
checkReveal();
// Check on scroll
window.addEventListener('scroll', checkReveal);
}
/**
* Update metrics values periodically to simulate live data
*/
function updateMetrics() {
const metrics = {
'CPU Usage': { min: 30, max: 60, element: null },
'Memory': { min: 45, max: 70, element: null },
'Storage': { min: 60, max: 75, element: null },
'Network': { min: 15, max: 40, element: null }
};
// Get all metric elements
document.querySelectorAll('.metric').forEach(metric => {
const nameElement = metric.querySelector('.metric-name');
if (nameElement && metrics[nameElement.textContent]) {
metrics[nameElement.textContent].element = metric;
}
});
function updateMetricValues() {
Object.keys(metrics).forEach(key => {
const metric = metrics[key];
if (!metric.element) return;
const valueEl = metric.element.querySelector('.metric-value');
const progressEl = metric.element.querySelector('.metric-progress');
if (valueEl && progressEl) {
const newValue = Math.floor(Math.random() * (metric.max - metric.min)) + metric.min;
valueEl.textContent = `${newValue}%`;
progressEl.style.width = `${newValue}%`;
}
});
}
// Update metrics every 5 seconds
setInterval(updateMetricValues, 5000);
}
/**
* Initialize contact form handling
*/
function initFormHandling(form) {
form.addEventListener('submit', async function(e) {
e.preventDefault();
const submitButton = form.querySelector('button[type="submit"]');
const originalButtonText = submitButton.innerHTML;
submitButton.innerHTML = '<i class="fas fa-spinner fa-spin"></i> Sending...';
submitButton.disabled = true;
try {
// Simulated form submission - in production replace with actual API call
// const formData = new FormData(form);
// const formValues = Object.fromEntries(formData.entries());
// Simulated API response delay
await new Promise(resolve => setTimeout(resolve, 1500));
// Success message
alert('Thank you for your message! I will get back to you soon.');
form.reset();
} catch (error) {
console.error('Error:', error);
alert('Failed to send message. Please try again or contact me directly via email.');
} finally {
submitButton.innerHTML = originalButtonText;
submitButton.disabled = false;
}
});
}
/**
@ -436,24 +119,3 @@ function updateYear() {
yearElement.textContent = new Date().getFullYear();
}
}
/**
* Utility function to add particle float animation
*/
document.addEventListener('DOMContentLoaded', function() {
// Initialize all website functionality
initNavigation();
initParticlesAndIcons();
initRoleRotation(); // Updated function
initTerminalTyping(); // Updated function
initSolutionsCarousel(); // Updated function
initScrollReveal();
updateMetrics();
updateYear();
// Initialize form handling
const contactForm = document.getElementById('contact-form');
if (contactForm) {
initFormHandling(contactForm);
}
});

1188
styles.css

File diff suppressed because it is too large Load Diff