Features
- register ps_nosub_1/2/3 tester cards
- route no-subscription nudge templates in sendTestWhatsApp
- include reEngagementLog and aggregate no-sub nudge stats
- reorder subscription after phone, show next nudge beat, adopt StatsCardsGrid
- show nudge stage pill per user and platform stats banner
- type reEngagementLog and noSubNudgeStats response fields
- add blog views endpoint querying PostHog via HogQL
- add useBlogViews hook for PostHog view counts
- add views column to admin blog table showing 30d and total counts
- add client-side blog list with search, category chips and featured post
- add processBlogContent util to inject heading ids and extract TOC
- add reading progress bar for post pages
- add social share buttons with copy-to-clipboard
- add sticky table of contents with scroll-spy highlighting
- capture blog_post_viewed PostHog event on post render
- expose updatedAt in BlogPost type for dateModified schema
- modernize list page hero, add stats strip and Blog schema with dateModified
- render OG image with cover as darkened background and title overlay
- upgrade post page with TOC, reading progress, share buttons, author card and richer schema
- add no-subscription 2/2/2 day nudge cadence with kill switch
- add LeadKpiCards widget for total, new, converted and conversion rate
- add LeadsByStage horizontal bar widget with click-through to filtered leads
- add LeadsTrendChart area chart for monthly created vs converted
- add tabbed StatsTabs switcher for proposals and leads KPIs with nuqs persistence
- mount Leads Overview section with KPI cards, trend chart and stage breakdown
- add avatar element and Contact/Business section labels in popup
- add contact fields to LeadPayload for person vs company split
- add contactPhotoUrl and businessLogoUrl to LeadPayload
- add FETCH_SERVICES handler to service worker for CORS-safe services fetch
- add Industry select and Services Interested multi-select to preview drawer with auto-inferred industry
- add loading screen markup to popup init flow
- add LOOKUP_LEAD_BY_PROFILE handler for existing-lead dedupe
- add serviceInterests to LeadPayload type
- add sourceActivity array to LeadPayload type
- crawl contact/about pages and log fetch status from background worker
- crawl contact/about pages in addition to homepage when scraping website for emails and phones
- detect session via cookie store so popup works without an open tab
- disable submit during enrichment and dedupe junk phones from discovered list
- implement LinkedIn lead enrichment with automated contact finding
- inject Add to Lead button on LinkedIn profile pages
- popup auto-opens in-page drawer on LinkedIn profiles when signed in
- preview drawer in content script with editable fields before lead creation
- redesign drawer with Details/Discovered/Activity tabs, confidence badge, split first/last name, LinkedIn URL field, verified-row Discovered list, styled services grid, slide animations, phone normalization and resync flow
- render injected Add to Lead button as full-width block row on mobile LinkedIn
- show preview modal with editable fields before submitting LinkedIn lead
- show session-check loading state with progress messages in popup
- split contact and business email/phone across tabs, restructure header, auto-detect industry, surface logo, handle personal profiles with no current employer
- split popup contact vs business sections and render avatar
- widen drawer to 640px with 2-col grid, leading icons, compact buttons and single view
- add WorkflowsGallerySection editorial masonry highlighting real firm day-to-day use of PracticeStacks
- mount WorkflowsGallerySection between Solutions and Stats on homepage
- implement automatic lead lookup and visual state update for existing LinkedIn profiles
- accept contact fields on PATCH and sync to primary Contact row
- accept sourceActivity array and persist enrichment history on lead create
- add Assignee filter dropdown in header with nuqs-persisted state
- add avatar and contact initial fallbacks on lead card
- add colored top borders, stage strip sub-nav, stage total footer and real pipeline value from service rates
- add GET by-profile lookup to dedupe against existing LinkedIn leads
- add Primary Contact sub-section to lead sheet with name/title/email/phone
- add stage strip pipeline overview above kanban board
- create primary Contact on prospect Business when lead includes contact info
- mirror LinkedIn contact/business images to S3 and include primary contact in GET response
- persist contact fields on Lead and save contact photo + business logo on create
- redesign Edit Opportunity sheet with sidebar nav, sectioned cards, completeness widget and scroll-clamped section nav
- redesign lead card with compact avatar, meta row, single service chip with overflow, always-rendered follow-up slot and emerald deal value pill
- redesign list view as stage-grouped custom table with collapsible headers, stage value and deal value column
- show business logo and primary contact photo in lead sheet header
- show business logo and primary contact photo on lead card
- add dashboardKeys.leadsOverview query-key factory
- add fetchLiveSubscriptionStatus helper for lightweight status+next-due fetch
- add leadsDashboard cache tag and wire into lead invalidations
- bust leadsOverview client cache on lead mutations
- add contactName/title/email/phone columns to Lead
- add photoUrl column to Contact
- add sourceActivity column to Lead for enrichment history
- add badge support and 'New' badge to changelog
- add real-workflow marketing webp assets for homepage editorial section
- redesign lead enrichment modal with tabbed interface and company logo support
- add contact fields to Lead and photoUrl to Contact
- add NOSUB_1/2/3 whatsapp template enum values
- add sourceActivity Json column to Lead
- add leads-overview API returning KPIs, stage breakdown and monthly trend
- add useLeadsOverview hook with nuqs-driven time range
- update features page hero section with SocialProofBadge and refined layout
- add global_public_stats cache tag for platform-wide statistics
- add usePublicStats hook for dynamic platform statistics fetching
- create dynamic SocialProofBadge with real user profiles and live firm counts
- define public-platform-stats query keys for TanStack Query
- implement public API endpoint for database-driven firm statistics
- add DELETE endpoint to clear all messages for a specific phone
- add DELETE endpoint to wipe all WhatsApp messages globally
- add sendNoSubscription1/2/3 helpers
- add useDeleteWhatsAppConversation and useDeleteAllWhatsApp mutation hooks
- fetch and store media URL from Meta Graph API on incoming image messages
- opt out of nudges on STOP keyword or STOP_NUDGES button
- register ps_nosub_1/2/3 templates and data interface
- render image preview in chat view, show unavailable placeholder for legacy messages
- replace window.confirm with shadcn AlertDialog for clear chat in chat view
- replace window.confirm with shadcn AlertDialog for global delete in conversation list
- wire delete mutations into page and pass clear/delete-all callbacks to child components
Bug Fixes
- inline about page JSON-LD
- color-code subscription badge by live Razorpay status and show next due date
- extend AdminUser.subscription type with live status, chargeAt, currentPeriodEnd
- fetch live Razorpay status per user so listing reflects real subscription state
- move Subscription column directly after User so status is visible without horizontal scroll
- inline announcement detail JSON-LD
- inline announcements list JSON-LD
- inline CollectionPage JSON-LD for blog index
- render JSON-LD as inline script so Google sees BlogPosting schema, closes #487
- inline changelog detail JSON-LD
- inline changelog list JSON-LD
- inline breadcrumb JSON-LD
- refine empty-state badge, remove glitchy check-draw animation and widen monitoring pill
- drop prod URL fallback and clear cross-env stored auth so dev build never writes to production
- drop storage-auth gate in content script and match Follow button style
- drop unused cookie args in verifySession and rely on credentials:include
- fall back to production URL when dev BASE_URL has no active session
- inline Add to Lead after Message on desktop and full-width row below action bar on narrow viewports
- reject decimals and unix timestamps in isRealPhone to cut junk from website scrape
- rely on credentials:include for session cookie instead of manual Cookie header
- use build-time BASE_URL in content script instead of stored auth baseUrl to prevent cross-env posts
- inline features breadcrumb JSON-LD
- inline firm page JSON-LD
- inline industry landing page JSON-LD, closes #488
- inline homepage JSON-LD schema
- accept and sync website and industry to linked business on PATCH
- drop unused Briefcase import
- force active-query refetch after delete so kanban refreshes without hard reload
- include contact fields in optimistic tempLead to satisfy Lead type
- include sourceActivity null default in optimistic tempLead to satisfy Lead type
- load website and industry from converted business when editing opportunity
- inline location landing page JSON-LD
- force flex-row on dropdown items to override NavigationMenuLink default flex-col
- inline pricing page JSON-LD
- restrict input styling to non-selectable types and refactor LinkedIn modal layout for better spacing
- inline software feature page JSON-LD
- resolve avatar clipping and aspect ratio issues in SafeImage and UserProfileImage
- reduce padding and move figcaption inside aspect-ratio container

