Improve cross-app UX: accessibility, mode consistency, and render performance

This commit is contained in:
Smittix
2026-02-19 22:32:08 +00:00
parent 40cc7a5058
commit dc01b20b98
11 changed files with 1051 additions and 507 deletions
+24 -18
View File
@@ -17,17 +17,17 @@
{% macro mode_item(mode, label, icon_svg, href=None) -%}
{%- set is_active = 'active' if active_mode == mode else '' -%}
{%- if href %}
<a href="{{ href }}" class="mode-nav-btn {{ is_active }}" style="text-decoration: none;">
<a href="{{ href }}" class="mode-nav-btn {{ is_active }}" style="text-decoration: none;" data-mode="{{ mode }}" data-mode-label="{{ label }}" aria-label="{{ label }} mode">
<span class="nav-icon icon">{{ icon_svg | safe }}</span>
<span class="nav-label">{{ label }}</span>
</a>
{%- elif is_index_page %}
<button class="mode-nav-btn {{ is_active }}" onclick="switchMode('{{ mode }}')">
<button type="button" class="mode-nav-btn {{ is_active }}" data-mode="{{ mode }}" data-mode-label="{{ label }}" aria-label="{{ label }} mode" onclick="switchMode('{{ mode }}')">
<span class="nav-icon icon">{{ icon_svg | safe }}</span>
<span class="nav-label">{{ label }}</span>
</button>
{%- else %}
<a href="/?mode={{ mode }}" class="mode-nav-btn {{ is_active }}" style="text-decoration: none;">
<a href="/?mode={{ mode }}" class="mode-nav-btn {{ is_active }}" style="text-decoration: none;" data-mode="{{ mode }}" data-mode-label="{{ label }}" aria-label="{{ label }} mode">
<span class="nav-icon icon">{{ icon_svg | safe }}</span>
<span class="nav-label">{{ label }}</span>
</a>
@@ -37,15 +37,15 @@
{% macro mobile_item(mode, label, icon_svg, href=None) -%}
{%- set is_active = 'active' if active_mode == mode else '' -%}
{%- if href %}
<a href="{{ href }}" class="mobile-nav-btn {{ is_active }}" style="text-decoration: none;">
<a href="{{ href }}" class="mobile-nav-btn {{ is_active }}" style="text-decoration: none;" data-mode="{{ mode }}" data-mode-label="{{ label }}" aria-label="{{ label }} mode">
<span class="icon icon--sm">{{ icon_svg | safe }}</span> {{ label }}
</a>
{%- elif is_index_page %}
<button class="mobile-nav-btn {{ is_active }}" data-mode="{{ mode }}" onclick="switchMode('{{ mode }}')">
<button type="button" class="mobile-nav-btn {{ is_active }}" data-mode="{{ mode }}" data-mode-label="{{ label }}" aria-label="{{ label }} mode" onclick="switchMode('{{ mode }}')">
<span class="icon icon--sm">{{ icon_svg | safe }}</span> {{ label }}
</button>
{%- else %}
<a href="/?mode={{ mode }}" class="mobile-nav-btn {{ is_active }}" style="text-decoration: none;">
<a href="/?mode={{ mode }}" class="mobile-nav-btn {{ is_active }}" style="text-decoration: none;" data-mode="{{ mode }}" data-mode-label="{{ label }}" aria-label="{{ label }} mode">
<span class="icon icon--sm">{{ icon_svg | safe }}</span> {{ label }}
</a>
{%- endif %}
@@ -55,7 +55,7 @@
<nav class="mode-nav" id="mainNav">
{# Signals Group #}
<div class="mode-nav-dropdown" data-group="signals">
<button class="mode-nav-dropdown-btn"{% if is_index_page %} onclick="toggleNavDropdown('signals')"{% endif %}>
<button type="button" class="mode-nav-dropdown-btn"{% if is_index_page %} onclick="toggleNavDropdown('signals')"{% endif %}>
<span class="nav-icon icon"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M2 12h4l3-8 3 16 3-8h4"/><path d="M22 12h-1"/><path d="M1 12h1"/></svg></span>
<span class="nav-label">Signals</span>
<span class="dropdown-arrow icon"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="6 9 12 15 18 9"/></svg></span>
@@ -72,7 +72,7 @@
{# Tracking Group #}
<div class="mode-nav-dropdown" data-group="tracking">
<button class="mode-nav-dropdown-btn"{% if is_index_page %} onclick="toggleNavDropdown('tracking')"{% endif %}>
<button type="button" class="mode-nav-dropdown-btn"{% if is_index_page %} onclick="toggleNavDropdown('tracking')"{% endif %}>
<span class="nav-icon icon"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M21 10c0 7-9 13-9 13s-9-6-9-13a9 9 0 0 1 18 0z"/><circle cx="12" cy="10" r="3"/></svg></span>
<span class="nav-label">Tracking</span>
<span class="dropdown-arrow icon"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="6 9 12 15 18 9"/></svg></span>
@@ -88,7 +88,7 @@
{# Space Group #}
<div class="mode-nav-dropdown" data-group="space">
<button class="mode-nav-dropdown-btn"{% if is_index_page %} onclick="toggleNavDropdown('space')"{% endif %}>
<button type="button" class="mode-nav-dropdown-btn"{% if is_index_page %} onclick="toggleNavDropdown('space')"{% endif %}>
<span class="nav-icon icon"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M4.5 16.5c-1.5 1.26-2 5-2 5s3.74-.5 5-2c.71-.84.7-2.13-.09-2.91a2.18 2.18 0 0 0-2.91-.09z"/><path d="m12 15-3-3a22 22 0 0 1 2-3.95A12.88 12.88 0 0 1 22 2c0 2.72-.78 7.5-6 11a22.35 22.35 0 0 1-4 2z"/><path d="M9 12H4s.55-3.03 2-4c1.62-1.08 5 0 5 0"/><path d="M12 15v5s3.03-.55 4-2c1.08-1.62 0-5 0-5"/></svg></span>
<span class="nav-label">Space</span>
<span class="dropdown-arrow icon"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="6 9 12 15 18 9"/></svg></span>
@@ -109,7 +109,7 @@
{# Wireless Group #}
<div class="mode-nav-dropdown" data-group="wireless">
<button class="mode-nav-dropdown-btn"{% if is_index_page %} onclick="toggleNavDropdown('wireless')"{% endif %}>
<button type="button" class="mode-nav-dropdown-btn"{% if is_index_page %} onclick="toggleNavDropdown('wireless')"{% endif %}>
<span class="nav-icon icon"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M5 12.55a11 11 0 0 1 14.08 0"/><path d="M1.42 9a16 16 0 0 1 21.16 0"/><path d="M8.53 16.11a6 6 0 0 1 6.95 0"/><circle cx="12" cy="20" r="1" fill="currentColor" stroke="none"/></svg></span>
<span class="nav-label">Wireless</span>
<span class="dropdown-arrow icon"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="6 9 12 15 18 9"/></svg></span>
@@ -125,7 +125,7 @@
{# Intel Group #}
<div class="mode-nav-dropdown" data-group="intel">
<button class="mode-nav-dropdown-btn"{% if is_index_page %} onclick="toggleNavDropdown('intel')"{% endif %}>
<button type="button" class="mode-nav-dropdown-btn"{% if is_index_page %} onclick="toggleNavDropdown('intel')"{% endif %}>
<span class="nav-icon icon"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z"/><circle cx="12" cy="12" r="3"/></svg></span>
<span class="nav-label">Intel</span>
<span class="dropdown-arrow icon"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="6 9 12 15 18 9"/></svg></span>
@@ -160,11 +160,11 @@
</a>
<div class="nav-divider"></div>
<div class="nav-tools">
<button class="nav-tool-btn" onclick="toggleAnimations()" title="Toggle Animations">
<button type="button" class="nav-tool-btn" onclick="toggleAnimations()" title="Toggle Animations" aria-label="Toggle animations">
<span class="icon-effects-on icon"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z"/></svg></span>
<span class="icon-effects-off icon"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z"/><line x1="2" y1="2" x2="22" y2="22"/></svg></span>
</button>
<button class="nav-tool-btn" onclick="toggleTheme()" title="Toggle Light/Dark Theme">
<button type="button" class="nav-tool-btn" onclick="toggleTheme()" title="Toggle Light/Dark Theme" aria-label="Toggle theme">
<span class="icon-moon icon"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z"/></svg></span>
<span class="icon-sun icon"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="5"/><line x1="12" y1="1" x2="12" y2="3"/><line x1="12" y1="21" x2="12" y2="23"/><line x1="4.22" y1="4.22" x2="5.64" y2="5.64"/><line x1="18.36" y1="18.36" x2="19.78" y2="19.78"/><line x1="1" y1="12" x2="3" y2="12"/><line x1="21" y1="12" x2="23" y2="12"/><line x1="4.22" y1="19.78" x2="5.64" y2="18.36"/><line x1="18.36" y1="5.64" x2="19.78" y2="4.22"/></svg></span>
</button>
@@ -174,11 +174,11 @@
<a href="/controller/manage" class="nav-tool-btn" title="Manage Remote Agents" style="text-decoration: none;">
<span class="icon"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="2" y="2" width="20" height="8" rx="2" ry="2"/><rect x="2" y="14" width="20" height="8" rx="2" ry="2"/><line x1="6" y1="6" x2="6.01" y2="6"/><line x1="6" y1="18" x2="6.01" y2="18"/></svg></span>
</a>
<button class="nav-tool-btn" onclick="showSettings()" title="Settings">
<button type="button" class="nav-tool-btn" onclick="showSettings()" title="Settings" aria-label="Open settings">
<span class="icon"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="3"/><path d="M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 0 1 0 2.83 2 2 0 0 1-2.83 0l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-2 2 2 2 0 0 1-2-2v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 0 1-2.83 0 2 2 0 0 1 0-2.83l.06-.06a1.65 1.65 0 0 0 .33-1.82 1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1-2-2 2 2 0 0 1 2-2h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 0 1 0-2.83 2 2 0 0 1 2.83 0l.06.06a1.65 1.65 0 0 0 1.82.33H9a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 2-2 2 2 0 0 1 2 2v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 0 1 2.83 0 2 2 0 0 1 0 2.83l-.06.06a1.65 1.65 0 0 0-.33 1.82V9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 2 2 2 2 0 0 1-2 2h-.09a1.65 1.65 0 0 0-1.51 1z"/></svg></span>
</button>
<button class="nav-tool-btn" onclick="showHelp()" title="Help & Documentation">?</button>
<button class="nav-tool-btn" onclick="logout(event)" title="Logout">
<button type="button" class="nav-tool-btn" onclick="showHelp()" title="Help & Documentation" aria-label="Open help">?</button>
<button type="button" class="nav-tool-btn" onclick="logout(event)" title="Logout" aria-label="Logout">
<span class="power-icon icon"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M9 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4"/><polyline points="16 17 21 12 16 7"/><line x1="21" y1="12" x2="9" y2="12"/></svg></span>
</button>
</div>
@@ -257,7 +257,8 @@
const current = html.getAttribute('data-animations') || 'on';
const next = current === 'on' ? 'off' : 'on';
html.setAttribute('data-animations', next);
localStorage.setItem('animations', next);
localStorage.setItem('intercept-animations', next);
localStorage.removeItem('animations');
};
}
@@ -316,7 +317,12 @@
document.documentElement.setAttribute('data-theme', savedTheme);
}
const savedAnimations = localStorage.getItem('intercept-animations');
const legacyAnimations = localStorage.getItem('animations');
const savedAnimations = localStorage.getItem('intercept-animations') || legacyAnimations;
if (legacyAnimations && !localStorage.getItem('intercept-animations')) {
localStorage.setItem('intercept-animations', legacyAnimations);
localStorage.removeItem('animations');
}
if (savedAnimations) {
document.documentElement.setAttribute('data-animations', savedAnimations);
}