fix(reader): mobile touch reading overhaul

- tap zones: map in-iframe taps into the visible page slice (the
  iframe is laid out at full section width; every tap previously
  computed as the left margin) and shrink the default zone size to 12%
- hyphens: manual on coarse pointers: Chrome's touch word-selection
  walks hyphen fragments, re-anchoring line-start drags and
  overshooting line ends into the next column
- selection popover: opens for settled touch selections (the gesture
  takeover swallows pointerup), positioned below the selection with
  on-screen clamping; creating a highlight clears the selection so
  the browser's own menu follows
- settle-time recovery: return the view to the selection's anchor
  page and clamp the selection to the visible page after the
  browser's selection auto-scroll wanders off the page grid
- overscroll-behavior: none on the reader page (pull-to-refresh
  during downward drags)
This commit is contained in:
John O'Keefe
2026-09-15 08:50:17 -04:00
parent cc8084a713
commit 0e55dafb1e
2 changed files with 271 additions and 46 deletions
+2 -2
View File
@@ -23,7 +23,7 @@ func readerInitExpr(metadata ReaderMetadata) string {
templ Reader(user User, metadata ReaderMetadata) {
<!DOCTYPE html>
<html lang="en">
<html lang="en" class="overscroll-none">
<head>
<meta charset="UTF-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover"/>
@@ -38,7 +38,7 @@ templ Reader(user User, metadata ReaderMetadata) {
<body
x-data="readerShell"
x-init={ readerInitExpr(metadata) }
class={ "theme-" + user.Theme + " h-screen overflow-hidden" }
class={ "theme-" + user.Theme + " h-screen overflow-hidden overscroll-none" }
>
<!-- Reading surface: edge-to-edge. Chrome overlays translucently;
drawers and scrim float above everything. -->