Layout QA

Checked on the latest main. The automated check is office/layout.test.mjs. It passed with no remaining issues.

What was checked

Issues found and fixed

  1. Mobile menu did not cover the page in WebKit. The nav is position: fixed inside a sticky header, so opening it left the links invisible or stuck at visibility: hidden / opacity: 0. Opening the menu now takes the header out of sticky positioning and paints a full-screen menu. The close button stays above the menu.
  2. Logo link was 37px tall on small screens. The brand link is now at least 44px tall below 960px.
  3. Journal “The Journal” link on tag pages was 15px tall. That kicker link is now at least 44px tall.
  4. Admin filter chips and Site Photos links were under 44px. Filter, tab, jump, and “View page” controls are now at least 44px tall. Team checkbox rows are at least 44px tall.

No overlapping text, no horizontal page scroll, no clipped text, no broken images, and no console errors remained after those fixes.

Screenshots

Full-page screenshots are in /opt/cursor/artifacts/qa/.

Item D — Site Photos

Done. Every public image slot is editable from Site Photos (/admin/photos) by the owner only. The nav entry is hidden from admins. GET, upload/replace, and reset under /admin/photos return 403 for an admin session and for an anonymous visitor, including when the admin posts a valid CSRF token. The owner can open the page and save a change.

The inventory is linkPhotoSlots() in office/photos.test.mjs (“every public image slot maps to an editable setting”). It walks every public template for <img>, {% photo %}, and CSS url() backgrounds, and it fails if a slot has no default image. The current inventory is 131 slots, 0 unmapped. Pages: Brand (logo, favicon, share image), Home (hero, inset, features, letters, closing backdrop), Weddings, Parties, Corporate, Packages, service cards, Portfolio (including the gallery contact sheet and stories), About (including the team portrait), Journal (cards, lead, covers, share images, inline images), Contact, testimonials, case study, thank-you, 404, privacy, terms, and photo credits.

Each slot has a preview, alt text, a focal-point crop (center, edges, and corners), a JPG/PNG/WebP upload under 8 MB, replace, and reset to the built-in photograph. Uploads are sniffed, resized with sharp, and stored on the disk at /var/data/uploads/site (beside OFFICE_DB). The public page picks up the replacement on the next request.

Empty frames fall back to an existing stock photograph (florals, a reception table, or evening lights) instead of rendering a blank box. The about-page team portrait keeps the garden ceremony as its stand-in and says so in the caption.

office/photos.test.mjs passed: 4 tests. The owner-only check is in that file. The photo editor screenshots below are Chromium at 1440px. The lean layout pass also opened /admin/photos as the owner.