diff --git a/frontend/src/components/CollageHero.vue b/frontend/src/components/CollageHero.vue index 538aeba..9234340 100644 --- a/frontend/src/components/CollageHero.vue +++ b/frontend/src/components/CollageHero.vue @@ -605,8 +605,8 @@ function handleItemClick(item: MediaItem, index: number) { pointer-events: none; } -:global(html[data-mouse-active="true"]) .collage-item:hover, -:global(html[data-mouse-active="false"]) .collage-item.nav-focused { +html.mouse-active .collage-item:hover, +html:not(.mouse-active) .collage-item.nav-focused { z-index: 10; } @@ -630,8 +630,8 @@ function handleItemClick(item: MediaItem, index: number) { } /* Show outline on hover and focus */ -:global(html[data-mouse-active="true"]) .collage-item:hover .hex-focus-outline, -:global(html[data-mouse-active="false"]) .collage-item.nav-focused .hex-focus-outline { +html.mouse-active .collage-item:hover .hex-focus-outline, +html:not(.mouse-active) .collage-item.nav-focused .hex-focus-outline { opacity: 1; } @@ -646,15 +646,15 @@ function handleItemClick(item: MediaItem, index: number) { } /* Brighter outline for keyboard focus */ -:global(html[data-mouse-active="false"]) .collage-item.nav-focused .hex-focus-outline polygon { +html:not(.mouse-active) .collage-item.nav-focused .hex-focus-outline polygon { stroke: #ffffff; stroke-width: 5; filter: drop-shadow(0 0 6px rgba(255, 255, 255, 0.8)); } /* Blinking effect on hover/focus */ -:global(html[data-mouse-active="true"]) .collage-item:hover .hex-focus-outline, -:global(html[data-mouse-active="false"]) .collage-item.nav-focused .hex-focus-outline { +html.mouse-active .collage-item:hover .hex-focus-outline, +html:not(.mouse-active) .collage-item.nav-focused .hex-focus-outline { animation: hex-outline-blink 1s ease-in-out infinite; } @@ -1035,8 +1035,8 @@ function handleItemClick(item: MediaItem, index: number) { white-space: nowrap; } -:global(html[data-mouse-active="true"]) .collage-item:not(.collage-featured):hover .collage-item-hover, -:global(html[data-mouse-active="false"]) .collage-item:not(.collage-featured).nav-focused .collage-item-hover { +html.mouse-active .collage-item:not(.collage-featured):hover .collage-item-hover, +html:not(.mouse-active) .collage-item:not(.collage-featured).nav-focused .collage-item-hover { opacity: 1; transform: translateX(-50%) translateY(0); } diff --git a/frontend/src/components/MediaCard.vue b/frontend/src/components/MediaCard.vue index 597a843..d630904 100644 --- a/frontend/src/components/MediaCard.vue +++ b/frontend/src/components/MediaCard.vue @@ -211,13 +211,13 @@ const matchedPeople = computed(() => { object-fit: cover; } -:global(html[data-mouse-active="true"]) .media-card:hover .card-focus-outline, -:global(html[data-mouse-active="false"]) .media-card.nav-focused .card-focus-outline { +html.mouse-active .media-card:hover .card-focus-outline, +html:not(.mouse-active) .media-card.nav-focused .card-focus-outline { opacity: 1; animation: card-outline-blink 1s ease-in-out infinite; } -:global(html[data-mouse-active="false"]) .media-card.nav-focused .card-focus-outline rect { +html:not(.mouse-active) .media-card.nav-focused .card-focus-outline rect { stroke: #ffffff; stroke-width: 5; filter: drop-shadow(0 0 6px rgba(255, 255, 255, 0.8)); diff --git a/frontend/src/components/MediaDetail.vue b/frontend/src/components/MediaDetail.vue index 0ca00af..31994de 100644 --- a/frontend/src/components/MediaDetail.vue +++ b/frontend/src/components/MediaDetail.vue @@ -813,12 +813,12 @@ function handleCastSelect(castName: string) { } .cast-card:focus-visible, -:global(html[data-mouse-active="false"]) .cast-card.nav-focused { +html:not(.mouse-active) .cast-card.nav-focused { outline: none; } .cast-card:focus-visible::after, -:global(html[data-mouse-active="false"]) .cast-card.nav-focused::after { +html:not(.mouse-active) .cast-card.nav-focused::after { border-width: 2px; } @@ -943,7 +943,7 @@ function handleCastSelect(castName: string) { cursor: pointer; } -:global(html[data-mouse-active="true"]) .showreel-image:hover { +html.mouse-active .showreel-image:hover { box-shadow: 0 4px 16px rgba(0, 0, 0, 0.5); } @@ -978,7 +978,7 @@ function handleCastSelect(castName: string) { transition: background 0.2s, border-color 0.2s; } -:global(html[data-mouse-active="true"]) .version-item:hover { +html.mouse-active .version-item:hover { background: rgba(255, 255, 255, 0.08); } @@ -1176,7 +1176,7 @@ function handleCastSelect(castName: string) { overflow: hidden; } -:global(html[data-mouse-active="true"]) .episode-item:hover { +html.mouse-active .episode-item:hover { background: rgba(255, 255, 255, 0.08); } @@ -1291,7 +1291,7 @@ function handleCastSelect(castName: string) { border: 1px solid transparent; } -:global(html[data-mouse-active="true"]) .release-item:hover { +html.mouse-active .release-item:hover { background: rgba(255, 255, 255, 0.06); } diff --git a/frontend/src/components/ReleaseVersionCard.vue b/frontend/src/components/ReleaseVersionCard.vue index 45ec1cf..1c2c939 100644 --- a/frontend/src/components/ReleaseVersionCard.vue +++ b/frontend/src/components/ReleaseVersionCard.vue @@ -312,7 +312,7 @@ function handleActivate(event: MouseEvent | KeyboardEvent) { grid-template-columns: minmax(0, 1fr) max-content max-content; } -:global(html[data-mouse-active="true"]) .version-row:hover { +html.mouse-active .version-row:hover { background: rgba(10, 14, 22, 0.28); border-color: rgba(255, 255, 255, 0.2); } @@ -322,7 +322,7 @@ function handleActivate(event: MouseEvent | KeyboardEvent) { background: rgba(10, 14, 22, 0.2); } -:global(html[data-mouse-active="true"]) .version-row.version-best:hover { +html.mouse-active .version-row.version-best:hover { background: rgba(10, 14, 22, 0.28); border-color: rgba(255, 255, 255, 0.2); } @@ -533,8 +533,8 @@ function handleActivate(event: MouseEvent | KeyboardEvent) { cursor: pointer; } -:global(html[data-mouse-active="true"]) .ctx-btn:hover:not(:disabled), -:global(html[data-mouse-active="false"]) .ctx-btn.nav-focused:not(:disabled), +html.mouse-active .ctx-btn:hover:not(:disabled), +html:not(.mouse-active) .ctx-btn.nav-focused:not(:disabled), .ctx-btn:focus-visible:not(:disabled) { background: rgba(255, 255, 255, 0.16); border-color: rgba(255, 255, 255, 0.35); diff --git a/frontend/src/components/SeriesFullView.vue b/frontend/src/components/SeriesFullView.vue index 332589c..6388891 100644 --- a/frontend/src/components/SeriesFullView.vue +++ b/frontend/src/components/SeriesFullView.vue @@ -806,8 +806,8 @@ onUnmounted(() => { outline: none; } -:global(html[data-mouse-active="true"]) .episode-tile:hover, -:global(html[data-mouse-active="false"]) .episode-tile.nav-focused { +html.mouse-active .episode-tile:hover, +html:not(.mouse-active) .episode-tile.nav-focused { z-index: 20; transition: z-index 0s; } @@ -850,14 +850,14 @@ onUnmounted(() => { } /* Show outline on hover and focus */ -:global(html[data-mouse-active="true"]) .episode-tile:hover .tile-focus-outline, -:global(html[data-mouse-active="false"]) .episode-tile.nav-focused .tile-focus-outline { +html.mouse-active .episode-tile:hover .tile-focus-outline, +html:not(.mouse-active) .episode-tile.nav-focused .tile-focus-outline { opacity: 1; animation: tile-outline-blink 1s ease-in-out infinite; } /* Brighter outline for keyboard focus */ -:global(html[data-mouse-active="false"]) .episode-tile.nav-focused .tile-focus-outline rect { +html:not(.mouse-active) .episode-tile.nav-focused .tile-focus-outline rect { stroke: #ffffff; stroke-width: 5; filter: drop-shadow(0 0 6px rgba(255, 255, 255, 0.8)); @@ -884,7 +884,7 @@ onUnmounted(() => { display: none; } -:global(html[data-mouse-active="true"]) .episode-tile:hover .tile-overlay { +html.mouse-active .episode-tile:hover .tile-overlay { opacity: 0.4; } @@ -945,7 +945,7 @@ onUnmounted(() => { text-shadow: 0 4px 20px rgba(0, 0, 0, 0.8); } -:global(html[data-mouse-active="true"]) .episode-tile:hover .tile-play { +html.mouse-active .episode-tile:hover .tile-play { opacity: 1; transform: translate(-50%, -50%) scale(1); } @@ -1081,7 +1081,7 @@ onUnmounted(() => { cursor: pointer; } -:global(html[data-mouse-active="true"]) .version-action-item:hover:not(:disabled), +html.mouse-active .version-action-item:hover:not(:disabled), .version-action-item:focus-visible:not(:disabled) { background: rgba(255, 255, 255, 0.12); outline: none; diff --git a/frontend/src/composables/useInputModality.ts b/frontend/src/composables/useInputModality.ts index 479cb83..d7d5774 100644 --- a/frontend/src/composables/useInputModality.ts +++ b/frontend/src/composables/useInputModality.ts @@ -24,9 +24,8 @@ function clearMouseIdleTimer() { function applyInputState(mouseActive: boolean) { const root = document.documentElement; - root.dataset.inputModality = modality; - root.dataset.mouseActive = mouseActive ? 'true' : 'false'; - root.dataset.pointerVisible = pointerVisible ? 'true' : 'false'; + root.classList.toggle('mouse-active', mouseActive); + root.classList.toggle('pointer-visible', pointerVisible); } function scheduleMouseIdle() { diff --git a/frontend/src/styles/main.css b/frontend/src/styles/main.css index 67289dc..cdb3600 100644 --- a/frontend/src/styles/main.css +++ b/frontend/src/styles/main.css @@ -40,8 +40,8 @@ html, body { -ms-hyphens: auto; } -html[data-pointer-visible="false"], -html[data-pointer-visible="false"] * { +html:not(.pointer-visible), +html:not(.pointer-visible) * { cursor: none !important; } @@ -65,7 +65,7 @@ html[data-pointer-visible="false"] * { border-radius: 4px; } -html[data-mouse-active="true"] ::-webkit-scrollbar-thumb:hover { +html.mouse-active ::-webkit-scrollbar-thumb:hover { background: var(--text-secondary); } @@ -175,13 +175,13 @@ html[data-mouse-active="true"] ::-webkit-scrollbar-thumb:hover { color: rgba(255, 255, 255, 0.78); } -html[data-mouse-active="true"] .header-nav-item:hover, +html.mouse-active .header-nav-item:hover, .header-nav-item.active { color: var(--text-primary); } .header-nav-item:focus, -html[data-mouse-active="false"] .header-nav-item.nav-focused { +html:not(.mouse-active) .header-nav-item.nav-focused { color: var(--text-primary); outline: none; text-decoration: underline; @@ -212,7 +212,7 @@ html[data-mouse-active="false"] .header-nav-item.nav-focused { transition: color var(--transition-fast); } -html[data-mouse-active="true"] .header-settings-btn:hover { +html.mouse-active .header-settings-btn:hover { color: var(--text-primary); } @@ -360,8 +360,8 @@ html[data-mouse-active="true"] .header-settings-btn:hover { color: var(--bg-primary); } -html[data-mouse-active="true"] .btn-primary:hover, -html[data-mouse-active="false"] .btn-primary.nav-focused { +html.mouse-active .btn-primary:hover, +html:not(.mouse-active) .btn-primary.nav-focused { background: rgba(255, 255, 255, 0.85); animation: btn-outline-blink 1s ease-in-out infinite; } @@ -371,8 +371,8 @@ html[data-mouse-active="false"] .btn-primary.nav-focused { color: var(--text-primary); } -html[data-mouse-active="true"] .btn-secondary:hover, -html[data-mouse-active="false"] .btn-secondary.nav-focused { +html.mouse-active .btn-secondary:hover, +html:not(.mouse-active) .btn-secondary.nav-focused { background: rgba(109, 109, 110, 0.5); animation: btn-outline-blink 1s ease-in-out infinite; } @@ -454,8 +454,8 @@ html[data-mouse-active="false"] .btn-secondary.nav-focused { outline: none; } -html[data-mouse-active="true"] .media-card:hover, -html[data-mouse-active="false"] .media-card.nav-focused { +html.mouse-active .media-card:hover, +html:not(.mouse-active) .media-card.nav-focused { z-index: 10; } @@ -477,7 +477,7 @@ html[data-mouse-active="false"] .media-card.nav-focused { box-shadow: 0 2px 8px rgba(0, 0, 0, 0.4); } -html[data-mouse-active="true"] .media-card:hover .media-card-poster { +html.mouse-active .media-card:hover .media-card-poster { box-shadow: 0 8px 24px rgba(0, 0, 0, 0.6); } @@ -523,7 +523,7 @@ html[data-mouse-active="true"] .media-card:hover .media-card-poster { transition: opacity var(--transition-fast); } -html[data-mouse-active="true"] .media-card:hover .media-card-info { +html.mouse-active .media-card:hover .media-card-info { opacity: 1; } @@ -627,7 +627,7 @@ html[data-mouse-active="true"] .media-card:hover .media-card-info { transition: background var(--transition-fast); } -html[data-mouse-active="true"] .modal-close:hover { +html.mouse-active .modal-close:hover { background: var(--bg-card); } @@ -723,7 +723,7 @@ html[data-mouse-active="true"] .modal-close:hover { transition: background var(--transition-fast); } -html[data-mouse-active="true"] .release-item:hover { +html.mouse-active .release-item:hover { background: var(--bg-card-hover); }