feat: frontend remote relay, kiosk hardening, CSS compositor fix

Frontend:
- Add remote-relay.ts: receives companion input via /ws/remote-relay,
  dispatches keyboard/mouse/scroll events into browser DOM
- Add CompanionIndicator.vue: NES gamepad icon when companion connected
- Wire relay start/stop to auth state in App.vue

Kiosk:
- Move Chromium data dir to /var/lib/archipelago/chromium-kiosk (encrypted)
- Disable MetricsReporting, AutofillServerCommunication, PasswordManager
- Remove --metrics-recording-only (contradicts disable-metrics)

CSS:
- Fix Chromium ghost rectangles: only apply preserve-3d + backface-visibility
  during transitions, not always-on (causes Chromium to skip painting
  off-viewport cards)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Dorian
2026-04-02 11:10:08 +01:00
parent 34a37191dd
commit 94524e150a
6 changed files with 303 additions and 7 deletions

View File

@@ -394,8 +394,10 @@ aside:not(.sidebar-animate) .sidebar-logout-btn {
.view-wrapper {
position: absolute;
inset: 0;
transform-style: preserve-3d;
backface-visibility: hidden;
/* preserve-3d + backface-visibility only during transitions (applied by
transition classes below). Keeping them always-on causes Chromium to skip
painting cards that start below the viewport — they appear as transparent
ghost rectangles when scrolled into view. */
will-change: transform, opacity;
opacity: 1;
}
@@ -408,6 +410,8 @@ aside:not(.sidebar-animate) .sidebar-logout-btn {
.depth-forward-enter-active.view-wrapper,
.depth-forward-leave-active.view-wrapper {
transition: all 0.8s cubic-bezier(0.25, 0.46, 0.45, 0.94);
transform-style: preserve-3d;
backface-visibility: hidden;
}
.depth-forward-enter-from.view-wrapper {
@@ -438,6 +442,8 @@ aside:not(.sidebar-animate) .sidebar-logout-btn {
.depth-back-enter-active.view-wrapper,
.depth-back-leave-active.view-wrapper {
transition: all 0.8s cubic-bezier(0.25, 0.46, 0.45, 0.94);
transform-style: preserve-3d;
backface-visibility: hidden;
}
.depth-back-enter-from.view-wrapper {
@@ -487,6 +493,8 @@ aside:not(.sidebar-animate) .sidebar-logout-btn {
.chat-open-enter-active.view-wrapper,
.chat-open-leave-active.view-wrapper {
transition: opacity 0.5s cubic-bezier(0.22, 1, 0.36, 1), transform 0.5s cubic-bezier(0.22, 1, 0.36, 1);
transform-style: preserve-3d;
backface-visibility: hidden;
}
.chat-open-enter-from.view-wrapper {
@@ -513,6 +521,8 @@ aside:not(.sidebar-animate) .sidebar-logout-btn {
.chat-close-enter-active.view-wrapper,
.chat-close-leave-active.view-wrapper {
transition: opacity 0.5s cubic-bezier(0.22, 1, 0.36, 1), transform 0.5s cubic-bezier(0.22, 1, 0.36, 1);
transform-style: preserve-3d;
backface-visibility: hidden;
}
.chat-close-enter-from.view-wrapper {