diff --git a/docs/superpowers/specs/2026-06-19-cyclone-production-readiness-design.md b/docs/superpowers/specs/2026-06-19-cyclone-production-readiness-design.md
index 97146de..f57370c 100644
--- a/docs/superpowers/specs/2026-06-19-cyclone-production-readiness-design.md
+++ b/docs/superpowers/specs/2026-06-19-cyclone-production-readiness-design.md
@@ -248,7 +248,194 @@ Each page gains: `` rows during `isLoading`, an error block with "Re
### 7.6 UI primitive: `src/components/ui/skeleton.tsx`
-~10 lines, shadcn-style: `
`. No new dep.
+A reusable row-shaped skeleton block. Voice: hairline + a slow horizontal scanline gradient (not the generic "pulse the whole block gray" pattern). Renders three bars (id / name / amount) sized to match the typography of the row it stands in for. ~25 lines, no new dep.
+
+```tsx
+// Sketch — not the final implementation
+export function Skeleton({ className, variant = "row" }: Props) {
+ return (
+
+
+ {variant === "row" ? (
+
+
+
+
+
+
+
+
+ ) : null}
+
+ );
+}
+```
+
+The `shimmer` keyframe is added to `tailwind.config.js` next to the existing `fade-in` keyframes. No external library.
+
+### 7.7 Live-data UX patterns
+
+The aesthetic is already committed (Cabinet Grotesk + Geist Mono, true-black ground, electric-blue accent, hairline chrome, radial top-right light, fine grain). This sub-project does not introduce a new accent color, a new typeface, a light theme, or a new layout primitive. The additions below are *only* the live-data UX patterns needed to make the page refactors feel as precise as the data they carry.
+
+#### 7.7.1 Loading — three skeleton variants
+
+Pages render 3–5 `Skeleton` rows (or cards, or KPI tiles) on `isLoading` so the page doesn't pop. Skeleton uses the row-shaped variant (above) inside table surfaces, the `card` variant inside the Provider grid, and the existing `.surface` + `display` text treatment for the page header (which renders immediately, not behind a skeleton).
+
+#### 7.7.2 Empty state
+
+Replace the existing generic "No claims yet." text with a consistent empty state primitive: a hairline-circle icon (1.5px stroke), an all-caps eyebrow (`text-[10.5px] font-semibold uppercase tracking-[0.18em] text-muted-foreground`), and a one-line message. The eyebrow uses the *page subject* so it reads as an instrument label: e.g., "Claims · inbox idle" / "Remittances · awaiting first 835" / "Activity · log idle" / "Providers · directory empty". No apologetic language, no illustrations.
+
+```tsx
+function EmptyState({ eyebrow, message }: { eyebrow: string; message: string }) {
+ return (
+
+
+
+
+
+ {eyebrow}
+
+
{message}
+
+ );
+}
+```
+
+`CircleDashed` from `lucide-react`.
+
+#### 7.7.3 Error state
+
+A bordered block at the top of the page content (not a full-page takeover — the user should still be able to navigate away). `border-destructive/30` on a `.surface` background; a destructive-tinted `AlertCircle` icon, the error message in `text-sm`, and a `Retry` button on the right. A sonner toast surfaces the same error at the bottom-right (existing Toaster config keeps this). Network errors get a more verbose message ("Can't reach the backend at `http://127.0.0.1:8000`. Is the FastAPI server running?").
+
+```tsx
+function ErrorState({ error, onRetry }: { error: Error; onRetry: () => void }) {
+ return (
+
+
+
+
+ Fetch failed
+
+
{error.message}
+
+
+
+ );
+}
+```
+
+#### 7.7.4 Refetch indicator (Layout-level)
+
+A 1px hairline at the very top of `` that animates in (left → right, accent color, 400ms) whenever *any* query is fetching in the background (e.g., after `invalidateQueries` post-parse). Uses `useIsFetching()` from `@tanstack/react-query`. Implemented as a fixed-position element inside `Layout.tsx`, not page-level — so every page benefits without per-page plumbing.
+
+```tsx
+// In Layout.tsx
+const isFetching = useIsFetching();
+return (
+
+ {isFetching > 0 ? (
+
+
+
+ ) : null}
+
+ …
+
+);
+```
+
+The `scan` keyframe is added to `tailwind.config.js`. The element is hairline-thin so it never competes with the content; the only motion on the page during a background refetch is this 1px sliver.
+
+#### 7.7.5 Active filter chips (Claims page)
+
+The existing `