Consistency fixes:
- Extract getThisWeekRange/getThisMonthRange to shared lib/utils/dateRanges.ts
(removed 4 identical copy-pasted definitions)
- Add error boundaries for behavior, cdn, search, pagespeed pages
(4 new error.tsx files — previously fell through to generic parent error)
- Add "View setup guide" CTA to empty states on journeys and behavior pages
(previously showed text with no actionable button)
- Fix non-lazy useState initializer in funnel detail page
- Fix Bot & Spam settings header from text-xl to text-2xl (matches all other sections)
- Add useMinimumLoading to PageSpeed skeleton (consistent with all other pages)
Cleanup:
- Remove 438 redundant dark: class prefixes (app is dark-mode only)
text-neutral-500 dark:text-neutral-400 → text-neutral-400 (206 occurrences)
text-neutral-900 dark:text-white → text-white (232 occurrences)
- Remove dead @stripe/react-stripe-js and @stripe/stripe-js packages
(billing migrated to Polar, no code imports Stripe)
- Remove duplicate motion package (framer-motion is the one actually used)
- Add column headers to rage/dead click tables
- Rich empty states with icons matching dashboard pattern
- Add frustration trend comparison chart (current vs previous period)
- Show "New" badge instead of misleading "+100%" when previous period is 0
- Click-to-copy on CSS selectors with toast feedback
- Normalize min-height to 270px for consistent card sizing
- Fix page title to include site domain (Behavior · domain | Pulse)
- Add "last seen" column with relative timestamps