feat: gamepad navigation rewrite, focus styling, container grid system
- Rewrite useControllerNav.ts with clean console-style navigation: Sidebar (up/down wrap, right→containers, left→nothing), Container tile grid (spatial nav, no wrap at edges), Nav bar support (up from containers, down to grid), Inner controls (enter drills in, escape exits, trapped arrows) - Add data-controller-container to Mesh, Fleet, Settings pages - Fix Home.vue fragment (modals outside root div) causing Vue warnings - Remove skip-to-content link (handled by controller nav) - Orange ambient glow focus styling matching glass aesthetic - Disable PWA service worker in dev mode (fixes HMR caching) - Add gamepad-nav skill and GAMEPAD-NAV-MAP.md spec document - 39 tests covering all navigation patterns Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.6
parent
1444bcb0c4
commit
aada19754d
+38
-17
@@ -27,7 +27,8 @@
|
||||
overflow: hidden;
|
||||
z-index: 9999;
|
||||
}
|
||||
.skip-to-content:focus {
|
||||
.skip-to-content:focus,
|
||||
.skip-to-content:focus-visible {
|
||||
position: fixed;
|
||||
top: 12px;
|
||||
left: 50%;
|
||||
@@ -44,14 +45,32 @@
|
||||
font-weight: 500;
|
||||
text-decoration: none;
|
||||
backdrop-filter: blur(12px);
|
||||
outline: none;
|
||||
}
|
||||
|
||||
/* Controller / keyboard navigation - orange border (Archipelago brand) */
|
||||
/* Controller / keyboard navigation — only for elements without their own focus styles.
|
||||
Elements with existing hover/active styles (glass-button, sidebar-nav-item, etc.) keep theirs. */
|
||||
*:focus-visible {
|
||||
outline: none;
|
||||
border-color: rgba(251, 146, 60, 0.8) !important;
|
||||
box-shadow: 0 0 0 2px rgba(251, 146, 60, 0.7), 0 0 16px rgba(251, 146, 60, 0.25);
|
||||
transition: box-shadow 0.2s ease, border-color 0.2s ease;
|
||||
box-shadow:
|
||||
0 0 0 1px rgba(251, 146, 60, 0.4),
|
||||
0 0 12px rgba(251, 146, 60, 0.2),
|
||||
0 0 24px rgba(251, 146, 60, 0.08);
|
||||
transition: box-shadow 0.2s ease;
|
||||
}
|
||||
|
||||
/* Elements with existing styles: suppress the global glow, let their own styles handle it */
|
||||
.glass-button:focus-visible,
|
||||
.glass-card:focus-visible,
|
||||
.sidebar-nav-item:focus-visible,
|
||||
.path-action-button:focus-visible,
|
||||
.path-option-card:focus-visible,
|
||||
.mode-switcher-btn:focus-visible,
|
||||
.kiosk-app-tile:focus-visible,
|
||||
input:focus-visible,
|
||||
textarea:focus-visible,
|
||||
select:focus-visible {
|
||||
box-shadow: unset;
|
||||
}
|
||||
|
||||
/* Mobile touch targets — ensure tappable elements meet 44px minimum */
|
||||
@@ -99,13 +118,15 @@ input[type="radio"]:active + * {
|
||||
transition: transform 0.2s ease, box-shadow 0.2s ease;
|
||||
}
|
||||
|
||||
/* Containers get subtle grow + orange glow when focused (gamepad selection) */
|
||||
/* Containers: console-style focus — subtle lift + ambient glow through glass */
|
||||
[data-controller-container]:focus-visible {
|
||||
transform: scale(1.02);
|
||||
outline: none;
|
||||
transform: scale(1.01) translateZ(0);
|
||||
box-shadow:
|
||||
0 0 0 2px rgba(251, 146, 60, 0.7),
|
||||
0 0 24px rgba(251, 146, 60, 0.2),
|
||||
inset 0 0 24px rgba(255, 255, 255, 0.03);
|
||||
0 0 0 1px rgba(251, 146, 60, 0.35),
|
||||
0 4px 20px rgba(251, 146, 60, 0.12),
|
||||
0 0 40px rgba(251, 146, 60, 0.06),
|
||||
inset 0 1px 0 rgba(251, 146, 60, 0.1);
|
||||
}
|
||||
|
||||
/* Global glassmorphism utilities */
|
||||
@@ -977,11 +998,9 @@ input[type="radio"]:active + * {
|
||||
transition: transform 0.2s ease, box-shadow 0.2s ease;
|
||||
}
|
||||
.sidebar-nav-item:focus-visible {
|
||||
transform: scale(1.02) !important;
|
||||
box-shadow:
|
||||
0 0 0 2px rgba(251, 146, 60, 0.7),
|
||||
0 0 24px rgba(251, 146, 60, 0.2),
|
||||
inset 0 0 24px rgba(255, 255, 255, 0.03) !important;
|
||||
outline: none !important;
|
||||
background: rgba(255, 255, 255, 0.1) !important;
|
||||
color: white !important;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1303,7 +1322,8 @@ html:has(body.video-background-active)::before {
|
||||
background: rgba(255, 255, 255, 0.1);
|
||||
}
|
||||
.cloud-file-item:focus-visible {
|
||||
box-shadow: 0 0 0 2px rgba(251, 146, 60, 0.7), 0 0 16px rgba(251, 146, 60, 0.25);
|
||||
outline: none;
|
||||
box-shadow: 0 0 0 1.5px rgba(251, 146, 60, 0.5), 0 0 16px rgba(251, 146, 60, 0.12);
|
||||
}
|
||||
|
||||
.cloud-file-item-thumb {
|
||||
@@ -1481,7 +1501,8 @@ html:has(body.video-background-active)::before {
|
||||
transform: translateY(0);
|
||||
}
|
||||
.cloud-grid-card:focus-visible {
|
||||
box-shadow: 0 0 0 2px rgba(251, 146, 60, 0.7), 0 0 16px rgba(251, 146, 60, 0.25);
|
||||
outline: none;
|
||||
box-shadow: 0 0 0 1.5px rgba(251, 146, 60, 0.5), 0 0 16px rgba(251, 146, 60, 0.12);
|
||||
}
|
||||
|
||||
.cloud-grid-card-cover {
|
||||
|
||||
Reference in New Issue
Block a user