Phase 5h slice 3 — splits the Tiles rollup into ProjectsCurrent (primary
grid) and ProjectsQuiet (collapsible fold) per m's §7 'pinned ∪
recently-active ∪ open-work' rule.
URL contract extended:
/dashboard — Tiles, scope=current (defaults elided)
/dashboard?scope=all — every active project in the grid
/dashboard?scope=current — same as default (chip allows explicit)
Scope chip lives next to the tab strip on Tiles only; Tasks + Events
tabs hide it (no scope concept there). Default chip label: '◇ current',
flips to '○ all' when scope=all. Chip href toggles to the alternate
state preserving filter + view.
Quiet fold:
- <details> element opened on click — projects with IsCurrent=false land
here, including all stale candidates.
- Fold summary: 'Quiet (N) — older than 14d · M stale' (M omitted when 0).
- Quiet tiles render with the same shape as primary tiles, slightly
faded; stale tiles also carry a 'tile-stale' class (dashed border) and
a 'stale' flag in the header.
Stale card on the Tasks tab retires entirely — m's pick. The
LastActivity stamp on each tile carries the staleness signal; the
'consider archiving?' nudge migrates to the Quiet fold framing. Stale
data still computes (collectStale runs in buildDashboard) because the
rollup needs the per-item stale flag and the repo-activity map for
LastActivity.
Cache key extends: (filter | view=X | scope=Y) so toggling scope from
the chip lands in a separate cache slot (no stale render).
Tests:
- TestDashboardStaleCardSurfacesDormantMaiProject retargeted at the new
Quiet fold + tile-stale class on Tiles.
- TestDashboardStaleCardSkipsRecentRepo asserts the inverse via class
inspection on the tile <article>.
- 4 new tests cover the scope chip: renders on Tiles only, label flips
on scope=all, scope=all hides the Quiet fold, chip URL flips correctly.
Empty state: scope=current with no current projects shows a
'Nothing current. Pin a project, or show all active.' note with a
direct link to scope=all.