mirror of
https://github.com/agessaman/meshcore-bot.git
synced 2026-05-12 02:24:59 +00:00
7984fa3af6
- Updated `send_dm` and `send_channel_message` methods to include an optional `command_id` for tracking message repeats. - Integrated transmission tracking to record and manage repeat messages, improving message handling and response accuracy. - Enhanced `capture_command` method in `BotIntegration` to store repeat information for better analysis in the web viewer. - Added favicon support and improved web viewer templates to display repeat information effectively. - Implemented JavaScript updates in the web viewer to handle command updates and display repeat counts dynamically.
1394 lines
50 KiB
HTML
1394 lines
50 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<title>HowlBot🤖 - Command Reference</title>
|
|
<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=Outfit:wght@400;500;600;700&family=JetBrains+Mono:wght@400;500;600&display=swap" rel="stylesheet">
|
|
<style>
|
|
:root {
|
|
--bg-primary: #0a0e14;
|
|
--bg-secondary: #111820;
|
|
--bg-card: #151c25;
|
|
--bg-card-hover: #1a232e;
|
|
--accent-blue: #00d4ff;
|
|
--accent-cyan: #00ffc8;
|
|
--accent-orange: #ff8a00;
|
|
--accent-purple: #a855f7;
|
|
--accent-red: #ff4757;
|
|
--accent-yellow: #ffd700;
|
|
--text-primary: #e8edf4;
|
|
--text-secondary: #8892a4;
|
|
--text-muted: #4a5568;
|
|
--border-subtle: rgba(255,255,255,0.06);
|
|
--glow-blue: rgba(0, 212, 255, 0.15);
|
|
--glow-cyan: rgba(0, 255, 200, 0.1);
|
|
}
|
|
|
|
* {
|
|
margin: 0;
|
|
padding: 0;
|
|
box-sizing: border-box;
|
|
}
|
|
|
|
html {
|
|
scroll-behavior: smooth;
|
|
}
|
|
|
|
body {
|
|
font-family: 'Outfit', sans-serif;
|
|
background: var(--bg-primary);
|
|
color: var(--text-primary);
|
|
min-height: 100vh;
|
|
overflow-x: hidden;
|
|
line-height: 1.6;
|
|
}
|
|
|
|
/* Atmospheric background */
|
|
.atmosphere {
|
|
position: fixed;
|
|
inset: 0;
|
|
background:
|
|
radial-gradient(ellipse 80% 50% at 20% 0%, rgba(0, 212, 255, 0.08) 0%, transparent 50%),
|
|
radial-gradient(ellipse 60% 40% at 80% 100%, rgba(0, 255, 200, 0.05) 0%, transparent 50%),
|
|
radial-gradient(ellipse 100% 100% at 50% 50%, var(--bg-primary) 0%, #060a0f 100%);
|
|
pointer-events: none;
|
|
z-index: -1;
|
|
}
|
|
|
|
/* Subtle grid overlay */
|
|
.grid-overlay {
|
|
position: fixed;
|
|
inset: 0;
|
|
background-image:
|
|
linear-gradient(rgba(255,255,255,0.01) 1px, transparent 1px),
|
|
linear-gradient(90deg, rgba(255,255,255,0.01) 1px, transparent 1px);
|
|
background-size: 60px 60px;
|
|
pointer-events: none;
|
|
z-index: -1;
|
|
}
|
|
|
|
.container {
|
|
max-width: 1600px;
|
|
margin: 0 auto;
|
|
padding: 3rem 2rem;
|
|
min-height: 100vh;
|
|
position: relative;
|
|
z-index: 1;
|
|
display: grid;
|
|
grid-template-columns: 280px 1fr;
|
|
gap: 3rem;
|
|
}
|
|
|
|
.sidebar-nav {
|
|
position: sticky;
|
|
top: 2rem;
|
|
height: fit-content;
|
|
max-height: calc(100vh - 4rem);
|
|
overflow-y: auto;
|
|
background: var(--bg-card);
|
|
border-radius: 16px;
|
|
border: 1px solid var(--border-subtle);
|
|
padding: 1.5rem;
|
|
z-index: 100;
|
|
transition: left 0.3s cubic-bezier(0.4, 0, 0.2, 1);
|
|
opacity: 1;
|
|
filter: none;
|
|
}
|
|
|
|
.mobile-menu-toggle {
|
|
display: none;
|
|
position: fixed;
|
|
top: 1.5rem;
|
|
right: 1.5rem;
|
|
z-index: 1001;
|
|
background: var(--bg-card);
|
|
border: 1px solid var(--border-subtle);
|
|
border-radius: 12px;
|
|
padding: 0.75rem;
|
|
cursor: pointer;
|
|
flex-direction: column;
|
|
gap: 5px;
|
|
align-items: center;
|
|
justify-content: center;
|
|
width: 48px;
|
|
height: 48px;
|
|
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3);
|
|
transition: all 0.3s ease;
|
|
}
|
|
|
|
.mobile-menu-toggle:hover {
|
|
background: var(--bg-card-hover);
|
|
border-color: var(--accent-cyan);
|
|
}
|
|
|
|
.mobile-menu-toggle.active {
|
|
background: var(--bg-card-hover);
|
|
border-color: var(--accent-cyan);
|
|
}
|
|
|
|
.hamburger {
|
|
width: 24px;
|
|
height: 2px;
|
|
background: var(--accent-cyan);
|
|
border-radius: 2px;
|
|
transition: all 0.3s ease;
|
|
}
|
|
|
|
.mobile-menu-toggle.active .hamburger:nth-child(1) {
|
|
transform: rotate(45deg) translate(7px, 7px);
|
|
}
|
|
|
|
.mobile-menu-toggle.active .hamburger:nth-child(2) {
|
|
opacity: 0;
|
|
}
|
|
|
|
.mobile-menu-toggle.active .hamburger:nth-child(3) {
|
|
transform: rotate(-45deg) translate(7px, -7px);
|
|
}
|
|
|
|
.sidebar-overlay {
|
|
display: none;
|
|
position: fixed;
|
|
inset: 0;
|
|
background: rgba(0, 0, 0, 0.7);
|
|
z-index: 1000;
|
|
backdrop-filter: none;
|
|
-webkit-backdrop-filter: none;
|
|
pointer-events: none;
|
|
}
|
|
|
|
.sidebar-overlay.visible {
|
|
pointer-events: auto;
|
|
}
|
|
|
|
@media (max-width: 1200px) {
|
|
.sidebar-overlay.visible {
|
|
/* Don't cover the sidebar area - start overlay after sidebar width */
|
|
left: 280px !important;
|
|
}
|
|
}
|
|
|
|
@media (min-width: 1201px) {
|
|
.sidebar-overlay {
|
|
backdrop-filter: blur(4px);
|
|
-webkit-backdrop-filter: blur(4px);
|
|
}
|
|
}
|
|
|
|
@media (max-width: 1200px) {
|
|
.sidebar-overlay {
|
|
backdrop-filter: none !important;
|
|
-webkit-backdrop-filter: none !important;
|
|
z-index: 1000 !important;
|
|
}
|
|
|
|
.sidebar-overlay.visible {
|
|
pointer-events: auto !important;
|
|
}
|
|
|
|
/* Ensure sidebar is always clickable above overlay */
|
|
.sidebar-nav {
|
|
pointer-events: auto !important;
|
|
}
|
|
|
|
.sidebar-nav * {
|
|
pointer-events: auto !important;
|
|
}
|
|
}
|
|
|
|
.sidebar-overlay.visible {
|
|
display: block;
|
|
}
|
|
|
|
.sidebar-nav::-webkit-scrollbar {
|
|
width: 6px;
|
|
}
|
|
|
|
.sidebar-nav::-webkit-scrollbar-track {
|
|
background: var(--bg-secondary);
|
|
border-radius: 3px;
|
|
}
|
|
|
|
.sidebar-nav::-webkit-scrollbar-thumb {
|
|
background: var(--border-subtle);
|
|
border-radius: 3px;
|
|
}
|
|
|
|
.sidebar-nav::-webkit-scrollbar-thumb:hover {
|
|
background: rgba(255,255,255,0.15);
|
|
}
|
|
|
|
.nav-header {
|
|
margin-bottom: 1.5rem;
|
|
padding-bottom: 1rem;
|
|
border-bottom: 1px solid var(--border-subtle);
|
|
}
|
|
|
|
.nav-header h3 {
|
|
font-size: 1rem;
|
|
font-weight: 600;
|
|
color: var(--text-primary);
|
|
text-transform: uppercase;
|
|
letter-spacing: 0.05em;
|
|
font-size: 0.85rem;
|
|
}
|
|
|
|
.nav-list {
|
|
list-style: none;
|
|
padding: 0;
|
|
margin: 0;
|
|
}
|
|
|
|
.nav-section-header {
|
|
font-size: 0.75rem;
|
|
text-transform: uppercase;
|
|
letter-spacing: 0.1em;
|
|
color: var(--text-muted);
|
|
font-weight: 600;
|
|
margin-top: 1.5rem;
|
|
margin-bottom: 0.75rem;
|
|
padding-left: 0.5rem;
|
|
}
|
|
|
|
.nav-section-header:first-child {
|
|
margin-top: 0;
|
|
}
|
|
|
|
.nav-sublist {
|
|
list-style: none;
|
|
padding: 0;
|
|
margin: 0 0 1rem 0;
|
|
padding-left: 0.5rem;
|
|
}
|
|
|
|
.nav-link {
|
|
display: block;
|
|
padding: 0.6rem 0.75rem;
|
|
color: var(--text-secondary);
|
|
text-decoration: none;
|
|
border-radius: 8px;
|
|
font-size: 0.9rem;
|
|
transition: all 0.2s ease;
|
|
margin-bottom: 0.25rem;
|
|
cursor: pointer;
|
|
-webkit-tap-highlight-color: rgba(0, 255, 200, 0.2);
|
|
}
|
|
|
|
.nav-link:hover {
|
|
background: var(--bg-card-hover);
|
|
color: var(--accent-cyan);
|
|
transform: translateX(4px);
|
|
}
|
|
|
|
.nav-link:active,
|
|
.nav-link.active {
|
|
background: rgba(0, 255, 200, 0.1);
|
|
color: var(--accent-cyan);
|
|
border-left: 3px solid var(--accent-cyan);
|
|
padding-left: calc(0.75rem - 3px);
|
|
}
|
|
|
|
.nav-sublink {
|
|
padding-left: 1.25rem;
|
|
font-size: 0.85rem;
|
|
color: var(--text-muted);
|
|
}
|
|
|
|
.nav-sublink:hover {
|
|
color: var(--accent-blue);
|
|
}
|
|
|
|
.main-content {
|
|
min-width: 0;
|
|
}
|
|
|
|
header {
|
|
margin-bottom: 4rem;
|
|
padding: 0;
|
|
}
|
|
|
|
.header-content {
|
|
background: var(--bg-card);
|
|
border-radius: 20px;
|
|
border: 1px solid var(--border-subtle);
|
|
padding: 3rem 2.5rem;
|
|
position: relative;
|
|
overflow: hidden;
|
|
}
|
|
|
|
.header-content::before {
|
|
content: '';
|
|
position: absolute;
|
|
top: 0;
|
|
left: 0;
|
|
right: 0;
|
|
height: 3px;
|
|
background: linear-gradient(90deg, var(--accent-blue), var(--accent-cyan));
|
|
}
|
|
|
|
.header-title {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 1rem;
|
|
margin-bottom: 1.5rem;
|
|
}
|
|
|
|
.logo-icon {
|
|
width: 56px;
|
|
height: 56px;
|
|
background: linear-gradient(135deg, var(--accent-blue), var(--accent-cyan));
|
|
border-radius: 14px;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
font-size: 1.75rem;
|
|
box-shadow: 0 4px 20px var(--glow-blue);
|
|
flex-shrink: 0;
|
|
}
|
|
|
|
h1 {
|
|
font-size: 3rem;
|
|
font-weight: 600;
|
|
margin: 0;
|
|
color: var(--accent-cyan);
|
|
letter-spacing: -0.02em;
|
|
font-family: 'Outfit', sans-serif;
|
|
}
|
|
|
|
.intro {
|
|
font-size: 1.1rem;
|
|
color: var(--text-secondary);
|
|
max-width: 900px;
|
|
line-height: 1.8;
|
|
margin-top: 0.5rem;
|
|
}
|
|
|
|
.channel-highlight {
|
|
color: var(--accent-cyan);
|
|
font-weight: 500;
|
|
}
|
|
|
|
.category-section {
|
|
margin-bottom: 3rem;
|
|
}
|
|
|
|
.category-title {
|
|
font-size: 1.75rem;
|
|
font-weight: 600;
|
|
margin-bottom: 1.5rem;
|
|
color: var(--text-primary);
|
|
padding-bottom: 1rem;
|
|
border-bottom: 1px solid var(--border-subtle);
|
|
letter-spacing: -0.01em;
|
|
}
|
|
|
|
.category-title .anchor-link,
|
|
.channel-category-title .anchor-link {
|
|
color: inherit;
|
|
text-decoration: none;
|
|
position: relative;
|
|
display: inline-block;
|
|
}
|
|
|
|
.category-title .anchor-link:hover,
|
|
.channel-category-title .anchor-link:hover {
|
|
color: var(--accent-cyan);
|
|
}
|
|
|
|
.category-title .anchor-link::before {
|
|
content: '#';
|
|
position: absolute;
|
|
left: -1.5rem;
|
|
opacity: 0;
|
|
color: var(--accent-blue);
|
|
font-weight: 400;
|
|
transition: opacity 0.2s ease;
|
|
}
|
|
|
|
.category-title:hover .anchor-link::before,
|
|
.channel-category-title:hover .anchor-link::before {
|
|
opacity: 0.5;
|
|
}
|
|
|
|
.category-section,
|
|
.channel-category {
|
|
scroll-margin-top: 2rem;
|
|
}
|
|
|
|
.commands-grid {
|
|
display: grid;
|
|
grid-template-columns: repeat(auto-fill, minmax(320px, 1fr));
|
|
gap: 1.25rem;
|
|
margin-bottom: 2rem;
|
|
}
|
|
|
|
.command-card {
|
|
background: var(--bg-card);
|
|
border-radius: 16px;
|
|
padding: 1.5rem;
|
|
border: 1px solid var(--border-subtle);
|
|
transition: all 0.3s ease;
|
|
position: relative;
|
|
overflow: hidden;
|
|
}
|
|
|
|
.command-card::before {
|
|
content: '';
|
|
position: absolute;
|
|
top: 0;
|
|
left: 0;
|
|
right: 0;
|
|
height: 3px;
|
|
background: linear-gradient(90deg, var(--accent-blue), transparent);
|
|
opacity: 0;
|
|
transition: opacity 0.3s ease;
|
|
}
|
|
|
|
.command-card:hover {
|
|
background: var(--bg-card-hover);
|
|
border-color: rgba(255,255,255,0.1);
|
|
transform: translateY(-2px);
|
|
}
|
|
|
|
.command-card:hover::before {
|
|
opacity: 1;
|
|
}
|
|
|
|
.command-header {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 0.75rem;
|
|
margin-bottom: 1rem;
|
|
}
|
|
|
|
.command-name {
|
|
font-size: 1.5rem;
|
|
font-weight: 600;
|
|
color: var(--accent-blue);
|
|
margin: 0;
|
|
letter-spacing: -0.01em;
|
|
}
|
|
|
|
.command-keywords {
|
|
display: flex;
|
|
flex-wrap: wrap;
|
|
gap: 0.5rem;
|
|
}
|
|
|
|
.keyword-badge {
|
|
background: rgba(0, 212, 255, 0.1);
|
|
color: var(--accent-cyan);
|
|
padding: 0.35rem 0.75rem;
|
|
border-radius: 8px;
|
|
font-size: 0.8rem;
|
|
font-weight: 500;
|
|
border: 1px solid rgba(0, 212, 255, 0.2);
|
|
font-family: 'JetBrains Mono', monospace;
|
|
}
|
|
|
|
.keyword-expand {
|
|
cursor: pointer;
|
|
transition: all 0.2s ease;
|
|
}
|
|
|
|
.keyword-expand:hover {
|
|
background: rgba(0, 212, 255, 0.2);
|
|
border-color: var(--accent-cyan);
|
|
transform: scale(1.05);
|
|
}
|
|
|
|
.keyword-expand.expanded {
|
|
display: none;
|
|
}
|
|
|
|
.keyword-hidden {
|
|
display: none;
|
|
}
|
|
|
|
.keyword-hidden.visible {
|
|
display: inline-block;
|
|
}
|
|
|
|
.command-description {
|
|
color: var(--text-secondary);
|
|
line-height: 1.7;
|
|
margin-bottom: 0.75rem;
|
|
font-size: 0.95rem;
|
|
}
|
|
|
|
.command-channels {
|
|
color: var(--accent-cyan);
|
|
font-size: 0.85rem;
|
|
margin-top: 0.75rem;
|
|
padding: 0.6rem 0.9rem;
|
|
background: rgba(0, 255, 200, 0.08);
|
|
border-radius: 8px;
|
|
border-left: 3px solid var(--accent-cyan);
|
|
font-family: 'JetBrains Mono', monospace;
|
|
font-weight: 500;
|
|
}
|
|
|
|
.channels-intro {
|
|
color: var(--text-secondary);
|
|
font-size: 1rem;
|
|
margin-bottom: 2rem;
|
|
line-height: 1.7;
|
|
}
|
|
|
|
.channel-category {
|
|
margin-bottom: 2.5rem;
|
|
}
|
|
|
|
.channel-category-title {
|
|
font-size: 1.25rem;
|
|
font-weight: 600;
|
|
color: var(--accent-blue);
|
|
margin-bottom: 1rem;
|
|
letter-spacing: -0.01em;
|
|
}
|
|
|
|
.channel-category-title .anchor-link::before {
|
|
content: '#';
|
|
position: absolute;
|
|
left: -1.2rem;
|
|
opacity: 0;
|
|
color: var(--accent-blue);
|
|
font-weight: 400;
|
|
transition: opacity 0.2s ease;
|
|
}
|
|
|
|
.channels-grid {
|
|
display: grid;
|
|
grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
|
|
gap: 1rem;
|
|
}
|
|
|
|
.channel-card {
|
|
background: var(--bg-card);
|
|
border-radius: 12px;
|
|
padding: 1.25rem;
|
|
border: 1px solid var(--border-subtle);
|
|
transition: all 0.3s ease;
|
|
}
|
|
|
|
.channel-card:hover {
|
|
background: var(--bg-card-hover);
|
|
border-color: rgba(0, 212, 255, 0.3);
|
|
transform: translateY(-2px);
|
|
}
|
|
|
|
.channel-name {
|
|
font-family: 'JetBrains Mono', monospace;
|
|
font-size: 1.1rem;
|
|
font-weight: 600;
|
|
color: var(--accent-cyan);
|
|
margin-bottom: 0.5rem;
|
|
}
|
|
|
|
.channel-description {
|
|
color: var(--text-secondary);
|
|
font-size: 0.9rem;
|
|
line-height: 1.6;
|
|
}
|
|
|
|
footer {
|
|
text-align: center;
|
|
margin-top: 4rem;
|
|
padding: 2rem;
|
|
color: var(--text-muted);
|
|
font-size: 0.9rem;
|
|
border-top: 1px solid var(--border-subtle);
|
|
}
|
|
|
|
@media (max-width: 1200px) {
|
|
.commands-grid {
|
|
grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
|
|
}
|
|
}
|
|
|
|
@media (max-width: 1200px) {
|
|
/* Disable all backdrop filters on mobile */
|
|
* {
|
|
backdrop-filter: none !important;
|
|
-webkit-backdrop-filter: none !important;
|
|
}
|
|
|
|
.container {
|
|
grid-template-columns: 1fr !important;
|
|
}
|
|
|
|
.mobile-menu-toggle {
|
|
display: flex;
|
|
}
|
|
|
|
.sidebar-nav {
|
|
position: fixed !important;
|
|
top: 0 !important;
|
|
left: -320px !important;
|
|
width: 280px !important;
|
|
height: 100vh !important;
|
|
max-height: 100vh !important;
|
|
margin: 0 !important;
|
|
padding-top: 4rem !important;
|
|
border-radius: 0 !important;
|
|
border-left: none !important;
|
|
border-top: none !important;
|
|
border-bottom: none !important;
|
|
border-right: 1px solid var(--border-subtle) !important;
|
|
transition: left 0.3s cubic-bezier(0.4, 0, 0.2, 1) !important;
|
|
z-index: 1002 !important;
|
|
opacity: 1 !important;
|
|
filter: none !important;
|
|
backdrop-filter: none !important;
|
|
-webkit-backdrop-filter: none !important;
|
|
transform: translateZ(0) !important;
|
|
will-change: left !important;
|
|
isolation: isolate !important;
|
|
background: var(--bg-card) !important;
|
|
visibility: visible !important;
|
|
-webkit-font-smoothing: antialiased !important;
|
|
-moz-osx-font-smoothing: grayscale !important;
|
|
overflow-y: auto !important;
|
|
overflow-x: hidden !important;
|
|
-webkit-overflow-scrolling: touch !important;
|
|
pointer-events: auto !important;
|
|
touch-action: pan-y !important;
|
|
-webkit-transform: translateZ(0) !important;
|
|
transform: translateZ(0) !important;
|
|
}
|
|
|
|
.sidebar-nav.open {
|
|
left: 0 !important;
|
|
}
|
|
|
|
.sidebar-nav * {
|
|
opacity: 1 !important;
|
|
filter: none !important;
|
|
backdrop-filter: none !important;
|
|
-webkit-backdrop-filter: none !important;
|
|
visibility: visible !important;
|
|
-webkit-font-smoothing: antialiased !important;
|
|
-moz-osx-font-smoothing: grayscale !important;
|
|
pointer-events: auto !important;
|
|
}
|
|
|
|
.sidebar-nav .nav-header h3 {
|
|
color: #e8edf4 !important;
|
|
opacity: 1 !important;
|
|
text-shadow: none !important;
|
|
}
|
|
|
|
.sidebar-nav .nav-link {
|
|
color: #8892a4 !important;
|
|
opacity: 1 !important;
|
|
text-shadow: none !important;
|
|
pointer-events: auto !important;
|
|
cursor: pointer !important;
|
|
-webkit-tap-highlight-color: rgba(0, 255, 200, 0.2) !important;
|
|
}
|
|
|
|
.sidebar-nav .nav-link:hover,
|
|
.sidebar-nav .nav-link:active {
|
|
color: #00ffc8 !important;
|
|
opacity: 1 !important;
|
|
}
|
|
|
|
.sidebar-nav .nav-section-header {
|
|
color: #8892a4 !important;
|
|
opacity: 1 !important;
|
|
text-shadow: none !important;
|
|
}
|
|
|
|
.main-content {
|
|
margin-top: 0;
|
|
}
|
|
}
|
|
|
|
@media (min-width: 1201px) {
|
|
.sidebar-nav {
|
|
position: sticky !important;
|
|
top: 2rem !important;
|
|
left: auto !important;
|
|
width: auto !important;
|
|
height: fit-content !important;
|
|
max-height: calc(100vh - 4rem) !important;
|
|
margin: 0 !important;
|
|
padding: 1.5rem !important;
|
|
border-radius: 16px !important;
|
|
border: 1px solid var(--border-subtle) !important;
|
|
z-index: 100 !important;
|
|
opacity: 1 !important;
|
|
filter: none !important;
|
|
backdrop-filter: none !important;
|
|
-webkit-backdrop-filter: none !important;
|
|
transform: none !important;
|
|
will-change: auto !important;
|
|
isolation: auto !important;
|
|
background: var(--bg-card) !important;
|
|
visibility: visible !important;
|
|
}
|
|
}
|
|
|
|
@media (max-width: 768px) {
|
|
.container {
|
|
padding: 2rem 1rem;
|
|
}
|
|
|
|
.header-content {
|
|
padding: 2rem 1.5rem;
|
|
}
|
|
|
|
.header-title {
|
|
flex-direction: column;
|
|
align-items: flex-start;
|
|
gap: 0.75rem;
|
|
}
|
|
|
|
.logo-icon {
|
|
width: 48px;
|
|
height: 48px;
|
|
font-size: 1.5rem;
|
|
}
|
|
|
|
h1 {
|
|
font-size: 2.25rem;
|
|
}
|
|
|
|
.commands-grid {
|
|
grid-template-columns: 1fr;
|
|
}
|
|
|
|
.sidebar-nav {
|
|
padding: 1rem;
|
|
width: calc(100vw - 3rem);
|
|
left: calc(-100vw + 3rem);
|
|
}
|
|
|
|
.sidebar-nav.open {
|
|
left: 0;
|
|
}
|
|
|
|
.mobile-menu-toggle {
|
|
top: 1rem;
|
|
right: 1rem;
|
|
}
|
|
}
|
|
</style>
|
|
</head>
|
|
<body>
|
|
<div class="atmosphere"></div>
|
|
<div class="grid-overlay"></div>
|
|
|
|
<div class="sidebar-overlay"></div>
|
|
|
|
<button class="mobile-menu-toggle" aria-label="Toggle navigation menu">
|
|
<span class="hamburger"></span>
|
|
<span class="hamburger"></span>
|
|
<span class="hamburger"></span>
|
|
</button>
|
|
|
|
<div class="container">
|
|
<nav class="sidebar-nav">
|
|
<div class="nav-header">
|
|
<h3>Navigation</h3>
|
|
</div>
|
|
<ul class="nav-list">
|
|
<li class="nav-section-header">Commands</li>
|
|
<ul class="nav-sublist">
|
|
<li><a href="#commands-basic" class="nav-link nav-sublink">Basic Commands</a></li>
|
|
<li><a href="#commands-analytics" class="nav-link nav-sublink">Analytics</a></li>
|
|
<li><a href="#commands-emergency" class="nav-link nav-sublink">Emergency</a></li>
|
|
<li><a href="#commands-entertainment" class="nav-link nav-sublink">Entertainment</a></li>
|
|
<li><a href="#commands-fun" class="nav-link nav-sublink">Fun Commands</a></li>
|
|
<li><a href="#commands-games" class="nav-link nav-sublink">Games & Entertainment</a></li>
|
|
<li><a href="#commands-meshcore-info" class="nav-link nav-sublink">Mesh Network Info</a></li>
|
|
<li><a href="#commands-solar" class="nav-link nav-sublink">Solar & Astronomical</a></li>
|
|
<li><a href="#commands-sports" class="nav-link nav-sublink">Sports</a></li>
|
|
<li><a href="#commands-weather" class="nav-link nav-sublink">Weather Commands</a></li>
|
|
</ul>
|
|
<li class="nav-section-header">Channels</li>
|
|
<ul class="nav-sublist">
|
|
<li><a href="#channels" class="nav-link nav-sublink">Available Channels</a></li>
|
|
<li><a href="#channels-general" class="nav-link nav-sublink">General Channels</a></li>
|
|
<li><a href="#channels-emergency" class="nav-link nav-sublink">Emergency</a></li>
|
|
<li><a href="#channels-seattle" class="nav-link nav-sublink">Seattle</a></li>
|
|
<li><a href="#channels-sports" class="nav-link nav-sublink">Sports</a></li>
|
|
<li><a href="#channels-vancouver" class="nav-link nav-sublink">Vancouver</a></li>
|
|
</ul>
|
|
</ul>
|
|
</nav>
|
|
|
|
|
|
<div class="main-content">
|
|
<header>
|
|
<div class="header-content">
|
|
<div class="header-title">
|
|
<div class="logo-icon">🤖</div>
|
|
<h1>HowlBot🤖</h1>
|
|
</div>
|
|
<div class="intro">
|
|
Hi, I'm HowlBot🤖! I provide various commands to help you interact with the mesh network. Use the commands below to get started. I'll answer you if you send a message in <span class="channel-highlight">#BotTest</span> or <span class="channel-highlight">#bot</span>.
|
|
</div>
|
|
</div>
|
|
</header>
|
|
|
|
<main>
|
|
<div class="category-section" id="commands-basic">
|
|
<h2 class="category-title"><a href="#commands-basic" class="anchor-link">Basic Commands</a></h2>
|
|
<div class="commands-grid">
|
|
<div class="command-card">
|
|
<div class="command-header">
|
|
<h3 class="command-name">test</h3>
|
|
<div class="command-keywords">
|
|
<span class="keyword-badge">t</span>
|
|
</div>
|
|
</div>
|
|
<p class="command-description">Responds to 'test' or 't' with connection info</p>
|
|
</div>
|
|
<div class="command-card">
|
|
<div class="command-header">
|
|
<h3 class="command-name">hello</h3>
|
|
<div class="command-keywords">
|
|
<span class="keyword-badge">hi</span>
|
|
<span class="keyword-badge">hey</span>
|
|
<span class="keyword-badge">howdy</span>
|
|
<span class="keyword-badge">greetings</span>
|
|
<span class="keyword-badge">salutations</span>
|
|
<span class="keyword-badge keyword-expand" data-hidden="good morning,good afternoon,good evening,good night,yo,sup,whats up,what's up,morning,afternoon,evening,night,gday,g'day,hola,bonjour,ciao,namaste,aloha,shalom,konnichiwa,guten tag,buenos dias,buenas tardes,buenas noches" data-command="hello">+25 more</span>
|
|
</div>
|
|
</div>
|
|
<p class="command-description">Responds to greetings with robot-themed responses</p>
|
|
</div>
|
|
<div class="command-card">
|
|
<div class="command-header">
|
|
<h3 class="command-name">ping</h3>
|
|
</div>
|
|
<p class="command-description">Responds to 'ping' with 'Pong!'</p>
|
|
</div>
|
|
<div class="command-card">
|
|
<div class="command-header">
|
|
<h3 class="command-name">help</h3>
|
|
</div>
|
|
<p class="command-description">Shows commands. Use 'help <command>' for details.</p>
|
|
</div>
|
|
<div class="command-card">
|
|
<div class="command-header">
|
|
<h3 class="command-name">channels</h3>
|
|
<div class="command-keywords">
|
|
<span class="keyword-badge">channel</span>
|
|
</div>
|
|
</div>
|
|
<p class="command-description">Lists hashtag channels with sub-categories. Use 'channels' for general, 'channels list' for all categories, 'channels <category>' for specific categories, 'channels #channel' for specific channel info.</p>
|
|
</div>
|
|
<div class="command-card">
|
|
<div class="command-header">
|
|
<h3 class="command-name">cmd</h3>
|
|
<div class="command-keywords">
|
|
<span class="keyword-badge">commands</span>
|
|
</div>
|
|
</div>
|
|
<p class="command-description">Lists available commands in compact format</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="category-section" id="commands-analytics">
|
|
<h2 class="category-title"><a href="#commands-analytics" class="anchor-link">Analytics</a></h2>
|
|
<div class="commands-grid">
|
|
<div class="command-card">
|
|
<div class="command-header">
|
|
<h3 class="command-name">stats</h3>
|
|
</div>
|
|
<p class="command-description">Show statistics for past 24 hours. Use 'stats messages', 'stats channels', or 'stats paths' for specific stats.</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="category-section" id="commands-emergency">
|
|
<h2 class="category-title"><a href="#commands-emergency" class="anchor-link">Emergency</a></h2>
|
|
<div class="commands-grid">
|
|
<div class="command-card">
|
|
<div class="command-header">
|
|
<h3 class="command-name">alert</h3>
|
|
<div class="command-keywords">
|
|
<span class="keyword-badge">alerts</span>
|
|
<span class="keyword-badge">incident</span>
|
|
<span class="keyword-badge">incidents</span>
|
|
</div>
|
|
</div>
|
|
<p class="command-description">Get active emergency incidents (usage: alert seattle, alert 98258, alert 178th seattle, alert seattle all)</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="category-section" id="commands-entertainment">
|
|
<h2 class="category-title"><a href="#commands-entertainment" class="anchor-link">Entertainment</a></h2>
|
|
<div class="commands-grid">
|
|
<div class="command-card">
|
|
<div class="command-header">
|
|
<h3 class="command-name">joke</h3>
|
|
<div class="command-keywords">
|
|
<span class="keyword-badge">jokes</span>
|
|
</div>
|
|
</div>
|
|
<p class="command-description">Get a random joke or joke from specific category (usage: joke [category])</p>
|
|
<div class="command-channels">Channel: #jokes</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="category-section" id="commands-fun">
|
|
<h2 class="category-title"><a href="#commands-fun" class="anchor-link">Fun Commands</a></h2>
|
|
<div class="commands-grid">
|
|
<div class="command-card">
|
|
<div class="command-header">
|
|
<h3 class="command-name">hacker</h3>
|
|
<div class="command-keywords">
|
|
<span class="keyword-badge">sudo</span>
|
|
<span class="keyword-badge">ps aux</span>
|
|
<span class="keyword-badge">grep</span>
|
|
<span class="keyword-badge">ls -l</span>
|
|
<span class="keyword-badge">ls -la</span>
|
|
<span class="keyword-badge keyword-expand" data-hidden="echo $PATH,rm,rm -rf,cat,whoami,top,htop,netstat,ss,kill,killall,chmod,find,history,passwd,su,ssh,wget,curl,df -h,free,ifconfig,ip addr,uname -a" data-command="hacker">+24 more</span>
|
|
</div>
|
|
</div>
|
|
<p class="command-description">Simulates hacking a supervillain's mainframe with hilarious error messages</p>
|
|
</div>
|
|
<div class="command-card">
|
|
<div class="command-header">
|
|
<h3 class="command-name">dadjoke</h3>
|
|
<div class="command-keywords">
|
|
<span class="keyword-badge">dad joke</span>
|
|
<span class="keyword-badge">dadjokes</span>
|
|
<span class="keyword-badge">dad jokes</span>
|
|
</div>
|
|
</div>
|
|
<p class="command-description">Get a random dad joke from icanhazdadjoke.com</p>
|
|
<div class="command-channels">Channel: #jokes</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="category-section" id="commands-games">
|
|
<h2 class="category-title"><a href="#commands-games" class="anchor-link">Games & Entertainment</a></h2>
|
|
<div class="commands-grid">
|
|
<div class="command-card">
|
|
<div class="command-header">
|
|
<h3 class="command-name">dice</h3>
|
|
</div>
|
|
<p class="command-description">Roll dice for D&D and tabletop games. Use 'dice' for d6, 'dice d20' for d20, 'dice 2d6' for 2d6, 'dice d10 d6' for mixed dice, 'dice decade' for decade die (00-90), etc.</p>
|
|
</div>
|
|
<div class="command-card">
|
|
<div class="command-header">
|
|
<h3 class="command-name">magic8</h3>
|
|
</div>
|
|
<p class="command-description">Emulates the classic Magic 8-ball toy'</p>
|
|
</div>
|
|
<div class="command-card">
|
|
<div class="command-header">
|
|
<h3 class="command-name">roll</h3>
|
|
</div>
|
|
<p class="command-description">Roll a random number between 1 and X (default 100). Use 'roll' for 1-100, 'roll 50' for 1-50, etc.</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="category-section" id="commands-meshcore-info">
|
|
<h2 class="category-title"><a href="#commands-meshcore-info" class="anchor-link">Mesh Network Info</a></h2>
|
|
<div class="commands-grid">
|
|
<div class="command-card">
|
|
<div class="command-header">
|
|
<h3 class="command-name">path</h3>
|
|
<div class="command-keywords">
|
|
<span class="keyword-badge">decode</span>
|
|
<span class="keyword-badge">route</span>
|
|
<span class="keyword-badge">p</span>
|
|
</div>
|
|
</div>
|
|
<p class="command-description">Decode hex path data to show which repeaters were involved in message routing</p>
|
|
</div>
|
|
<div class="command-card">
|
|
<div class="command-header">
|
|
<h3 class="command-name">prefix</h3>
|
|
<div class="command-keywords">
|
|
<span class="keyword-badge">repeater</span>
|
|
<span class="keyword-badge">lookup</span>
|
|
</div>
|
|
</div>
|
|
<p class="command-description">Look up repeaters by two-character prefix (e.g., 'prefix 1A')</p>
|
|
</div>
|
|
<div class="command-card">
|
|
<div class="command-header">
|
|
<h3 class="command-name">multitest</h3>
|
|
<div class="command-keywords">
|
|
<span class="keyword-badge">mt</span>
|
|
</div>
|
|
</div>
|
|
<p class="command-description">Listens for 6 seconds and collects all unique paths from incoming messages</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="category-section" id="commands-solar">
|
|
<h2 class="category-title"><a href="#commands-solar" class="anchor-link">Solar & Astronomical</a></h2>
|
|
<div class="commands-grid">
|
|
<div class="command-card">
|
|
<div class="command-header">
|
|
<h3 class="command-name">hfcond</h3>
|
|
</div>
|
|
<p class="command-description">Get HF band conditions for ham radio</p>
|
|
</div>
|
|
<div class="command-card">
|
|
<div class="command-header">
|
|
<h3 class="command-name">satpass</h3>
|
|
</div>
|
|
<p class="command-description">Get satellite pass info: satpass <NORAD_number_or_shortcut> [visual]</p>
|
|
</div>
|
|
<div class="command-card">
|
|
<div class="command-header">
|
|
<h3 class="command-name">moon</h3>
|
|
</div>
|
|
<p class="command-description">Get moon phase, rise/set times and position</p>
|
|
</div>
|
|
<div class="command-card">
|
|
<div class="command-header">
|
|
<h3 class="command-name">sun</h3>
|
|
</div>
|
|
<p class="command-description">Get sunrise/sunset times</p>
|
|
</div>
|
|
<div class="command-card">
|
|
<div class="command-header">
|
|
<h3 class="command-name">solar</h3>
|
|
</div>
|
|
<p class="command-description">Get current solar conditions and HF band info</p>
|
|
</div>
|
|
<div class="command-card">
|
|
<div class="command-header">
|
|
<h3 class="command-name">solarforecast</h3>
|
|
<div class="command-keywords">
|
|
<span class="keyword-badge">sf</span>
|
|
</div>
|
|
</div>
|
|
<p class="command-description">Get solar panel production forecast (usage: sf <location|repeater_name|coordinates|zipcode> [panel_size] [azimuth, 0=south] [angle])</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="category-section" id="commands-sports">
|
|
<h2 class="category-title"><a href="#commands-sports" class="anchor-link">Sports</a></h2>
|
|
<div class="commands-grid">
|
|
<div class="command-card">
|
|
<div class="command-header">
|
|
<h3 class="command-name">sports</h3>
|
|
<div class="command-keywords">
|
|
<span class="keyword-badge">score</span>
|
|
<span class="keyword-badge">scores</span>
|
|
</div>
|
|
</div>
|
|
<p class="command-description">Get sports scores and schedules (usage: sports [team/league])</p>
|
|
<div class="command-channels">Channels: #BotTest, #bot, #sounders, #seahawks</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="category-section" id="commands-weather">
|
|
<h2 class="category-title"><a href="#commands-weather" class="anchor-link">Weather Commands</a></h2>
|
|
<div class="commands-grid">
|
|
<div class="command-card">
|
|
<div class="command-header">
|
|
<h3 class="command-name">wx</h3>
|
|
<div class="command-keywords">
|
|
<span class="keyword-badge">weather</span>
|
|
<span class="keyword-badge">wxa</span>
|
|
<span class="keyword-badge">wxalert</span>
|
|
</div>
|
|
</div>
|
|
<p class="command-description">Get weather information for a zip code (usage: wx 12345)</p>
|
|
</div>
|
|
<div class="command-card">
|
|
<div class="command-header">
|
|
<h3 class="command-name">aqi</h3>
|
|
<div class="command-keywords">
|
|
<span class="keyword-badge">air</span>
|
|
<span class="keyword-badge">airquality</span>
|
|
<span class="keyword-badge">air_quality</span>
|
|
</div>
|
|
</div>
|
|
<p class="command-description">Get Air Quality Index for a location (usage: aqi seattle, aqi greenwood, aqi vancouver canada, aqi 47.6,-122.3, or aqi help)</p>
|
|
</div>
|
|
<div class="command-card">
|
|
<div class="command-header">
|
|
<h3 class="command-name">gwx</h3>
|
|
<div class="command-keywords">
|
|
<span class="keyword-badge">globalweather</span>
|
|
<span class="keyword-badge">gwxa</span>
|
|
</div>
|
|
</div>
|
|
<p class="command-description">Get weather information for any global location (usage: gwx Tokyo)</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="category-section" id="channels">
|
|
<h2 class="category-title"><a href="#channels" class="anchor-link">Available Channels</a></h2>
|
|
<p class="channels-intro">These are semi-public channels that are in use on our local mesh! Join them to connect with others with common interests! <br/> To add these channels to your client, click on the three dot menu and select "Add Channel".</p>
|
|
<div class="channel-category" id="channels-general">
|
|
<h3 class="channel-category-title"><a href="#channels-general" class="anchor-link">General Channels</a></h3>
|
|
<div class="channels-grid">
|
|
<div class="channel-card">
|
|
<div class="channel-name">#bot</div>
|
|
<div class="channel-description">Channel for bot testing, diagnostics, and bot-related chat</div>
|
|
</div>
|
|
<div class="channel-card">
|
|
<div class="channel-name">#cats</div>
|
|
<div class="channel-description">Cat facts, stories, and feline-related conversation</div>
|
|
</div>
|
|
<div class="channel-card">
|
|
<div class="channel-name">#dev</div>
|
|
<div class="channel-description">Mesh developer chat for the Cascadia region</div>
|
|
</div>
|
|
<div class="channel-card">
|
|
<div class="channel-name">#eastside</div>
|
|
<div class="channel-description">Bellevue, Redmond, Kirkland, etc. chat</div>
|
|
</div>
|
|
<div class="channel-card">
|
|
<div class="channel-name">#emergency</div>
|
|
<div class="channel-description">Channel for emergency communications and urgent information</div>
|
|
</div>
|
|
<div class="channel-card">
|
|
<div class="channel-name">#hamradio</div>
|
|
<div class="channel-description">Amateur radio topics, licensing, and general ham discussion</div>
|
|
</div>
|
|
<div class="channel-card">
|
|
<div class="channel-name">#mesh</div>
|
|
<div class="channel-description">Mesh networking topics, node setup, and troubleshooting</div>
|
|
</div>
|
|
<div class="channel-card">
|
|
<div class="channel-name">#olympia</div>
|
|
<div class="channel-description">Olympia, WA chat</div>
|
|
</div>
|
|
<div class="channel-card">
|
|
<div class="channel-name">#pierce</div>
|
|
<div class="channel-description">Pierce County, WA chat</div>
|
|
</div>
|
|
<div class="channel-card">
|
|
<div class="channel-name">#queer</div>
|
|
<div class="channel-description">LGBTQ+ community chat and support</div>
|
|
</div>
|
|
<div class="channel-card">
|
|
<div class="channel-name">#seattle</div>
|
|
<div class="channel-description">Seattle, WA chat</div>
|
|
</div>
|
|
<div class="channel-card">
|
|
<div class="channel-name">#snoco</div>
|
|
<div class="channel-description">Snohomish County, WA chat</div>
|
|
</div>
|
|
<div class="channel-card">
|
|
<div class="channel-name">#sounders</div>
|
|
<div class="channel-description">Seattle Sounders FC soccer discussion and updates</div>
|
|
</div>
|
|
<div class="channel-card">
|
|
<div class="channel-name">#tacoma</div>
|
|
<div class="channel-description">Tacoma, WA chat</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="channel-category" id="channels-emergency">
|
|
<h3 class="channel-category-title"><a href="#channels-emergency" class="anchor-link">Emergency</a></h3>
|
|
<div class="channels-grid">
|
|
<div class="channel-card">
|
|
<div class="channel-name">#emergency</div>
|
|
<div class="channel-description">Emergency communications and alerts</div>
|
|
</div>
|
|
<div class="channel-card">
|
|
<div class="channel-name">#hamradio</div>
|
|
<div class="channel-description">Amateur radio emergency net coordination</div>
|
|
</div>
|
|
<div class="channel-card">
|
|
<div class="channel-name">#weather</div>
|
|
<div class="channel-description">Weather updates and local conditions</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="channel-category" id="channels-seattle">
|
|
<h3 class="channel-category-title"><a href="#channels-seattle" class="anchor-link">Seattle</a></h3>
|
|
<div class="channels-grid">
|
|
<div class="channel-card">
|
|
<div class="channel-name">#capitolhill</div>
|
|
<div class="channel-description">Capitol Hill neighborhood chat and local info</div>
|
|
</div>
|
|
<div class="channel-card">
|
|
<div class="channel-name">#kraken</div>
|
|
<div class="channel-description">Seattle Kraken chat for Seattle area users</div>
|
|
</div>
|
|
<div class="channel-card">
|
|
<div class="channel-name">#mariners</div>
|
|
<div class="channel-description">Seattle Mariners chat for Seattle area users</div>
|
|
</div>
|
|
<div class="channel-card">
|
|
<div class="channel-name">#queer</div>
|
|
<div class="channel-description">LGBTQ+ chat for Seattle area</div>
|
|
</div>
|
|
<div class="channel-card">
|
|
<div class="channel-name">#seahawks</div>
|
|
<div class="channel-description">Seattle Seahawks chat for Seattle area users</div>
|
|
</div>
|
|
<div class="channel-card">
|
|
<div class="channel-name">#seattle</div>
|
|
<div class="channel-description">General chat for Seattle area</div>
|
|
</div>
|
|
<div class="channel-card">
|
|
<div class="channel-name">#sounders</div>
|
|
<div class="channel-description">Seattle Sounders FC chat for Seattle area users</div>
|
|
</div>
|
|
<div class="channel-card">
|
|
<div class="channel-name">#tech</div>
|
|
<div class="channel-description">Technology topics and tech chat for Seattle area</div>
|
|
</div>
|
|
<div class="channel-card">
|
|
<div class="channel-name">#transit</div>
|
|
<div class="channel-description">Seattle Transit chat and bus schedules</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="channel-category" id="channels-sports">
|
|
<h3 class="channel-category-title"><a href="#channels-sports" class="anchor-link">Sports</a></h3>
|
|
<div class="channels-grid">
|
|
<div class="channel-card">
|
|
<div class="channel-name">#huskies</div>
|
|
<div class="channel-description">Washington Huskies sports discussion</div>
|
|
</div>
|
|
<div class="channel-card">
|
|
<div class="channel-name">#kraken</div>
|
|
<div class="channel-description">Seattle Kraken NHL hockey discussion</div>
|
|
</div>
|
|
<div class="channel-card">
|
|
<div class="channel-name">#mariners</div>
|
|
<div class="channel-description">Seattle Mariners MLB baseball chat</div>
|
|
</div>
|
|
<div class="channel-card">
|
|
<div class="channel-name">#reign</div>
|
|
<div class="channel-description">OL Reign NWSL soccer discussion</div>
|
|
</div>
|
|
<div class="channel-card">
|
|
<div class="channel-name">#seahawks</div>
|
|
<div class="channel-description">Seattle Seahawks NFL football discussion</div>
|
|
</div>
|
|
<div class="channel-card">
|
|
<div class="channel-name">#sounders</div>
|
|
<div class="channel-description">Seattle Sounders FC soccer chat</div>
|
|
</div>
|
|
<div class="channel-card">
|
|
<div class="channel-name">#storm</div>
|
|
<div class="channel-description">Seattle Storm WNBA basketball chat</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="channel-category" id="channels-vancouver">
|
|
<h3 class="channel-category-title"><a href="#channels-vancouver" class="anchor-link">Vancouver</a></h3>
|
|
<div class="channels-grid">
|
|
<div class="channel-card">
|
|
<div class="channel-name">#canucks</div>
|
|
<div class="channel-description">Vancouver Canucks NHL hockey discussion</div>
|
|
</div>
|
|
<div class="channel-card">
|
|
<div class="channel-name">#vancouverbc</div>
|
|
<div class="channel-description">General chat for Vancouver, BC area</div>
|
|
</div>
|
|
<div class="channel-card">
|
|
<div class="channel-name">#whitecaps</div>
|
|
<div class="channel-description">Vancouver Whitecaps MLS soccer chat</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
</main>
|
|
|
|
<footer>
|
|
<p>Generated command reference for HowlBot🤖</p>
|
|
</footer>
|
|
</div>
|
|
</div>
|
|
|
|
<script>
|
|
// Handle mobile menu toggle
|
|
(function() {
|
|
'use strict';
|
|
|
|
const menuToggle = document.querySelector('.mobile-menu-toggle');
|
|
const sidebar = document.querySelector('.sidebar-nav');
|
|
const overlay = document.querySelector('.sidebar-overlay');
|
|
|
|
if (menuToggle && sidebar) {
|
|
function toggleMenu() {
|
|
const isOpen = sidebar.classList.contains('open');
|
|
if (isOpen) {
|
|
menuToggle.classList.remove('active');
|
|
sidebar.classList.remove('open');
|
|
if (overlay) {
|
|
overlay.classList.remove('visible');
|
|
}
|
|
} else {
|
|
menuToggle.classList.add('active');
|
|
sidebar.classList.add('open');
|
|
if (overlay) {
|
|
overlay.classList.add('visible');
|
|
}
|
|
}
|
|
}
|
|
|
|
function closeMenu() {
|
|
menuToggle.classList.remove('active');
|
|
sidebar.classList.remove('open');
|
|
if (overlay) {
|
|
overlay.classList.remove('visible');
|
|
}
|
|
}
|
|
|
|
menuToggle.addEventListener('click', function(e) {
|
|
e.stopPropagation();
|
|
e.preventDefault();
|
|
toggleMenu();
|
|
return false;
|
|
});
|
|
|
|
// Handle overlay clicks - overlay now only covers area after sidebar
|
|
if (overlay) {
|
|
overlay.addEventListener('click', function(e) {
|
|
closeMenu();
|
|
});
|
|
}
|
|
|
|
// Handle nav link clicks - don't prevent default, let browser handle navigation
|
|
const navLinks = sidebar.querySelectorAll('.nav-link');
|
|
navLinks.forEach(link => {
|
|
link.addEventListener('click', function(e) {
|
|
if (window.innerWidth <= 1200) {
|
|
// Close menu after a delay to allow navigation
|
|
setTimeout(function() {
|
|
closeMenu();
|
|
}, 200);
|
|
}
|
|
});
|
|
});
|
|
}
|
|
|
|
// Handle keyword expansion
|
|
const expandButtons = document.querySelectorAll('.keyword-expand');
|
|
|
|
expandButtons.forEach(button => {
|
|
button.addEventListener('click', function() {
|
|
const hiddenAliases = this.getAttribute('data-hidden').split(',');
|
|
const commandKeywords = this.closest('.command-keywords');
|
|
|
|
// Hide the expand button
|
|
this.classList.add('expanded');
|
|
|
|
// Add hidden aliases as visible badges
|
|
hiddenAliases.forEach(alias => {
|
|
const badge = document.createElement('span');
|
|
badge.className = 'keyword-badge keyword-hidden visible';
|
|
badge.textContent = alias.trim();
|
|
commandKeywords.appendChild(badge);
|
|
});
|
|
});
|
|
});
|
|
})();
|
|
</script>
|
|
</body>
|
|
</html> |