UI: drop tab-bar tap highlight; don't slide the first screen on launch #45

Merged
developer merged 3 commits from feature/ui-tap-startup-polish into development 2026-06-11 21:55:21 +00:00
2 changed files with 17 additions and 10 deletions
Showing only changes of commit 9277a70565 - Show all commits
+12 -3
View File
@@ -32,8 +32,9 @@
// Screen transitions: the lobby is the navigation root. Entering a screen from the
// lobby slides it in from the right (forward); returning to the lobby slides the
// screen out to the right and reveals the lobby (back). Transitions are local, so
// they do not play on the initial mount, and collapse to nothing under reduce-motion.
// screen out to the right and reveals the lobby (back). The first pane shown after boot
// does not slide (the `started` gate below), and transitions collapse to nothing under
// reduce-motion.
// Slide direction by route depth: going deeper (lobby → game → chat/check) slides forward,
// returning to a shallower screen slides back. A plain "lobby is back" rule slid the chat/check
// back-to-the-game the wrong way. dir is read with the previous depth (the effect updates it
@@ -52,7 +53,15 @@
const enterSign = $derived(dir === 'forward' ? 1 : -1);
const leaveSign = $derived(dir === 'forward' ? -1 : 1);
const routeKey = $derived(router.route.name + (router.route.params.id ?? ''));
const animMs = $derived(app.reduceMotion ? 0 : 260);
// The first pane shown once the app is ready must not slide: it would look like the app
// was navigated into rather than launched. The pane is a local transition inside a {#key}
// block, so it plays on that block's own first mount anyway — hold the duration at 0 until
// just after that mount (the effect runs post-render), then animate every later change.
let started = $state(false);
$effect(() => {
if (app.ready) started = true;
});
const animMs = $derived(!started || app.reduceMotion ? 0 : 260);
// slideX slides a pane horizontally by a full width. sign>0 enters from / exits to
// the right; sign<0 the left. Percentage keeps it viewport-relative without reading
+5 -7
View File
@@ -34,12 +34,13 @@
width: 100%;
user-select: none;
-webkit-user-select: none;
-webkit-tap-highlight-color: transparent; /* no WebKit flash on tap */
}
:global(.tab:disabled) {
opacity: 0.4;
}
/* The icon square hugs the emoji (just a little padding) so it is the press-highlight
target and the badge can sit on its corner. */
/* The icon square hugs the emoji (just a little padding) so the badge can sit on its
corner. */
:global(.tab .sq) {
position: relative;
display: inline-grid;
@@ -50,12 +51,9 @@
line-height: 1;
transition: background-color 0.12s;
}
:global(.tab:active:not(:disabled) .sq) {
background: var(--surface-2);
}
/* A tab that navigates between peer views (Settings / Comms hubs) stays highlighted
while selected: a filled square with an accent underline, distinct from the
momentary press tint above. */
while selected: a filled square with an accent underline. A tap itself leaves no
highlight — there is no press tint, and the WebKit tap flash is disabled on .tab. */
:global(.tab.active .sq) {
background: var(--surface-2);
box-shadow: inset 0 -2px 0 var(--accent);