JOURNAL — IMAGE UPLOAD AND ARCHIVE UPDATE

INSTALL ON YOUR EXISTING SITE
Back up the site and database first. Upload the contents of Software into your
existing Journal application directory, merging directories and replacing the
application files. Keep your existing config.php, database, and uploaded images.
Do not run install.php again. No database migration is required.
If .htaccess or .user.ini has custom hosting settings, merge the supplied changes
instead of replacing your settings. Reload the editor after updating.

CHANGES
- Post images appear after the story text with 32px spacing.
- Images fit within 640px wide and 500px high, preserving proportions without
  cropping or enlarging small images. Existing images get the same display limit.
- With JavaScript enabled, large post images are resized before upload, helping
  avoid PHP request limits. Without JavaScript the normal form upload remains
  available; images are still constrained when displayed.
- Invalid images and PHP upload failures are reported instead of silently skipped.
  Failed JavaScript submissions leave your text and selected image in the editor.
- The uploads directory is created if missing; it must be writable by PHP.
- .user.ini requests an 8MB file limit and 12MB total request limit. PHP-FPM/CGI
  hosts may take several minutes to apply it. Host/proxy limits can still override
  these values. PHP module installations may need the host to set the limits.
- Exactly ten published posts per page, newest first, with Older/Newer navigation.
  The oldest posts move to later pages; nothing is deleted or unpublished.
  Previous custom page-size settings are ignored. Drafts and future posts remain
  excluded, and equal publication dates use post ID as a stable tie-breaker.
- Homepage hero-image PHP upload failures are no longer silently skipped.

VALIDATION
PHP syntax checks passed. HTTP tests passed for real multipart image saving,
invalid images, PHP file/request limits, existing-image preservation, image
placement, and 25 posts split into pages of 10/10/5. These HTTP tests used a
SQLite adapter in a disposable copy, not a live MySQL server. JavaScript tests
with browser mocks passed for landscape/portrait scaling, exact bounds, small
images, and save-error feedback. No live hosting or real browser visual test
has been performed. The production application still uses MySQL unchanged.
