web: make the board usable on a phone, not just reachable
CI & Build / Build now, or wait for Android? (push) Successful in 3s
CI & Build / Python lint (push) Successful in 3s
CI & Build / TypeScript typecheck (push) Successful in 8s
CI & Build / Python tests (push) Successful in 34s
CI & Build / Build & push image (push) Successful in 50s
Desktop (Tauri) / Windows installer (cross-compiled) (push) Successful in 3m13s
Desktop (Tauri) / Tauri desktop (Linux) (push) Successful in 5m6s
Desktop (Tauri) / Update manifest (push) Successful in 6s

The controls a card carries were always-visible overlays on a touch device —
correct as far as it went (task 2697: a finger cannot hover, and the pill is
the only way to pin or archive), but they were still absolutely positioned, so
they sat ON the note's own title. A card reading "thought sync tauri app"
rendered as "ught sync tauri app" with the grip parked over the first three
characters, and the four-icon pill covering the right half of the first line.

Placement is now CSS's decision. One element each, two placements: where a
pointer can hover they lift out of flow into the floating top-corner pills they
have always been; where nothing can hover they stay in flow as a footer row,
which cannot overlap anything by construction. Keyed on hover rather than
width, for the same reason `.hover-reveal` already is — a narrow window on a
laptop still hovers, a wide tablet still doesn't. The colour popover moved
inside the action set so it follows it, and opens into the card from either
end.

The header was sharing one phone-width row between a menu button, the logo, the
lens name, a search field and four icons; everything in it was truncated, the
lens down to "N…" and the search box to an empty pill. It wraps now, so search
takes its own line below sm, and account / settings / sign-out move into the
drawer where there is room to name them rather than guess at a glyph. One input,
moved by CSS — duplicating it would have meant two `searchInput` refs and a `/`
shortcut that focuses the wrong one.

Also closes the other half of task 2706, which was waiting on a device to look
at: `viewport-fit=cover` together with the `env(safe-area-inset-*)` padding
that makes it safe (sides on body, top on the sticky header, bottom on the
board and the drawer), and `100dvh` behind an @supports so the app box follows
the visual viewport when the keyboard opens instead of the layout viewport.
Both halves in one change, as that task insisted.

And the composer no longer tells a phone to "Press Enter".
This commit is contained in:
2026-08-21 21:55:46 -04:00
parent 81695fa0c8
commit 16f86bef93
5 changed files with 279 additions and 115 deletions
+15 -4
View File
@@ -258,16 +258,27 @@ async function onDrop(targetId: string) {
</script>
<template>
<div class="mx-auto w-full max-w-6xl px-4 py-6">
<!-- `pb-[…safe-area-inset-bottom]`: the board is the last thing on the page, so
it is what ends up underneath the gesture bar once `viewport-fit=cover` lets
the page draw there. Added to the existing py-6 rather than replacing it. -->
<div class="mx-auto w-full max-w-6xl px-4 pb-[calc(1.5rem+env(safe-area-inset-bottom,0px))] pt-6">
<button
v-if="isMainBoard"
type="button"
class="mx-auto mb-4 block w-full max-w-xl rounded-xl border border-dashed border-neutral-300 px-4 py-2.5 text-center text-sm text-neutral-400 transition hover:border-neutral-400 hover:text-neutral-600 focus:outline-none focus-visible:ring-2 focus-visible:ring-brand dark:border-neutral-700 dark:hover:border-neutral-500"
@click="ui.requestCompose()"
>
Press
<kbd class="mx-0.5 rounded border border-neutral-300 px-1 text-xs dark:border-neutral-600">Enter</kbd>
or start typing to add a note
<!-- Two ways of saying the same thing, because the keyboard half is a lie on a
phone: there is no Enter key until something is already focused, and the
box has always been tappable. `hidden sm:inline` / `sm:hidden` rather than
a JS pointer check — this is presentation, and it should be right in the
first paint rather than after one. -->
<span class="hidden sm:inline">
Press
<kbd class="mx-0.5 rounded border border-neutral-300 px-1 text-xs dark:border-neutral-600">Enter</kbd>
or start typing to add a note
</span>
<span class="sm:hidden">Tap to add a note</span>
</button>
<FilterBar v-if="isMainBoard" />