Four UI changes landing together since they all polish Section ① and
Section ② of the public demo:
1. Section ① (Live Market — Chicago) explainer rewritten data-source-
first ("Live from City of Chicago Open Data...") with bolded dial
names so a skimmer can map the visual to the prose. Drops the
"internal calendar" jargon and the slightly-overclaiming "rest of
the page is reacting" framing — downstream sections read the same
feed but don't react to the per-shift filter, so the new copy says
"this row is its heartbeat" instead.
2. Fill-probability bar gets a left-to-right paint reveal (clip-path
inset animation) so the green→gold→orange→red gradient reads as a
*timeline growing* instead of a static heatmap with a "danger zone"
at the right. Followed by a 30%-wide shimmer sweep on a 3.4s loop
for live-signal feel.
3. Paint trigger moved from on-render to IntersectionObserver — by
the time the user scrolls to Section ② the on-render animation had
already finished. Now each bar paints in over 2.8s when it enters
viewport (threshold 0.2, 350ms entry delay). Single shared observer,
unobserve()s after firing so the watch list trends to zero.
4. Contract cards now compact-by-default with click-to-expand. New
summary strip shows revenue / margin / fill-by-1wk / top candidate
so scanners get the punchline without expanding. Click anywhere on
the card surface (excluding inner content) to expand the full FP
curve, economics grid, candidates list, and Project Index. Project
Index auto-opens with the parent card so users actually find the
build signals — but only on user-driven expand (avoiding 20× OSHA
scrapes on page load). grid-template-rows: 0fr → 1fr animation
handles the smooth height transition.
All four animations honor prefers-reduced-motion.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>