Replace ~48 magic z-index values (z-10..z-[9999] + 2 inline zIndex) with named
tailwind zIndex tokens (base/menu/chrome/paneltab/panel/rail/overlay/popover/
tooltip/tuner). Values are UNCHANGED — a rename, not a renumber — so layering is
identical; the names give one source of truth for the stack.
The xl breakpoint was a fact about the FEED's toolbar, hard-coded into
the switcher that E4's managers are meant to reuse — their rows are far
emptier and would have hidden the label for no reason. It's a prop now,
defaulting to icon-only.
The two views spans collapse into one builder, which also fixes a
regression I'd just added: splitting them put the exact-count tooltip on
the number alone, so hovering the word gave nothing.
Three from UAT: the row's cap goes 1280 -> 1472 (+15%), since with the
rail and filters hidden there was a lot of page left over and the fixed
columns mean the extra width can only go to the title; the views column
drops the word and keeps it in the tooltip (a table doesn't repeat its
unit every line), taking that column 144 -> 64; and the view switcher
names the current mode where the toolbar has room, falling back to the
icon alone below xl. Title: 431 -> 511 at 1440, 706 at 1900.
Seeding the roving index from an effect only scheduled the update, so the
focus effect still read the previous index and focused the wrong item for
one render — a screen reader announced both. Seed it where the menu opens
instead. The modes are one exclusive choice, so they also need a group to
scope their checked-ness to.
Arrows/Home/End move a roving focus and Escape hands focus back to the
trigger — the menu unmounts under the focused item, which stranded focus
on <body>. Outside-click deliberately does not refocus: that would steal
focus from whatever was just clicked.
The view mode moves out of Settings into a switcher next to sort, on the
feed and channel pages alike. It leaves the Settings prefs draft for its
own eager save: a toolbar click must not mark that page dirty and trip
its leave-page guard.
lib/feedView.ts owns the vocabulary and maps the old grid/list prefs
forward on read, so nobody's saved choice is lost.