The Share button on /mirror is unclickable below ~700px and below the
fold in short windows. Measured with elementFromPoint on Chromium:
320x568 stage 288x180 button 187px past the stage bottom hit=H2
390x844 stage 358x224 button 113px past hit=LABEL
480x800 stage 448x280 button 36px past hit=#share-link
900x480 stage 868x543 inside the stage, below the viewport hit=null
Root cause: .stage is display:grid with place-items:center, so <video>,
.placeholder and .livetag occupy three stacked rows rather than one
overlay cell. An idle <video> is intrinsically 300x150, so the
placeholder always starts at stage.top + 151 and runs out of the
overflow:hidden box; aspect-ratio 16/10 with no min/max height then
clips it when narrow and overshoots the viewport when short.
#stop measures clickable everywhere (the placeholder is hidden when
live), so the fix is scoped to the idle stage.
Phase: one-cell stage, floor + ceiling + scroll escape, a 12-viewport
clickability sweep (idle and live), and stylesheet guards.
LLM-Generated: true
Convert the three open TODO items into .agents/phases/todo/ directories
(Protocol B append — PLAN.md, AGENTS.md and existing phases untouched, so
PLAN.md's roadmap table does not list these phases):
- 01_keyboard_kiosk_control (TODO.md:3) — mouse-free /watch and /mirror:
key router, j/k/Enter/f/g/n/p/1-9/m/?, focus-visible controls, help overlay.
- 02_sharp_capture (TODO.md:4) — capture screen pixels instead of window
pixels, maintain-resolution per leg, 12 -> 25 Mbit/s default cap,
real-desktop size assertion on the viewer.
- 03_audio_share (TODO.md:5) — one accumulating MediaStream per tile (the
ontrack overwrite dropped the first track), staged-only unmute policy,
honest audio states on /mirror, viewer-side inbound-audio assertion.
Every task cites its TODO source line. Locked with the user: 25 Mbit/s
default, only the staged mirror can be audible, full key map.
Note for the user: PLAN.md section 6 still says the per-leg cap defaults to
12 Mbit/s; phase 02 task 03 changes that and this commit does not edit PLAN.md.
LLM-Generated: true
PLAN.md locks the architectural decisions (WebRTC mesh with the sharer as
sole offerer, JSON-only signaling, in-memory roster with no database, no
auth, no CDN, Linux as the reference platform) and records the roster rules,
the verification ladder, and the constraints that are accepted rather than
hidden: the secure-context requirement, mesh upload scaling with watcher
count, and the Wayland portal's per-share prompt.
Phases are deliberately not written yet -- the prototype and its tests came
first, so .agents/phases/todo/ holds only a README pointing at the candidate
phase list in PLAN.md section 7.
SECURITY.md answers the question a no-auth tool has to answer: not "who is
allowed in" but "where is this allowed to run". It separates what an
unauthenticated LAN visitor can do from the guarantees that are enforced and
named to a test, and tells users the two things they will actually hit --
that http://<lan-ip> hides getDisplayMedia, and that on Wayland the
compositor asks every time and mirror must not work around it.
LLM-Generated: true