6 dimmed by header lens · matching blocks stay put — nothing reflows under you
LifeLab · header lens
That meta line — [all] · [page] 2 · :project/lifelab: 4 — already had the parts: [all]/[page] is a source toggle, tag pills are facet chips with counts. Upgrade: clicking a pill activates it into a chip, / opens the same completion line as every picker and funnel, and the result filters everything the page shows — river, subpages, linked, transcluded regions. Stacking rule: intersection. Header state is view state — remembered per page, ephemeral until you pin or name it.
Passive counts are one click from being filters. Same {} grammar, same completion, zero new UI vocabulary.
Header lens ∧ region lens. Rows a region would show but the page lens hides render dimmed, struck — you can always tell which filter bit.
this visit (view state) → pinned to page (page property) → named (lens/…). Same ladder as buffers: ephemeral, resident, citizen.
Pinned header lens serializes as a page property — lens: todo when:-3w.. — grep-able, sync-safe, MCP-writable like everything else.
On the journal day page: :project/lifelab: pill clicked → chip with ×. / opened the completion line, todo half-typed. Non-matching river blocks dim in place (org-agenda honesty) — count line reads 3 of 9. The unsaved lens pill appears the moment the header diverges.
6 dimmed by header lens · matching blocks stay put — nothing reflows under you
Header lens {todo} stacked on a region with its own {when:-3w..}: the region row hidden by the page lens renders dimmed with the culprit named. Clicking the unsaved pill opens the ladder: this visit (default — view state, same place day/week/month already lives), pin to page (a property line on the page), name it (lens/).
The big-page face is three sections; the header lens bites all of them, each reporting shown of total. Subpages keep their identity — matches render under their subpage header, so structure survives filtering. [all] vs [page] stays the source toggle: [all] descends into subpages, [page] is direct blocks only.
Stacked = two windows: independent fold/close/lens, drag to reorder — but a shared filter is written twice and there's no cross-set sort. Union = one set: one lens, unified sort/group — write-home stays per sub-river. Comma is safe: slugified titles exclude , (like :), and picks store IDs anyway.
a · stacked — two windows
b · union — one set, one lens
Rule of thumb the UI teaches: reach for union exactly when you want one lens over both. The picker makes it cheap to choose either — ↵ then ![[ again for stacked, , for union — and converting later is a text edit.
Where the state lives: the header lens joins day/week/month in per-page view state (something already remembers those); pin promotes it to a page property (lens: todo when:-3w.. — one grep-able line); name promotes it to lens/…, summonable via ![[. Stacking is intersection, and every hidden row can say which lens hid it. Union sources compose with lenses (![[Projects, Reading]]{todo}); relational join stays in Lua on purpose.