- Remove 1000 property limit from count display
- Add MLS_Cluster class for geohash-based server-side clustering
- Add AJAX endpoint for dynamic cluster loading based on viewport/zoom
- Update property-results.php and ajax-handlers.php to use efficient counting
- Update map JavaScript to fetch clusters dynamically as user pans/zooms
- Server returns clusters at low zoom, individual markers at high zoom
- Fixes property count showing 1000 instead of actual ~30k properties
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Show spinning loader while images load
- Lazy load images as cards enter viewport (with 200px buffer)
- Use data-bg attribute to defer background-image loading
- MutationObserver detects AJAX-loaded content
- Spinner hides when image loads or on error
- Fallback to placeholder on load error
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
MLS Grid media URLs expire after ~24 hours. Instead of running
scheduled syncs, this adds on-demand refresh when images are requested:
- Add is_url_expired() to parse expires timestamp from media URLs
- Add refresh_media_urls() to fetch fresh URLs from API for one listing
- Add get_property_media() API method using ListingId filter
- Image endpoint checks URL expiration before fetching
- If expired, refreshes URLs from API then proceeds with fetch
This is more efficient than scheduled full syncs because:
- Only refreshes URLs for listings actually being viewed
- Zero overhead for unviewed listings
- Scales naturally with traffic
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Create MLS_Image_Endpoint class with on-demand thumbnail generation
- Use ImageMagick to convert images to WebP format
- Thumbnail sizes: 800px (thumb) and 1800px (full), maintain aspect ratio
- Only downsize images, never upsize
- Cache thumbnails in wp-content/uploads/mls-thumbnails/
- Add mls_get_image_url() helper function (1-based index)
- Update property cards to display thumbnail as background-cover image
- Long cache headers (1 year) with ETag support
URL format: /mls-image/{listing_key}/{index}/{size}/
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Major changes to sync strategy following MLS Grid best practices:
- Initial sync now fetches only Active/Pending properties (~30K vs 1.3M)
- Replication (incremental) fetches all changes, deletes non-Active/Pending
- On-demand media fetching replaces background queue (avoids rate limits)
- Media downloaded and cached when first viewed, not during sync
- Updated CLI commands: wp mls media status/fetch/clear
- Comprehensive documentation with troubleshooting guide
This fixes the "Value out of range" API error caused by high $skip values.
Co-Authored-By: Claude <noreply@anthropic.com>
- Add download_status, retry_after, queued_at columns to mls_media table
- Add mls_media_log table for download attempt tracking
- Rewrite media handler to queue downloads instead of immediate download
- Add 700ms delay between downloads (25% buffer over 2/sec limit)
- Add 3-hour backoff for rate-limited (429) responses
- Add max 5 attempts before marking as permanently failed
- Add wp mls media command: status, process, reset, logs
- Deprecate wp mls sync media in favor of wp mls media process
- Update documentation with queue system details and cron examples
Media downloads are now separate from property sync:
1. wp mls sync full/incremental - syncs properties, queues media
2. wp mls media process - downloads queued media with rate limiting
Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add wp mls recovery list to show resumable syncs
- Add wp mls recovery auto to auto-resume most recent failed sync
- Add wp mls recovery cleanup to mark stale syncs (>1hr) as failed
- Track last_next_link during incremental sync pagination
- Add get_resumable_syncs(), cleanup_stale_syncs(), auto_resume() methods
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add --verbose flag to sync commands for detailed API request/response output
- Add progress indicators (.=#xPpE|) for compact sync output
- Implement exponential backoff (1s, 2s, 4s, 8s, 16s) for media downloads
- Log failed media downloads to wp-content/uploads/mls-missing-media.log
- Add 'wp mls cache missing' command to view/clear the log
- Retry on rate limit (429) and server errors (5xx)
- Update documentation with new features
Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Features:
- Full sync of NorthStar MLS properties via MLS Grid API v2
- Incremental sync using ModificationTimestamp
- Local media download and storage
- Rate limit compliance (2 req/sec, 7200/hr, 40000/day)
- Sync state tracking with resume capability
- WP-CLI commands: test, sync, status, stats, cache
- Admin settings page with manual sync triggers
- Public API functions: mls_get_properties, mls_get_property, etc.
Database tables:
- mls_properties: Listing data with full field mapping
- mls_media: Downloaded images
- mls_sync_state: Sync progress tracking
- mls_rate_limits: API usage tracking
- mls_sync_log: Debug logging
Documentation:
- docs/CLAUDE.md: AI development guide
- docs/API.md: MLS Grid API reference
- docs/USAGE.md: User documentation
Tested: Connection, auth, sync 10 records, media download verified
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Gallery thumbnails: constrain container to 88vw on mobile to prevent overflow
- Property specs: show as compact two-column list in single card on mobile,
keep boxed grid layout on desktop
Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Changed label to flex column layout and hide br tags that CF7
inserts between label text and input fields.
Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Adjusted negative margins so the clickable link area stays within
proper bounds and doesn't overlap the spacing below agent-info.
Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Added social icon links before phone button in header CTA area
- Icons styled with border, hover effects matching site aesthetic
- Only visible on desktop (>= 1024px) alongside phone button
- Uses theme options for URLs (same as footer)
Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Changed select name from 'location' to 'property_location' to match
the property archive filter parameter.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Add homeproz_get_active_locations() helper function
- Only shows locations that have properties with Active or Pending status
- Applied to homepage community dropdown and properties page location filter
- Sold properties no longer count toward location visibility
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Hero changes:
- Remove top padding from .site-main (was causing inconsistent gaps)
- Remove margin-bottom and border from archive-hero
- Add padding-top to property archive container
- Change resources section background to --color-bg-dark
Service cards:
- Replace "Find a Rental" with "Resources & Guides"
- Reorder: Find a Home, Sell Your Home, Resources & Guides
- Update subtitle to remove rental reference
- Add book icon for resources card
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- No margin below hero on mobile/tablet (< 1200px)
- 2rem margin below hero on desktop (>= 1200px)
- Consistent hero styling across all interior pages
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Currency inputs auto-format with thousand separators on input
- Only allows numeric characters (strips letters, symbols, etc.)
- .val() returns raw integer for calculations
- Percentage inputs allow only numbers and one decimal point
- Select all on focus for easy replacement
- Maintains cursor position while typing
- Real-time sync between down payment dollar and percent fields
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Updated global form styles in main.scss and mortgage calculator inputs
to use #000 background instead of color variables.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Two-column layout matching property details page pattern
- Real-time mortgage calculation with principal, interest, loan amount, and total interest
- Input formatting with currency/percentage display
- Down payment syncs between dollar amount and percentage
- Sidebar with quick tips, help contact widget, and related resources
- "How to Use" and "Keep in Mind" sections with practical guidance
- Widget titles use Times New Roman 18px bold to match existing styles
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Property details page:
- Move address to header above gallery
- Add property type badges (blue residential, red commercial)
- Gallery autoplay with play/pause button, 5-second interval
- Fade transitions for autoplay, slide transitions for swipe
- Thumbnail navigation with sync
- Swipe support in gallery and lightbox
- Widget titles: 18px Times New Roman bold
- Remove breadcrumbs
Layout and styling:
- Container width: 1400px
- Contact page map 50% taller (375px)
- Contact info labels: Times New Roman 16px
- Agent photo backgrounds solid black
- CTA accent button hover: black text
Clickable components:
- Service cards fully clickable with stretched links
- Resource cards fully clickable with stretched links
- Addresses link to Google Maps (contact page, footer)
Footer updates:
- Add Send Us a Message link with paper airplane icon
- Replace credentials with legal section
- Privacy Policy, Fair Housing, MLS Disclaimer, Brokerage Disclosure links
- Credits: Web Design by HansonXyz
Other:
- Install Classic Editor plugin
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Enhance archive-hero to support optional background images
- Add Page Hero ACF fields (title, subtitle, background) for all pages
- Add Properties Page hero settings in Theme Options
- Update all page templates to use consistent archive-hero style
- Resource pages now use archive-hero with featured image fallback
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Add 5 new hero images to assets/images/hero-gallery/
- Create hero-section.js with image rotation (6s interval)
- Only preload/animate at >= 1450px to save mobile bandwidth
- Fade transition with slight grow effect
- Add overflow:hidden to prevent scrollbar during transition
- Images use 30% right crop via transform system
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Matches service cards styling:
- Dark background (--color-bg-dark)
- Red accent border (--color-accent)
- Rounded corners with overflow hidden
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Doubled logo max-width from 200px to 400px
- Created logo-transparent.webp with transparent background
- Used flood fill to preserve internal black elements
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Added logo parameter to hero-section.php component
- Added .hero-section-logo CSS (200px max-width, centered)
- Updated front-page.php to pass logo.webp to hero
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Use logo.webp from assets/images
- Logo height: 50px
- Negative margin (-4px) to fit within existing header height
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Remove status dropdown (always show all properties)
- Remove sort dropdown (use status-based sorting)
- Sort order: Active > Pending > Sold, then by modified date
- Map view: half height, 2-column property grid
- Beds field same width as others
- Add CLAUDE.md documentation for property system
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- All filters now on one row at 1200px+
- Beds field narrower (70px) for single-digit values
- Price range wider with compact $Xk format
- Sort, Search, Reset moved inline after price range
- Shorter labels: Type, Status, Beds, Sort
- Responsive: 2-col mobile, 4-col tablet, full row desktop
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Changed 'homeproz-main' to 'homeproz-script' so homeprozAjax variable
is actually attached to the correct script and available on the page.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
The previous WP_Query with meta_query required agent_order to exist,
which excluded agents that hadn't been edited since the field was added.
Changed to simpler approach: fetch all published agents with get_posts(),
filter disabled in PHP, sort by order (defaulting to 10) then alphabetically.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Added agent_order (number) and agent_disabled (toggle) ACF fields
- Created archive-agent.php template for /agents/ listing page
- Queries only active agents, ordered by agent_order then title
- Grid layout with agent cards showing photo, name, title, bio
- Contact action buttons (phone, email, profile)
- Added "Agents" link to footer fallback menu
- Updated single-agent.php to return 404 for disabled agents
- Updated property-agent.php to handle disabled agents:
- Shows agent name and photo (for historical reference)
- Replaces agent contact with office phone number
- Removes Agent Profile button and email
- Adds "Contact Us" button linking to contact form
- Added archive-agent.scss with responsive grid styles
Admin can now:
- Set display order for agents (lower numbers first)
- Disable agents who have left (hides from listing, 404s profile)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Wrapped agent avatar/name/title in single clickable link to profile
- Added Agent Profile button between Call and Email buttons
- Added hover styles for agent info link block
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Changed listing_agent ACF field from user type to post_object (Agent CPT)
- Assigned random agents to all existing properties
- Updated property-agent.php template to:
- Pull agent data from Agent CPT (photo, phone, email, title)
- Link agent name to their profile page
- Show generic contact card when no agent assigned
- Always show "Request Information" widget linking to contact page
- Added property inquiry flow:
- Contact links include ?property=PropertyName GET parameter
- Contact page pre-fills message with property inquiry text
- JS handles CF7 textarea pre-fill if plugin is active
- Added styles for new property-inquiry-card and generic-contact-card widgets
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Created Agent custom post type with ACF fields (phone, email, website, title, license, bio, gallery, social links repeater)
- Added single-agent.php template with modern profile layout: header with photo/contact buttons/social links, biography section, photo gallery, current listings, sidebar contact card
- Created single-agent.scss with responsive styling matching HomeProz dark theme
- Updated single-property.php sidebar: moved property header widget, added document downloads with primary button styling
- Imported 4 agents from homeprozrealestate.com with profile images
- Added agent scrape scripts for reference
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Completed tasks:
- html-7jz: Added Communities section with landing page and community template
- html-t8u: Added Resources section with Buyer's Guide and Seller's Guide
- html-3nq: Enhanced footer with office hours, professional logos, license info
New files:
- page-communities.php: Communities landing page listing all locations
- template-community.php: Individual community page template
- page-resources.php: Resources hub with featured guides
- template-resource.php: Individual resource/guide page template
- content-communities.scss, content-resources.scss: Styles for new pages
WordPress changes:
- Created Communities page with 3 child pages (Albert Lea, Austin, Glenville)
- Created Resources page with 2 child pages (Buyer's Guide, Seller's Guide)
- Added Communities and Resources to primary navigation menu
- Added new location terms for communities
Footer enhancements:
- Office hours section (4-column grid now)
- Professional association logos (REALTOR, Equal Housing)
- License number display
Phase 8 P1 tasks completed:
- Added location search dropdown to hero section (html-98b)
- Added service cards section with Buy/Rent/Sell options (html-5bw)
- Separated Featured Homes and Commercial/Land into distinct sections (html-2fp)
Changes:
- hero-section.php: New show_location_search option with community dropdown
- service-cards.php/scss: New component with 3 service cards
- front-page.php: Hero with search, service cards, separate property sections
- Added community terms: Glenville, Emmons, Clarks Grove, Alden, Hartland, Geneva
- Initialize beads (.beads/ directory)
- Add Claude Code hooks for SessionStart/PreCompact
- Update CLAUDE.md to clarify all build artifacts are committed
- Update .gitignore to allow node_modules and dist