Derives the whole body switch from one bound state. No second state
machine, no boolean fallback inputs - every branch is a computed() over
resolveAsyncView, the same lookup table the rest of cngx switches on.
Two cases the lookup table does not cover on its own:
No state bound. The timeline is then a plain list over [items],
but an empty one still has to reach the empty surface; otherwise
*cngxTimelineEmpty would be unreachable on the synchronous path.
The announcement. Only loading and refreshing have anything to
say, and the string is empty otherwise so the live region stays in the
DOM while staying silent.
Busy with an empty screen. The lookup table resolves a non-first-load
loading or pending to content; with no rows that renders nothing at
all, so it is treated as a load instead. refreshing keeps its tail.
First-load busy over seed rows. The lookup table resolves a first
load to skeleton unconditionally, but [items] documents seed rows as
a legitimate companion to a bound state - rows that exist are painted,
never hidden behind placeholders. aria-busy still marks the list.
Swap the whole mapping through CNGX_TIMELINE_VIEW_FACTORY rather
than forking the organism - treating pending as content, or holding the
skeleton through a refresh, is a per-app decision.