d961a89bf80447839429bcbdb6e5628c2354cde6
2
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
6026d98598 |
Half the editor was on the phone and none of it could be touched
Reported as "quite a few options don't function on mobile", and measured in a real touch emulation rather than a narrow window — the distinction matters, because two of the three causes need `pointer: coarse` to appear at all. Three causes, one theme: the chrome was built for a pointer that hovers. The toolbar reveals itself on :hover — flex-wrap: wrap, overflow: visible. A touchscreen never hovers, so that rule never fired and the row stayed clipped at overflow: hidden permanently. Fourteen of its twenty-three controls could not be reached by any gesture: every heading, both lists, all three alignments, link, image, table, outline, and both AI passes. The faded right edge promised there was more that way, and there was no way. It now scrolls sideways on a coarse pointer, keeping every control, exactly as .petal-chrome-strip does one line above it — the same trade that comment already argued for, applied to the row it was comparing itself to. That move was only safe once the panels could get out. Every dropdown in the editor chrome — tone, export, colour, highlight, size — was already broken on a phone for a subtler reason: `position: fixed` is relative to the viewport only while no ancestor establishes a containing block, and mask-image does, exactly like transform. Both scrollers fade their edges with a mask. So on any screen narrow enough for the fade to appear, the menu was pulled back inside the very box it was escaping, painted under the toolbar and untappable. The comment in anchoredMenu.ts said "nothing clips a fixed box unless an ancestor has a transform, and none of the editor's chrome does"; it was true when it was written and had quietly stopped being true. The panels now portal to <body>, where nothing above them can clip, stack over or contain them whatever the chrome does with masks later, and the outside-tap tests ask about both halves. The kitten took the last two. She covered "Español" and "I am learning Português" in the drawer, and "Hide falling petals" in the status bar outright — three sample points across it, all three landing on the cat. She already knows how to yield: useCardOverlap fades her for cards and for anything with the modal role, and the drawer is the one overlay that has neither, being navigation rather than something opened on purpose. It is named there now. The status bar is a different problem — it is always present, so yielding to it would mean fading forever — and the honest fix is to sit above it on a narrow screen instead of negotiating with it every frame. Measuring, not eyeballing: a sweep of every visible, enabled control reports zero off-screen and zero blocked, against fourteen and three before. Desktop is deliberately untouched — at rest the slim clipped line with its mask, on hover the wrapped row with all twenty-three buttons on screen — and the edge measurement ChromeStrip already did is now shared with the toolbar rather than written twice. Claude-Session: https://claude.ai/code/session_01GJHNvirh7Hzhc9RL3HAvz7 |
||
|
|
ac1c6cddb0 |
French dragged her whole page sideways
The bug reads as a language-picker bug — switch off Mandarin on a phone and
the writing starts scrolling left and right — but the picker only changes
how wide Petal's own chrome wants to be. Every pill says its thing twice,
历史 · History against Historique · History, and every pill is nowrap and
shrink-0. So the title row's width is a property of the langpack: 459px in
Chinese, 551px in French, 506px in Portuguese, against the 338px column a
390px phone gives it. That row lives in the editor pane, and a pane that is
overflow-y: auto has an overflow-x of auto too, whatever the stylesheet
says. The overflow had nowhere to go but the page of writing.
Chinese was already 120px over. French is simply where it stopped being
possible to ignore.
The pills now live in a strip that scrolls itself, with overscroll-behavior
so a swipe off the end doesn't turn into a page gesture. What that buys is
the thing worth keeping: every label stays bilingual at every width. The
first version of this fix dropped the English half on phones, which fixed
the geometry by taking away the half she is learning from — on the device
she writes on most.
A scrolled pill that has left the screen is indistinguishable from a pill
that isn't there, so each edge with more behind it fades, the same hint
.petal-toolbar gives with its clipped right edge, except this row can be
scrolled from either end and has to point the right way. ChromeStrip sets
data-edge from the scroll position and re-measures when the pills resize —
which is also what catches every label changing width at once when she
switches her pair.
The tone and export menus had to leave with them. A scroll container clips
its absolutely-positioned children, so both menus would have been trapped in
a 36px-tall box; they anchor against the viewport now.
Two smaller ones the same measurement turned up:
- The header overflowed the viewport itself below 360px — a real
page-level scroll, 40px of it at 320px, off 🌷 Jardim de palavras ·
Garden. Narrower padding on phones, and under 360px the wordmark
yields. Of everything in that row it is the one thing that can go: she
is already inside the app, and the blossom stays.
- The language picker wanted 307px inside a 280px drawer and spilled out
of it. It wraps now. That one was broken in Chinese too, at 291px.
Verified in a real browser rather than by arithmetic: 310px to 780px in 10px
steps, in all three packs, no page overflow and no editor-pane overflow at
any width. Edge fades flip correctly, the export menu opens unclipped with
the strip scrolled to its end, tsc clean, 195 frontend tests pass. Desktop
is untouched — one 40px header row, as before.
Claude-Session: https://claude.ai/code/session_016y6gyuHkQXPiEuW8RGQyua
|