v0.0.1: project initialization
|
|
@ -0,0 +1,8 @@
|
|||
# Queue-North-Website — Development Log
|
||||
|
||||
## v0.0.1 — 2026-05-11
|
||||
|
||||
**Ripley** — Project initialized
|
||||
- Created project directory at `/home/kaspa/.openclaw/Projects/Queue-North-Website/`
|
||||
- Set up PROJECT.md, STRUCTURE.md, FUTURE.md, HISTORY.md, DEVELOPMENT_LOG.md
|
||||
- Git repo not yet initialized (awaiting first code)
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
# Queue-North-Website — Planning
|
||||
|
||||
## Next Items
|
||||
*Awaiting project requirements from _null.*
|
||||
|
||||
---
|
||||
|
||||
*Add items here as they are defined. Priority levels: CRITICAL, HIGH, MEDIUM, LOW*
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
# Queue-North-Website — Changelog
|
||||
|
||||
## v0.0.1
|
||||
|
||||
### Added
|
||||
- Project initialized with PROJECT.md, STRUCTURE.md, FUTURE.md, HISTORY.md, DEVELOPMENT_LOG.md
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
# Queue North Website
|
||||
|
||||
## Overview
|
||||
Project: Queue-North-Website
|
||||
Created: 2026-05-11
|
||||
Status: Active
|
||||
|
||||
## Description
|
||||
Website project for Queue North. Details TBD.
|
||||
|
||||
## Directory Structure
|
||||
- `/home/kaspa/.openclaw/Projects/Queue-North-Website/` — Project root
|
||||
- All project files live here
|
||||
|
||||
## Git
|
||||
- **Branch:** `dev` (working), `main` (stable)
|
||||
- **Remote:** `ssh://forgejo/null/Queue-North-Website.git`
|
||||
|
||||
## Conventions
|
||||
- Follow AGENTS.md for agent dispatch protocol
|
||||
- Ripley coordinates, Neo codes, Scarlett styles, Bishop verifies, Hudson secures
|
||||
- All agents read STRUCTURE.md before starting tasks
|
||||
- Ripley owns git — no agent touches git directly
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
# Queue-North-Website — Project Structure
|
||||
|
||||
## Agent Roles
|
||||
|
||||
| Agent | Role | Focus Area |
|
||||
|-------|------|------------|
|
||||
| Neo | Backend Coder | Server code, APIs, database, build system |
|
||||
| Scarlett | UI/Design | Frontend components, Tailwind CSS, layout, visuals |
|
||||
| Bishop | Verification | Build, runtime tests, documentation, version bumps |
|
||||
| Private_Hudson | Security | Auth, data exposure, input validation, dependency audit |
|
||||
| Ripley | Coordinator | Git, deploy, pipeline, task dispatch |
|
||||
|
||||
## Code Ownership
|
||||
TBD — will be defined as the project takes shape.
|
||||
|
||||
## Key Files
|
||||
- `PROJECT.md` — Project overview and conventions
|
||||
- `STRUCTURE.md` — This file. Agent roles, code ownership, critical paths
|
||||
- `FUTURE.md` — Planning doc (what to build next)
|
||||
- `HISTORY.md` — Version changelog
|
||||
- `DEVELOPMENT_LOG.md` — Agent activity log
|
||||
|
||||
## Cross-Cutting Concerns
|
||||
- All agents must read this file before starting any task
|
||||
- All agents report back to Ripley — no agent-to-agent handoffs
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 288 288">
|
||||
<defs>
|
||||
<style>
|
||||
.cls-1 {
|
||||
fill: #fff;
|
||||
}
|
||||
</style>
|
||||
</defs>
|
||||
<path class="cls-1" d="M172.73,132.13h-21.87l-5.04,9.59c-.69,1.49-1.83,3.16-1.83,3.16h-.23s-1.03-1.68-1.83-3.16l-5.04-9.59h-21.85l17.17,26.51-17.1,26.54h21.48l5.8-11.08c.57-1.03,1.37-3.02,1.37-3.02h.23s.8,1.99,1.37,3.02l5.89,11.08h21.5l-17.1-26.54,17.07-26.51h0Z"/>
|
||||
<path class="cls-1" d="M75.88,171.67c-6.06,0-10.85-4.67-10.85-10.47,0-4.92,2.65-8.71,4.8-10.98,8.83,4.04,16.91,7.07,16.91,12.24,0,5.93-4.16,9.21-10.85,9.21h0ZM76.51,117.28c5.93,0,9.47,3.28,9.47,8.33,0,5.55-2.4,9.72-3.15,11.11-7.95-3.41-14.51-6.44-14.51-12.37,0-3.91,2.52-7.07,8.2-7.07h0ZM98.72,144.54c.88-1.14,8.83-10.85,8.83-20.57,0-16.79-13.76-26.12-30.54-26.12-21.08,0-30.29,12.87-30.29,26,0,7.7,3.41,13.13,8.2,17.29-2.78,2.15-12.49,10.35-12.49,21.96,0,14.39,11.48,28.02,33.44,28.02s33.44-13.76,33.44-27.51c0-9.09-4.54-14.89-10.6-19.06h0Z"/>
|
||||
<path class="cls-1" d="M211.7,171.67c-6.06,0-10.85-4.67-10.85-10.47,0-4.92,2.65-8.71,4.8-10.98,8.83,4.04,16.91,7.07,16.91,12.24,0,5.93-4.17,9.21-10.85,9.21h0ZM212.33,117.28c5.93,0,9.47,3.28,9.47,8.33,0,5.55-2.4,9.72-3.15,11.11-7.95-3.41-14.51-6.44-14.51-12.37,0-3.91,2.52-7.07,8.2-7.07h0ZM234.54,144.54c.88-1.14,8.83-10.85,8.83-20.57,0-16.79-13.76-26.12-30.54-26.12-21.08,0-30.29,12.87-30.29,26,0,7.7,3.41,13.13,8.2,17.29-2.78,2.15-12.5,10.35-12.5,21.96,0,14.39,11.48,28.02,33.44,28.02s33.44-13.76,33.44-27.51c0-9.09-4.54-14.89-10.6-19.06h0Z"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.6 KiB |
|
After Width: | Height: | Size: 2.2 MiB |
|
After Width: | Height: | Size: 2.0 MiB |
|
After Width: | Height: | Size: 1.2 MiB |
|
After Width: | Height: | Size: 1.1 MiB |
|
After Width: | Height: | Size: 355 KiB |
|
After Width: | Height: | Size: 2.2 MiB |
|
After Width: | Height: | Size: 2.1 MiB |
|
After Width: | Height: | Size: 1.2 MiB |
|
After Width: | Height: | Size: 1.9 MiB |
|
After Width: | Height: | Size: 1.4 MiB |
|
After Width: | Height: | Size: 2.0 MiB |
|
After Width: | Height: | Size: 1.9 MiB |
|
After Width: | Height: | Size: 2.3 MiB |
|
After Width: | Height: | Size: 1.6 MiB |
|
After Width: | Height: | Size: 2.2 MiB |
|
After Width: | Height: | Size: 17 KiB |
|
After Width: | Height: | Size: 707 B |
|
After Width: | Height: | Size: 29 KiB |
|
After Width: | Height: | Size: 32 KiB |
|
After Width: | Height: | Size: 50 KiB |
|
After Width: | Height: | Size: 1.9 KiB |
|
After Width: | Height: | Size: 3.6 KiB |
|
After Width: | Height: | Size: 152 KiB |
|
After Width: | Height: | Size: 5.7 KiB |
|
After Width: | Height: | Size: 11 KiB |
|
After Width: | Height: | Size: 346 KiB |
|
After Width: | Height: | Size: 300 KiB |
|
After Width: | Height: | Size: 244 KiB |
|
After Width: | Height: | Size: 1.8 MiB |
|
After Width: | Height: | Size: 1.9 MiB |
|
|
@ -0,0 +1,768 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<title>Queue North Technologies</title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<meta
|
||||
name="description"
|
||||
content="Queue North Technologies is an official 8x8 Certified Partner delivering UCaaS, Contact Center, deployment, and managed lifecycle support for SMB and enterprise organizations."
|
||||
/>
|
||||
<link rel="stylesheet" href="styles.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=Inter:wght@300;400;500;600;700&display=swap" rel="stylesheet">
|
||||
|
||||
<!-- Favicons -->
|
||||
<link rel="icon" type="image/png" sizes="16x16" href="assets/icons/logo16.png">
|
||||
<link rel="icon" type="image/png" sizes="32x32" href="assets/icons/logo32.png">
|
||||
<link rel="icon" type="image/png" sizes="48x48" href="assets/icons/logo48.png">
|
||||
<link rel="icon" type="image/png" sizes="96x96" href="assets/icons/logo96.png">
|
||||
<link rel="apple-touch-icon" sizes="180x180" href="assets/icons/logo180.png">
|
||||
<link rel="icon" type="image/png" sizes="192x192" href="assets/icons/logo192.png">
|
||||
<link rel="icon" type="image/png" sizes="512x512" href="assets/icons/logo512.png">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<header class="site-header">
|
||||
<div class="logo">
|
||||
<a href="#home" data-route="home" class="logo-link" aria-label="Queue North Technologies Home">
|
||||
<img src="assets/logo2.png" alt="Queue North Technologies Logo" />
|
||||
</a>
|
||||
</div>
|
||||
<nav id="primary-navigation" class="site-nav" aria-label="Primary">
|
||||
<a href="#home" data-route="home">Home</a>
|
||||
<a href="#about" data-route="about">About</a>
|
||||
|
||||
<div class="nav-dropdown">
|
||||
<button class="nav-dropdown-toggle" type="button" data-route="services" aria-haspopup="true" aria-expanded="false">Services</button>
|
||||
<div class="nav-dropdown-menu" role="menu" aria-label="Services menu">
|
||||
<a href="#services" data-route="services" role="menuitem">All Services</a>
|
||||
<a href="#unified-communications" data-route="unified-communications" role="menuitem">Unified Communications</a>
|
||||
<a href="#contact-center" data-route="contact-center" role="menuitem">Contact Center</a>
|
||||
<a href="#managed-support" data-route="managed-support" role="menuitem">Managed Services & Support</a>
|
||||
<a href="#consulting-training" data-route="consulting-training" role="menuitem">Consulting & Training</a>
|
||||
<a href="#infrastructure-cabling" data-route="infrastructure-cabling" role="menuitem">Infrastructure Cabling</a>
|
||||
<a href="#wireless-access" data-route="wireless-access" role="menuitem">Wireless Access</a>
|
||||
<a href="#local-networking" data-route="local-networking" role="menuitem">Local Networking</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<a href="#8x8" data-route="eightx8">8x8</a>
|
||||
|
||||
<div class="nav-dropdown">
|
||||
<button class="nav-dropdown-toggle" type="button" data-route="industries" aria-haspopup="true" aria-expanded="false">Industries</button>
|
||||
<div class="nav-dropdown-menu" role="menu" aria-label="Industries menu">
|
||||
<a href="#industries" data-route="industries" role="menuitem">All Industries</a>
|
||||
<a href="#healthcare" data-route="healthcare" role="menuitem">Healthcare</a>
|
||||
<a href="#retail" data-route="retail" role="menuitem">Retail</a>
|
||||
<a href="#manufacturing" data-route="manufacturing" role="menuitem">Manufacturing</a>
|
||||
<a href="#education-finance" data-route="education-finance" role="menuitem">Education & Finance</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<a href="#contact" data-route="contact">Contact Us</a>
|
||||
<a href="#support" data-route="support">Support</a>
|
||||
</nav>
|
||||
</header>
|
||||
|
||||
<main class="app">
|
||||
<!-- HOME -->
|
||||
<section id="page-home" class="page active" data-page="home" aria-labelledby="home-title">
|
||||
<div class="hero hero-split">
|
||||
<div class="hero-inner hero-split-inner">
|
||||
|
||||
<div class="hero-content">
|
||||
<h1 id="home-title">UCaaS & Contact Center Experts</h1>
|
||||
<p>
|
||||
Queue North Technologies is an official 8x8 Certified Partner holding Sales, Sales Engineer, Build, Deployment, and Support Certifications.
|
||||
We design, implement, and operate secure, scalable communication environments for SMB and enterprise organizations.
|
||||
</p>
|
||||
|
||||
<div class="hero-actions">
|
||||
<button id="cta-consultation" class="primary-btn">Request a Consultation</button>
|
||||
</div>
|
||||
|
||||
<div class="hero-trust">
|
||||
<span>Official 8x8 Certified Partner</span>
|
||||
<span>Veteran Owned</span>
|
||||
<span>25+ Years Experience</span>
|
||||
<span>SMB to Enterprise</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- IMAGE AREA (real image, no visible box) -->
|
||||
<div class="hero-media" aria-label="Homepage visual">
|
||||
<img
|
||||
class="hero-photo"
|
||||
src="assets/hero-tech.png"
|
||||
alt="Technician working in a data center"
|
||||
loading="eager"
|
||||
decoding="async"
|
||||
/>
|
||||
|
||||
<!-- Rotating phrases + final lockup (overlayed on the image, bottom-left) -->
|
||||
<div class="hero-media-overlay" aria-hidden="true">
|
||||
<div class="hero-rotator">
|
||||
<span id="hero-rotator-text" class="hero-rotator-text"></span>
|
||||
</div>
|
||||
|
||||
<div id="hero-lockup" class="hero-lockup hero-lockup-subtitle is-hidden">
|
||||
<div class="hero-brand">Queue North</div>
|
||||
<div>Where Stability Meets Direction</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Keep only a tight “why us” summary on Home -->
|
||||
<section class="section">
|
||||
<div class="container card-grid">
|
||||
<div class="card">
|
||||
<h3>End-to-End Ownership</h3>
|
||||
<p>Architecture, deployment, adoption, and long-term operational support — with documentation and accountability.</p>
|
||||
</div>
|
||||
<div class="card">
|
||||
<h3>Operational Clarity</h3>
|
||||
<p>We align platform features to workflows, call flows, and real-world staffing — not marketing checklists.</p>
|
||||
</div>
|
||||
<div class="card">
|
||||
<h3>Reliable Support</h3>
|
||||
<p>Consistent escalation management, change control, and an operator mindset that sticks after go-live.</p>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</section>
|
||||
|
||||
<!-- ABOUT -->
|
||||
<section id="page-about" class="page" data-page="about" aria-labelledby="about-title">
|
||||
<section class="about-canvas" aria-labelledby="about-title">
|
||||
<div class="about-panel about-panel-left">
|
||||
<h2 id="about-title">About Queue North Technologies</h2>
|
||||
<p>
|
||||
Veteran-owned communications and networking partner focused on reliable, future-ready systems.
|
||||
We tell you the truth and align technology to operations — not licensing structures.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="about-panel about-panel-right">
|
||||
<h3>What Sets Us Apart</h3>
|
||||
<ul class="bullet-list">
|
||||
<li>Trustworthy, straightforward guidance</li>
|
||||
<li>Veteran-owned leadership and discipline</li>
|
||||
<li>25+ years in telecommunications and networking</li>
|
||||
<li>Flexible service levels and support governance</li>
|
||||
<li>Only pay for the features and services you actually need</li>
|
||||
</ul>
|
||||
</div>
|
||||
</section>
|
||||
</section>
|
||||
|
||||
<!-- SERVICES -->
|
||||
|
||||
<section id="page-services" class="page" data-page="services" aria-labelledby="services-title">
|
||||
<section class="page-hero alt-section">
|
||||
<div class="container page-hero-inner">
|
||||
<h2 id="services-title">Services</h2>
|
||||
<p class="section-intro">
|
||||
Modern communication, networking, and support services built around your operations today and your growth tomorrow
|
||||
</p>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="section">
|
||||
<div class="container services-grid">
|
||||
|
||||
<a class="service-item" href="#unified-communications" data-route="unified-communications">
|
||||
<img class="service-overview-image" src="assets/Unified communications in a modern office.png" alt="Unified Communications" loading="lazy" decoding="async" />
|
||||
<div class="card service-overview-card">
|
||||
<h3>Unified Communications</h3>
|
||||
<p>Voice, meetings, and messaging that keep your people connected without adding operational friction.</p>
|
||||
</div>
|
||||
</a>
|
||||
|
||||
<a class="service-item" href="#contact-center" data-route="contact-center">
|
||||
<img class="service-overview-image" src="assets/Modern call center in action.png" alt="Contact Center" loading="lazy" decoding="async" />
|
||||
<div class="card service-overview-card">
|
||||
<h3>Contact Center</h3>
|
||||
<p>Customer engagement built with routing, reporting, and workflow control that support real operational performance.</p>
|
||||
</div>
|
||||
</a>
|
||||
|
||||
<a class="service-item" href="#managed-support" data-route="managed-support">
|
||||
<img class="service-overview-image" src="assets/Managed Support.png" alt="Managed Services and Support" loading="lazy" decoding="async" />
|
||||
<div class="card service-overview-card">
|
||||
<h3>Managed Services & Support</h3>
|
||||
<p>Consistent support, clear accountability, and lifecycle management that keep your environment stable long after deployment.</p>
|
||||
</div>
|
||||
</a>
|
||||
|
||||
<a class="service-item" href="#consulting-training" data-route="consulting-training">
|
||||
<img class="service-overview-image" src="assets/Consulting & Training.png" alt="Consulting and Training" loading="lazy" decoding="async" />
|
||||
<div class="card service-overview-card">
|
||||
<h3>Consulting & Training</h3>
|
||||
<p>Straightforward guidance and practical training that help your team use technology with confidence and discipline.</p>
|
||||
</div>
|
||||
</a>
|
||||
|
||||
<a class="service-item" href="#infrastructure-cabling" data-route="infrastructure-cabling">
|
||||
<img class="service-overview-image" src="assets/Cabling.png" alt="Infrastructure Cabling" loading="lazy" decoding="async" />
|
||||
<div class="card service-overview-card">
|
||||
<h3>Infrastructure Cabling</h3>
|
||||
<p>Clean structured cabling that gives your business the physical foundation for reliable communication and growth.</p>
|
||||
</div>
|
||||
</a>
|
||||
|
||||
<a class="service-item" href="#wireless-access" data-route="wireless-access">
|
||||
<img class="service-overview-image" src="assets/Wireless.png" alt="Wireless Access" loading="lazy" decoding="async" />
|
||||
<div class="card service-overview-card">
|
||||
<h3>Wireless Access</h3>
|
||||
<p>Business Wi‑Fi designed for usable coverage, dependable performance, and fewer support headaches across your environment.</p>
|
||||
</div>
|
||||
</a>
|
||||
|
||||
<a class="service-item" href="#local-networking" data-route="local-networking">
|
||||
<img class="service-overview-image" src="assets/Local Networking.png" alt="Local Networking" loading="lazy" decoding="async" />
|
||||
<div class="card service-overview-card">
|
||||
<h3>Local Networking</h3>
|
||||
<p>Switching and routing built for stability, visibility, and secure local network performance.</p>
|
||||
</div>
|
||||
</a>
|
||||
|
||||
</div>
|
||||
</section>
|
||||
</section>
|
||||
|
||||
|
||||
<section id="page-unified-communications" class="page" data-page="unified-communications" aria-labelledby="unified-communications-title">
|
||||
<section class="section service-page-section alt-section">
|
||||
<div class="container service-page-content">
|
||||
<h2 id="unified-communications-title" class="service-page-title">Unified Communications</h2>
|
||||
<img class="service-page-image" src="assets/Unified communications in a modern office.png" alt="Unified Communications service" loading="lazy" decoding="async" />
|
||||
<p class="service-page-tagline">Voice, meetings, and messaging that keep your people connected without adding operational friction.</p>
|
||||
</div>
|
||||
</section>
|
||||
</section>
|
||||
|
||||
<section id="page-contact-center" class="page" data-page="contact-center" aria-labelledby="contact-center-title">
|
||||
<section class="section service-page-section alt-section">
|
||||
<div class="container service-page-content">
|
||||
<h2 id="contact-center-title" class="service-page-title">Contact Center</h2>
|
||||
<img class="service-page-image" src="assets/Modern call center in action.png" alt="Contact Center service" loading="lazy" decoding="async" />
|
||||
<p class="service-page-tagline">Customer engagement built with routing, reporting, and workflow control that support real operational performance.</p>
|
||||
</div>
|
||||
</section>
|
||||
</section>
|
||||
|
||||
<section id="page-managed-support" class="page" data-page="managed-support" aria-labelledby="managed-support-title">
|
||||
<section class="section service-page-section alt-section">
|
||||
<div class="container service-page-content">
|
||||
<h2 id="managed-support-title" class="service-page-title">Managed Services & Support</h2>
|
||||
<img class="service-page-image" src="assets/Managed Support.png" alt="Managed Services and Support service" loading="lazy" decoding="async" />
|
||||
<p class="service-page-tagline">Consistent support, clear accountability, and lifecycle management that keep your environment stable long after deployment.</p>
|
||||
</div>
|
||||
</section>
|
||||
</section>
|
||||
|
||||
<section id="page-consulting-training" class="page" data-page="consulting-training" aria-labelledby="consulting-training-title">
|
||||
<section class="section service-page-section alt-section">
|
||||
<div class="container service-page-content">
|
||||
<h2 id="consulting-training-title" class="service-page-title">Consulting & Training</h2>
|
||||
<img class="service-page-image" src="assets/Consulting & Training.png" alt="Consulting and Training service" loading="lazy" decoding="async" />
|
||||
<p class="service-page-tagline">Straightforward guidance and practical training that help your team use technology with confidence and discipline.</p>
|
||||
</div>
|
||||
</section>
|
||||
</section>
|
||||
|
||||
<section id="page-infrastructure-cabling" class="page" data-page="infrastructure-cabling" aria-labelledby="infrastructure-cabling-title">
|
||||
<section class="section service-page-section alt-section">
|
||||
<div class="container service-page-content">
|
||||
<h2 id="infrastructure-cabling-title" class="service-page-title">Infrastructure Cabling</h2>
|
||||
<img class="service-page-image" src="assets/Cabling.png" alt="Infrastructure Cabling service" loading="lazy" decoding="async" />
|
||||
<p class="service-page-tagline">Clean structured cabling that gives your business the physical foundation for reliable communication and growth.</p>
|
||||
</div>
|
||||
</section>
|
||||
</section>
|
||||
|
||||
<section id="page-wireless-access" class="page" data-page="wireless-access" aria-labelledby="wireless-access-title">
|
||||
<section class="section service-page-section alt-section">
|
||||
<div class="container service-page-content">
|
||||
<h2 id="wireless-access-title" class="service-page-title">Wireless Access</h2>
|
||||
<img class="service-page-image" src="assets/Wireless.png" alt="Wireless Access service" loading="lazy" decoding="async" />
|
||||
<p class="service-page-tagline">Business Wi‑Fi designed for usable coverage, dependable performance, and fewer support headaches across your environment.</p>
|
||||
</div>
|
||||
</section>
|
||||
</section>
|
||||
|
||||
<section id="page-local-networking" class="page" data-page="local-networking" aria-labelledby="local-networking-title">
|
||||
<section class="section service-page-section alt-section">
|
||||
<div class="container service-page-content">
|
||||
<h2 id="local-networking-title" class="service-page-title">Local Networking</h2>
|
||||
<img class="service-page-image" src="assets/Local Networking.png" alt="Local Networking service" loading="lazy" decoding="async" />
|
||||
<p class="service-page-tagline">Switching and routing built for secure local performance, clean management, and the operational visibility your business needs.</p>
|
||||
</div>
|
||||
</section>
|
||||
</section>
|
||||
|
||||
<!-- 8x8 -->
|
||||
<section id="page-8x8" class="page" data-page="eightx8" aria-labelledby="eightx8-title">
|
||||
<section class="page-hero">
|
||||
<div class="container page-hero-inner">
|
||||
<div>
|
||||
<h2 id="eightx8-title">8x8 Certified Partner</h2>
|
||||
|
||||
<ul class="bullet-list">
|
||||
<li>Solution design, licensing strategy, and platform fit</li>
|
||||
<li>Deployment planning, number porting, and migrations</li>
|
||||
<li>Configuration, routing, reporting, and operational governance</li>
|
||||
<li>Post-deployment support, escalation, and change control</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="page-hero-media">
|
||||
<div class="partner-lockup">
|
||||
<img
|
||||
class="partner-lockup-img"
|
||||
src="assets/JointLogoWhite.png"
|
||||
alt="Queue North Technologies | 8x8 Certified Partner"
|
||||
/>
|
||||
<div class="small-muted partner-lockup-caption">
|
||||
Queue North holds 8x8 Sales, Sales Engineer, Build, Deployment, and Support Certifications — enabling full lifecycle delivery.
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="section alt-section">
|
||||
<div class="container card-grid">
|
||||
<div class="card">
|
||||
<h3>UCaaS</h3>
|
||||
<p>Voice, meetings, and messaging delivered with documentation, governance, and operational clarity.</p>
|
||||
</div>
|
||||
<div class="card">
|
||||
<h3>Contact Center</h3>
|
||||
<p>Queue strategy, routing logic, reporting, and workforce workflows built for real performance visibility.</p>
|
||||
</div>
|
||||
<div class="card">
|
||||
<h3>Lifecycle Support</h3>
|
||||
<p>We stay accountable after go-live — support structure, escalation, and change control that doesn’t fall apart.</p>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</section>
|
||||
|
||||
<!-- INDUSTRIES -->
|
||||
<section id="page-industries" class="page" data-page="industries" aria-labelledby="industries-title">
|
||||
<section class="page-hero alt-section">
|
||||
<div class="container page-hero-inner">
|
||||
<div>
|
||||
<h2 id="industries-title">Industries We Serve</h2>
|
||||
<p class="section-intro">
|
||||
We focus on sectors where communication, reliability, and integration directly impact operations and customer experience.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="section">
|
||||
<div class="container industries-grid">
|
||||
|
||||
<div class="industry-item">
|
||||
<img class="industry-image" src="assets/Healthcare.png" alt="Healthcare" loading="lazy" decoding="async" />
|
||||
<div class="card industry-card">
|
||||
<h3>Healthcare</h3>
|
||||
<p>Patient experience, scheduling, and staff coordination with a focus on compliance.</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="industry-item">
|
||||
<img class="industry-image" src="assets/Retail.png" alt="Retail" loading="lazy" decoding="async" />
|
||||
<div class="card industry-card">
|
||||
<h3>Retail</h3>
|
||||
<p>Connect stores, back office, and support teams while improving customer interaction.</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="industry-item">
|
||||
<img class="industry-image" src="assets/Manufacturing.png" alt="Manufacturing" loading="lazy" decoding="async" />
|
||||
<div class="card industry-card">
|
||||
<h3>Manufacturing</h3>
|
||||
<p>Reliable office-to-plant communications including paging and alerting for production environments.</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="industry-item">
|
||||
<!-- If you keep the space in the filename, use %20 -->
|
||||
<img class="industry-image" src="assets/Financial%20Services.png" alt="Education & Finance" loading="lazy" decoding="async" />
|
||||
<div class="card industry-card">
|
||||
<h3>Education & Finance</h3>
|
||||
<p>Campus communications and customer-facing communications in tightly regulated environments.</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</section>
|
||||
</section>
|
||||
|
||||
<section id="page-healthcare" class="page" data-page="healthcare" aria-labelledby="healthcare-title">
|
||||
<section class="section service-page-section alt-section">
|
||||
<div class="container service-page-content">
|
||||
<h2 id="healthcare-title" class="service-page-title">Healthcare</h2>
|
||||
<img class="service-page-image" src="assets/Healthcare.png" alt="Healthcare industry" loading="lazy" decoding="async" />
|
||||
<p class="service-page-tagline">Patient experience, scheduling, and staff coordination with a focus on compliance.</p>
|
||||
</div>
|
||||
</section>
|
||||
</section>
|
||||
|
||||
<section id="page-retail" class="page" data-page="retail" aria-labelledby="retail-title">
|
||||
<section class="section service-page-section alt-section">
|
||||
<div class="container service-page-content">
|
||||
<h2 id="retail-title" class="service-page-title">Retail</h2>
|
||||
<img class="service-page-image" src="assets/Retail.png" alt="Retail industry" loading="lazy" decoding="async" />
|
||||
<p class="service-page-tagline">Connect stores, back office, and support teams while improving customer interaction.</p>
|
||||
</div>
|
||||
</section>
|
||||
</section>
|
||||
|
||||
<section id="page-manufacturing" class="page" data-page="manufacturing" aria-labelledby="manufacturing-title">
|
||||
<section class="section service-page-section alt-section">
|
||||
<div class="container service-page-content">
|
||||
<h2 id="manufacturing-title" class="service-page-title">Manufacturing</h2>
|
||||
<img class="service-page-image" src="assets/Manufacturing.png" alt="Manufacturing industry" loading="lazy" decoding="async" />
|
||||
<p class="service-page-tagline">Reliable office-to-plant communications including paging and alerting for production environments.</p>
|
||||
</div>
|
||||
</section>
|
||||
</section>
|
||||
|
||||
<section id="page-education-finance" class="page" data-page="education-finance" aria-labelledby="education-finance-title">
|
||||
<section class="section service-page-section alt-section">
|
||||
<div class="container service-page-content">
|
||||
<h2 id="education-finance-title" class="service-page-title">Education & Finance</h2>
|
||||
<img class="service-page-image" src="assets/Financial%20Services.png" alt="Education and Finance industry" loading="lazy" decoding="async" />
|
||||
<p class="service-page-tagline">Campus communications and customer-facing communications in tightly regulated environments.</p>
|
||||
</div>
|
||||
</section>
|
||||
</section>
|
||||
|
||||
<!-- CONTACT -->
|
||||
<section id="page-contact" class="page" data-page="contact" aria-labelledby="contact-title">
|
||||
<section class="page-hero">
|
||||
<div class="container page-hero-inner">
|
||||
<div>
|
||||
<h2 id="contact-title">Contact Us</h2>
|
||||
<p class="section-intro">
|
||||
If your environment provides no insight or accountability — or support is slow and inconsistent — we can help.
|
||||
Share a few details and we’ll provide clear direction.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="section alt-section">
|
||||
<div class="container two-column">
|
||||
<div>
|
||||
<h3>What we’ll help you do</h3>
|
||||
<ul class="bullet-list">
|
||||
<li>Identify the features you actually need</li>
|
||||
<li>Align solutions with operations and budget</li>
|
||||
<li>Plan deployment, migration, and training</li>
|
||||
<li>Ask how you qualify for our free migration</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<div class="wf_customMessageBox" id="wf_splash" style="display:none" role="status" aria-live="polite">
|
||||
<div class="wf_customCircle" aria-hidden="true">
|
||||
<div class="wf_customCheckMark"></div>
|
||||
</div>
|
||||
<span id="wf_splash_info"></span>
|
||||
<button type="button" class="wf_customClose" id="wf_splash_close" aria-label="Close message"></button>
|
||||
</div>
|
||||
|
||||
<form
|
||||
id="contact-form"
|
||||
class="contact-form"
|
||||
name="WebToLeads7130861000000581796"
|
||||
method="POST"
|
||||
action="https://crm.zoho.com/crm/WebToLeadForm"
|
||||
target="zoho_webform_iframe"
|
||||
accept-charset="UTF-8"
|
||||
>
|
||||
<!-- Zoho CRM required hidden fields. Do not remove. -->
|
||||
<input type="hidden" name="xnQsjsdp" value="b78607b2ef073f134a736184c22aa442ba026b6b00cfdbcb8078d8dee0bb1bbd" />
|
||||
<input type="hidden" name="zc_gad" id="zc_gad" value="" />
|
||||
<input type="hidden" name="xmIwtLD" value="e1201f09c921b74ca7844fca8689433ad14277423595fe88de0e4cd6c58e43e743fb001043cb5229e129ff4ab8b2beea" />
|
||||
<input type="hidden" name="actionType" value="TGVhZHM=" />
|
||||
<input type="hidden" name="returnURL" value="null" />
|
||||
<input type="text" name="aG9uZXlwb3Q" value="" tabindex="-1" autocomplete="off" aria-hidden="true" style="display:none;" />
|
||||
|
||||
<label for="Last_Name">
|
||||
Name <span aria-hidden="true">*</span>
|
||||
<input type="text" id="Last_Name" name="Last Name" maxlength="80" required />
|
||||
</label>
|
||||
|
||||
<label for="Company">
|
||||
Company <span aria-hidden="true">*</span>
|
||||
<input type="text" id="Company" name="Company" maxlength="200" required />
|
||||
</label>
|
||||
|
||||
<label for="Zip_Code">
|
||||
Zip Code <span aria-hidden="true">*</span>
|
||||
<input type="text" id="Zip_Code" name="Zip Code" maxlength="30" inputmode="numeric" autocomplete="postal-code" required />
|
||||
</label>
|
||||
|
||||
<label for="Email">
|
||||
Email <span aria-hidden="true">*</span>
|
||||
<input type="email" id="Email" name="Email" maxlength="100" required />
|
||||
</label>
|
||||
|
||||
<label for="Phone">
|
||||
Phone
|
||||
<input type="tel" id="Phone" name="Phone" maxlength="30" autocomplete="tel" />
|
||||
</label>
|
||||
|
||||
<label for="Description">
|
||||
How can we help? <span aria-hidden="true">*</span>
|
||||
<textarea id="Description" name="Description" rows="4" required></textarea>
|
||||
</label>
|
||||
|
||||
<button type="submit" id="formsubmit" class="primary-btn">Submit</button>
|
||||
<p id="form-status" class="form-status" aria-live="polite"></p>
|
||||
</form>
|
||||
<iframe name="zoho_webform_iframe" id="zoho_webform_iframe" title="Zoho form submission" style="display:none;"></iframe>
|
||||
|
||||
<!-- Zoho CRM webform validation and splash-message submit handling. Scoped to this form. -->
|
||||
<script>
|
||||
function validateEmail7130861000000581796() {
|
||||
var form = document.forms['WebToLeads7130861000000581796'];
|
||||
var emailFld = form.querySelector('[name="Email"]');
|
||||
if (!emailFld) return true;
|
||||
var emailVal = emailFld.value.replace(/^\s+|\s+$/g, '');
|
||||
if (emailVal.length !== 0) {
|
||||
var atpos = emailVal.indexOf('@');
|
||||
var dotpos = emailVal.lastIndexOf('.');
|
||||
if (atpos < 1 || dotpos < atpos + 2 || dotpos + 2 >= emailVal.length) {
|
||||
alert('Please enter a valid email address.');
|
||||
emailFld.focus();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
function checkMandatory7130861000000581796() {
|
||||
var form = document.forms['WebToLeads7130861000000581796'];
|
||||
var mandatoryFields = ['Company', 'Last Name', 'Email', 'Zip Code', 'Description'];
|
||||
var labels = ['Company', 'Name', 'Email', 'Zip Code', 'How can we help?'];
|
||||
|
||||
for (var i = 0; i < mandatoryFields.length; i++) {
|
||||
var fieldObj = form[mandatoryFields[i]];
|
||||
if (fieldObj && fieldObj.value.replace(/^\s+|\s+$/g, '').length === 0) {
|
||||
alert(labels[i] + ' cannot be empty.');
|
||||
fieldObj.focus();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (!validateEmail7130861000000581796()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
var existingServiceField = form.querySelector('input[name="service"]');
|
||||
if (existingServiceField) {
|
||||
existingServiceField.remove();
|
||||
}
|
||||
|
||||
var urlparams = new URLSearchParams(window.location.search);
|
||||
if (urlparams.has('service') && urlparams.get('service') === 'smarturl') {
|
||||
var serviceField = document.createElement('input');
|
||||
serviceField.setAttribute('type', 'hidden');
|
||||
serviceField.setAttribute('value', urlparams.get('service'));
|
||||
serviceField.setAttribute('name', 'service');
|
||||
form.appendChild(serviceField);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
(function () {
|
||||
var form = document.getElementById('contact-form');
|
||||
var submitButton = document.getElementById('formsubmit');
|
||||
var status = document.getElementById('form-status');
|
||||
var splash = document.getElementById('wf_splash');
|
||||
var splashInfo = document.getElementById('wf_splash_info');
|
||||
var splashClose = document.getElementById('wf_splash_close');
|
||||
var splashTimer;
|
||||
|
||||
function showSplash(message) {
|
||||
if (!splash || !splashInfo) return;
|
||||
splashInfo.textContent = message || 'Thank you. Your information has been submitted.';
|
||||
splash.style.display = 'flex';
|
||||
clearTimeout(splashTimer);
|
||||
splashTimer = setTimeout(function () {
|
||||
splash.style.display = 'none';
|
||||
}, 5000);
|
||||
}
|
||||
|
||||
if (splashClose) {
|
||||
splashClose.addEventListener('click', function () {
|
||||
if (splash) splash.style.display = 'none';
|
||||
});
|
||||
}
|
||||
|
||||
if (!form) return;
|
||||
|
||||
var submitPending = false;
|
||||
var iframe = document.getElementById('zoho_webform_iframe');
|
||||
|
||||
if (iframe) {
|
||||
iframe.addEventListener('load', function () {
|
||||
if (!submitPending) return;
|
||||
submitPending = false;
|
||||
form.reset();
|
||||
showSplash('Thank you. Your information has been submitted.');
|
||||
if (submitButton) {
|
||||
submitButton.removeAttribute('disabled');
|
||||
submitButton.textContent = 'Submit';
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
form.addEventListener('submit', function (event) {
|
||||
if (!checkMandatory7130861000000581796()) {
|
||||
event.preventDefault();
|
||||
return;
|
||||
}
|
||||
|
||||
if (submitButton) {
|
||||
submitButton.setAttribute('disabled', 'disabled');
|
||||
submitButton.textContent = 'Submitting...';
|
||||
}
|
||||
if (status) {
|
||||
status.textContent = '';
|
||||
}
|
||||
|
||||
if (typeof _wfa_track !== 'undefined' && _wfa_track.wfa_submit) {
|
||||
_wfa_track.wfa_submit(event);
|
||||
}
|
||||
|
||||
submitPending = true;
|
||||
|
||||
setTimeout(function () {
|
||||
if (submitPending) {
|
||||
submitPending = false;
|
||||
form.reset();
|
||||
showSplash('Thank you. Your information has been submitted.');
|
||||
if (submitButton) {
|
||||
submitButton.removeAttribute('disabled');
|
||||
submitButton.textContent = 'Submit';
|
||||
}
|
||||
}
|
||||
}, 3500);
|
||||
});
|
||||
})();
|
||||
</script>
|
||||
|
||||
<!-- Zoho CRM webform analytics. Do not remove. -->
|
||||
<script id="wf_anal" src="https://crm.zohopublic.com/crm/WebFormAnalyticsServeServlet?rid=e44e9662530fc5bd9cdd3c43501fc243f89ba03759e7946c4b5e5016795b606b59b54d0e73c68671b2140fac5c8e788agid3b907524e85f9cba94899d77d7200771ee5d0ea567c43ec341d7b2ce40324d40gid26922a9cd1e8191a5f58ecb2524e0d22b8dd027eb943658ee681ab6890436af2gidefa1b1002d15951a0a2ac36cb33cdb4b5c6aeb110e6f4ac68b764345b9429653&tw=e048253ca680b107993ed5922e00cc1ebab3de97e797fce56fc6ad6af0dfc0bc"></script>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</section>
|
||||
|
||||
<!-- SUPPORT -->
|
||||
<!-- SUPPORT -->
|
||||
<section id="page-support" class="page" data-page="support" aria-labelledby="support-title">
|
||||
<section class="page-hero alt-section">
|
||||
<div class="container support-hero-inner">
|
||||
<!-- LEFT: title + intro + form (centered) -->
|
||||
<div class="support-hero-left">
|
||||
<h2 id="support-title">Support</h2>
|
||||
<p class="section-intro">
|
||||
Need to sign up for the Queue North Support Center? Create an account to access our knowledge base and submit support tickets.
|
||||
</p>
|
||||
|
||||
<div class="support-action-card" aria-label="Queue North Support Center options">
|
||||
<a
|
||||
class="primary-btn support-action-btn"
|
||||
href="https://queuenorthtechnologiesllc.zohodesk.com/portal/en/signup"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>Create Account</a>
|
||||
|
||||
<p class="support-member-text">Already a member?</p>
|
||||
|
||||
<a
|
||||
class="primary-btn support-action-btn"
|
||||
href="https://queuenorthtechnologiesllc.zohodesk.com/portal/en/signin"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>Sign In</a>
|
||||
|
||||
<div class="support-phone-block">
|
||||
<span>Or call our support team</span>
|
||||
<span class="support-phone">(321) 730-8020</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- RIGHT: image (no card/container styling) -->
|
||||
<div class="support-hero-right" aria-label="Support visual">
|
||||
<img
|
||||
class="support-hero-image"
|
||||
src="assets/support.png"
|
||||
alt="Support agent assisting a customer"
|
||||
loading="lazy"
|
||||
decoding="async"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</section>
|
||||
|
||||
</main>
|
||||
|
||||
<footer class="site-footer">
|
||||
<div class="container footer-main">
|
||||
<div class="footer-brand">
|
||||
<div class="footer-heading">Queue North Technologies</div>
|
||||
<p>Veteran-owned communications and networking partner.</p>
|
||||
</div>
|
||||
|
||||
<div class="footer-column footer-phone">
|
||||
<div class="footer-heading">Phone</div>
|
||||
<a href="tel:+13217308020">Direct: (321) 730-8020</a>
|
||||
<a href="tel:+18886562850">Toll-Free: (888) 656-2850</a>
|
||||
</div>
|
||||
|
||||
<div class="footer-column footer-quick-links">
|
||||
<div class="footer-heading">Quick Links</div>
|
||||
<div class="footer-link-list">
|
||||
<a href="#home" data-route="home">Home</a>
|
||||
<a href="#contact" data-route="contact">Contact</a>
|
||||
<a href="#support" data-route="support">Support</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="footer-column footer-social">
|
||||
<div class="footer-heading">LinkedIn</div>
|
||||
<a class="footer-linkedin" href="https://linkedin.com/company/queue-north-technologies-llc" target="_blank" rel="noopener noreferrer" aria-label="Queue North Technologies on LinkedIn">
|
||||
<span class="linkedin-badge" aria-hidden="true">in</span>
|
||||
<span>Visit us on LinkedIn</span>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="container footer-legal">
|
||||
<div>© <span id="year"></span> Queue North Technologies. All rights reserved.</div>
|
||||
<div>8x8® is a registered trademark of 8x8, Inc. Queue North Technologies is an independent certified partner and is not owned or operated by 8x8, Inc.</div>
|
||||
</div>
|
||||
</footer>
|
||||
|
||||
<script src="main.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -0,0 +1,332 @@
|
|||
document.addEventListener("DOMContentLoaded", function () {
|
||||
const pages = Array.from(document.querySelectorAll(".page"));
|
||||
const navLinks = Array.from(document.querySelectorAll("[data-route]"));
|
||||
const dropdowns = Array.from(document.querySelectorAll(".nav-dropdown"));
|
||||
const siteNav = document.querySelector(".site-nav");
|
||||
const mobileNavToggle = document.querySelector(".mobile-nav-toggle");
|
||||
|
||||
function closeMobileNav() {
|
||||
if (!siteNav || !mobileNavToggle) return;
|
||||
siteNav.classList.remove("open");
|
||||
mobileNavToggle.setAttribute("aria-expanded", "false");
|
||||
}
|
||||
|
||||
function openMobileNav() {
|
||||
if (!siteNav || !mobileNavToggle) return;
|
||||
siteNav.classList.add("open");
|
||||
mobileNavToggle.setAttribute("aria-expanded", "true");
|
||||
}
|
||||
|
||||
function toggleMobileNav() {
|
||||
if (!siteNav || !mobileNavToggle) return;
|
||||
const willOpen = !siteNav.classList.contains("open");
|
||||
if (willOpen) {
|
||||
openMobileNav();
|
||||
} else {
|
||||
closeMobileNav();
|
||||
closeAllDropdowns();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function closeAllDropdowns(exceptDropdown = null) {
|
||||
if (mobileNavToggle) {
|
||||
mobileNavToggle.addEventListener("click", (e) => {
|
||||
e.preventDefault();
|
||||
toggleMobileNav();
|
||||
});
|
||||
}
|
||||
|
||||
dropdowns.forEach((dropdown) => {
|
||||
if (dropdown === exceptDropdown) return;
|
||||
dropdown.classList.remove("open");
|
||||
const toggle = dropdown.querySelector(".nav-dropdown-toggle");
|
||||
if (toggle) {
|
||||
toggle.setAttribute("aria-expanded", "false");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function syncDropdownState() {
|
||||
dropdowns.forEach((dropdown) => {
|
||||
const toggle = dropdown.querySelector(".nav-dropdown-toggle");
|
||||
if (!toggle) return;
|
||||
const expanded = dropdown.classList.contains("open") ? "true" : "false";
|
||||
toggle.setAttribute("aria-expanded", expanded);
|
||||
});
|
||||
}
|
||||
|
||||
dropdowns.forEach((dropdown) => {
|
||||
const toggle = dropdown.querySelector(".nav-dropdown-toggle");
|
||||
const dropdownMenuLinks = Array.from(dropdown.querySelectorAll(".nav-dropdown-menu [data-route]"));
|
||||
|
||||
if (!toggle) return;
|
||||
|
||||
toggle.addEventListener("click", (e) => {
|
||||
e.preventDefault();
|
||||
const parentRoute = toggle.dataset.route || "home";
|
||||
|
||||
if (window.innerWidth <= 900) {
|
||||
closeAllDropdowns();
|
||||
window.location.hash = parentRoute === "eightx8" ? "8x8" : parentRoute;
|
||||
setActive(parentRoute);
|
||||
return;
|
||||
}
|
||||
|
||||
const willOpen = !dropdown.classList.contains("open");
|
||||
closeAllDropdowns(dropdown);
|
||||
dropdown.classList.toggle("open", willOpen);
|
||||
toggle.setAttribute("aria-expanded", willOpen ? "true" : "false");
|
||||
|
||||
if (willOpen) {
|
||||
window.location.hash = parentRoute === "eightx8" ? "8x8" : parentRoute;
|
||||
setActive(parentRoute);
|
||||
}
|
||||
});
|
||||
|
||||
dropdownMenuLinks.forEach((link) => {
|
||||
link.addEventListener("click", () => {
|
||||
closeAllDropdowns();
|
||||
|
||||
window.setTimeout(() => {
|
||||
if (document.activeElement) {
|
||||
document.activeElement.blur();
|
||||
}
|
||||
}, 0);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
document.addEventListener("click", (e) => {
|
||||
const clickedInsideDropdown = dropdowns.some((dropdown) => dropdown.contains(e.target));
|
||||
const clickedInsideNav = siteNav ? siteNav.contains(e.target) : false;
|
||||
const clickedMobileToggle = mobileNavToggle ? mobileNavToggle.contains(e.target) : false;
|
||||
|
||||
if (!clickedInsideDropdown) {
|
||||
closeAllDropdowns();
|
||||
}
|
||||
|
||||
if (window.innerWidth <= 900 && !clickedInsideNav && !clickedMobileToggle) {
|
||||
closeMobileNav();
|
||||
}
|
||||
});
|
||||
|
||||
document.addEventListener("keydown", (e) => {
|
||||
if (e.key === "Escape") {
|
||||
closeAllDropdowns();
|
||||
closeMobileNav();
|
||||
}
|
||||
});
|
||||
|
||||
const serviceRoutes = new Set([
|
||||
"services",
|
||||
"unified-communications",
|
||||
"contact-center",
|
||||
"managed-support",
|
||||
"consulting-training",
|
||||
"infrastructure-cabling",
|
||||
"wireless-access",
|
||||
"local-networking"
|
||||
]);
|
||||
|
||||
const industryRoutes = new Set([
|
||||
"industries",
|
||||
"healthcare",
|
||||
"retail",
|
||||
"manufacturing",
|
||||
"education-finance"
|
||||
]);
|
||||
|
||||
function setActive(route) {
|
||||
const requested = route || "home";
|
||||
const hasRoute = pages.some((p) => p.dataset.page === requested);
|
||||
const target = hasRoute ? requested : "home";
|
||||
|
||||
pages.forEach((p) => {
|
||||
const isActive = p.dataset.page === target;
|
||||
p.classList.toggle("active", isActive);
|
||||
p.setAttribute("aria-hidden", isActive ? "false" : "true");
|
||||
});
|
||||
|
||||
navLinks.forEach((a) => {
|
||||
const routeName = a.dataset.route;
|
||||
const isServiceParent = routeName === "services" && serviceRoutes.has(target);
|
||||
const isIndustryParent = routeName === "industries" && industryRoutes.has(target);
|
||||
const isActive = routeName === target || isServiceParent || isIndustryParent;
|
||||
a.classList.toggle("active", isActive);
|
||||
if (isActive) {
|
||||
a.setAttribute("aria-current", "page");
|
||||
} else {
|
||||
a.removeAttribute("aria-current");
|
||||
}
|
||||
});
|
||||
|
||||
syncDropdownState();
|
||||
|
||||
window.scrollTo({ top: 0, behavior: "instant" });
|
||||
|
||||
if (target === "home") {
|
||||
startHeroMotion();
|
||||
} else {
|
||||
stopHeroMotion();
|
||||
}
|
||||
}
|
||||
|
||||
function routeFromHash() {
|
||||
const hash = (window.location.hash || "#home").replace("#", "").trim();
|
||||
if (hash === "8x8") return "eightx8";
|
||||
return hash || "home";
|
||||
}
|
||||
|
||||
navLinks.forEach((a) => {
|
||||
a.addEventListener("click", (e) => {
|
||||
const route = a.dataset.route;
|
||||
if (!route) return;
|
||||
|
||||
e.preventDefault();
|
||||
window.location.hash = route === "eightx8" ? "8x8" : route;
|
||||
setActive(route);
|
||||
|
||||
if (window.innerWidth <= 900) {
|
||||
closeMobileNav();
|
||||
closeAllDropdowns();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
const cta = document.getElementById("cta-consultation");
|
||||
if (cta) {
|
||||
cta.addEventListener("click", () => {
|
||||
window.location.hash = "contact";
|
||||
setActive("contact");
|
||||
closeMobileNav();
|
||||
closeAllDropdowns();
|
||||
});
|
||||
}
|
||||
|
||||
window.addEventListener("hashchange", () => {
|
||||
setActive(routeFromHash());
|
||||
});
|
||||
|
||||
window.addEventListener("resize", () => {
|
||||
if (window.innerWidth <= 900) {
|
||||
closeAllDropdowns();
|
||||
}
|
||||
});
|
||||
|
||||
const yearSpan = document.getElementById("year");
|
||||
if (yearSpan) yearSpan.textContent = new Date().getFullYear();
|
||||
|
||||
const rotatorEl = document.getElementById("hero-rotator-text");
|
||||
const lockupEl = document.getElementById("hero-lockup");
|
||||
|
||||
const phrases = [
|
||||
"Technical Precision",
|
||||
"Operational Clarity",
|
||||
"Human-Centered Support"
|
||||
];
|
||||
|
||||
const phraseFadeIn = 1100;
|
||||
const phraseHold = 1900;
|
||||
const phraseFadeOut = 1100;
|
||||
const betweenGap = 500;
|
||||
const lockupFadeIn = 1200;
|
||||
const lockupHold = 6500;
|
||||
const loopGap = 800;
|
||||
|
||||
let heroTimer = null;
|
||||
let heroRunId = 0;
|
||||
|
||||
function showEl(el) {
|
||||
if (!el) return;
|
||||
el.classList.add("is-visible");
|
||||
el.classList.remove("is-hidden");
|
||||
}
|
||||
|
||||
function hideEl(el) {
|
||||
if (!el) return;
|
||||
el.classList.remove("is-visible");
|
||||
el.classList.add("is-hidden");
|
||||
}
|
||||
|
||||
function setText(el, text) {
|
||||
if (!el) return;
|
||||
el.textContent = text;
|
||||
}
|
||||
|
||||
function sleep(ms) {
|
||||
return new Promise((resolve) => {
|
||||
heroTimer = window.setTimeout(resolve, ms);
|
||||
});
|
||||
}
|
||||
|
||||
function clearHeroTimer() {
|
||||
if (heroTimer) {
|
||||
window.clearTimeout(heroTimer);
|
||||
heroTimer = null;
|
||||
}
|
||||
}
|
||||
|
||||
async function heroLoop(runId) {
|
||||
if (!rotatorEl || !lockupEl) return;
|
||||
|
||||
hideEl(lockupEl);
|
||||
hideEl(rotatorEl);
|
||||
|
||||
while (runId === heroRunId) {
|
||||
for (let i = 0; i < phrases.length; i++) {
|
||||
if (runId !== heroRunId) return;
|
||||
|
||||
setText(rotatorEl, phrases[i]);
|
||||
|
||||
rotatorEl.style.setProperty("--hero-fade-ms", `${phraseFadeIn}ms`);
|
||||
rotatorEl.style.setProperty("--hero-drift-ms", `${phraseFadeIn + phraseHold + phraseFadeOut}ms`);
|
||||
showEl(rotatorEl);
|
||||
await sleep(phraseFadeIn);
|
||||
|
||||
await sleep(phraseHold);
|
||||
|
||||
hideEl(rotatorEl);
|
||||
await sleep(phraseFadeOut);
|
||||
|
||||
await sleep(betweenGap);
|
||||
}
|
||||
|
||||
if (runId !== heroRunId) return;
|
||||
|
||||
lockupEl.style.setProperty("--hero-lockup-fade-ms", `${lockupFadeIn}ms`);
|
||||
showEl(lockupEl);
|
||||
await sleep(lockupFadeIn);
|
||||
|
||||
await sleep(lockupHold);
|
||||
|
||||
hideEl(lockupEl);
|
||||
await sleep(loopGap);
|
||||
}
|
||||
}
|
||||
|
||||
function startHeroMotion() {
|
||||
if (!rotatorEl || !lockupEl) return;
|
||||
|
||||
heroRunId += 1;
|
||||
clearHeroTimer();
|
||||
hideEl(lockupEl);
|
||||
hideEl(rotatorEl);
|
||||
heroLoop(heroRunId);
|
||||
}
|
||||
|
||||
function stopHeroMotion() {
|
||||
heroRunId += 1;
|
||||
clearHeroTimer();
|
||||
hideEl(lockupEl);
|
||||
hideEl(rotatorEl);
|
||||
}
|
||||
|
||||
window.addEventListener("resize", () => {
|
||||
if (window.innerWidth > 900) {
|
||||
closeMobileNav();
|
||||
}
|
||||
});
|
||||
|
||||
setActive(routeFromHash());
|
||||
});
|
||||