feat: MPS-24 Phase 2.6b — facet nav on shop home + mobile SERP lanes

Operator review on tablet showed two gaps in the 2.6 ship:
- Shop home (layout 2 lanes) had no facet sidebar — only tag detail did
- Mobile lanes were horizontal Netflix-style tile rows with no
  description visible at all

This batch extends the facet experience across every page where the
operator opted into categorization (home_layout >= 1):

- New templates/_facet_nav.j2 with three macros (facet_form, sidebar,
  details). One source of truth for the controls, three variants of
  the wrapper. shop_tag.j2 refactored to import the macro.
- home.j2 + shop.j2 now wrap content in .tag-detail-layout when
  home_layout >= 1, rendering both the desktop sidebar and the mobile
  <details> accordion. CSS toggles visibility per viewport.
- Each lane in layout 2 now emits BOTH horizontal tiles AND vertical
  .serp-list-row markup with 6-sentence excerpts. CSS shows tiles
  >=800px, SERP rows <800px. Tablet / phone shoppers see image +
  title + price + description excerpt under each tag heading.
- views/shop.py: facet_tags is populated for any home_layout >= 1
  (was only on ?tag= filter); sort + price now also filter the
  non-tag-filtered home grid when the shopper applies them.

Native HTML. No JS dependency. Same controls everywhere.

Test: test_shop_home_lanes_renders_facet_sidebar_and_mobile_rows.
Docs: CLAUDE.md MPS-24 section, architecture matrix, ticket Phase 2.6b.
This commit is contained in:
russell@unturf.com 2026-05-15 16:30:23 -04:00
parent 0f84e6871b
commit 8970e960fb
No known key found for this signature in database
10 changed files with 387 additions and 98 deletions

View file

@ -219,6 +219,8 @@ mps_page_session (raw rows)
| Tag auto-suggest (MPS-24 Phase 2) | `lib/tag_suggest.py` over `Product.title` + `Product.description` | `?show_suggestions=1` on `/s/{id}/tags` + `scripts/backfill_tags.py` | Never auto-applies |
| Tag-detail facet sidebar (MPS-24 Phase 2.6) | `shop_tag.j2` + `views/shop.py` `_price_range_from_request` / `_filter_by_price_range` | Sort + price range + categories list, GET form, sidebar ≥800px, top chip strip <800px | Always on for tag detail pages |
| 6-sentence SERP excerpt (MPS-24 Phase 2.6) | `Product.excerpt_sentences(n=6, max_chars=1500)` via shared `_strip_markdown()` helper | `shop_tag.j2` row description | Always on |
| Facet nav on shop home (MPS-24 Phase 2.6b) | `_facet_nav.j2` macros + `home.j2` / `shop.j2` wrappers | Desktop sidebar + mobile `<details>` accordion when `shop.home_layout >= 1` | Opt-in via home_layout |
| Mobile SERP rows under each lane (MPS-24 Phase 2.6b) | `home.j2` / `shop.j2` `.tag-lane-rows` markup + CSS visibility swap | Horizontal tiles ≥800px; vertical SERP rows with 6-sentence excerpts <800px | On for layout 2 |
## Ticket Index

View file

@ -319,6 +319,28 @@ picker is Phase 2).
| `tests/test_models.py` | `TestTagSuggestPureFunctions` — 11 unit tests over tokenize / stem / cluster |
| `tests/test_functional.py` | `test_suggest_clusters_renders_candidates`, `test_apply_suggestion_creates_tag_and_attaches_products`, `test_dismiss_suggestion_adds_to_stopwords`, `test_apply_suggestion_rejects_empty_input` |
### Phase 2.6b — facet nav on shop home (layout 2) + mobile SERP rows under each lane (shipped 2026-05-15)
Follow-up to 2.6 after operator review on tablet: layout 2 (sectioned
lanes) had no facet sidebar and mobile lanes were horizontal tile rows
with no description (image attached in chat shows the issue on
`shop.printableprompts.com` rendered on a tablet in Firefox).
| Surface | Change |
|---------|--------|
| `templates/_facet_nav.j2` (new) | Reusable Jinja macros: `facet_form(...)` shared body, `sidebar(...)` desktop wrapper, `details(...)` mobile `<details>` accordion. Single source of truth for the controls |
| `templates/shop_tag.j2` | Switched to the macro; both sidebar + details now render |
| `templates/home.j2` + `shop.j2` | Wrapped lanes content + flat/filtered grid in `.tag-detail-layout` when `shop.home_layout >= 1`; both facet variants render. Each lane now emits BOTH horizontal `.tag-lane-grid` (desktop) AND vertical `.serp-list.tag-lane-rows` with 6-sentence excerpts (mobile/tablet) |
| `views/shop.py` | `_build_home_layout_context()` populates `facet_tags` for any `layout >= 1` (was only on `?tag=` filter). Also wires sort + price filter on non-tag-filtered home when shopper applies them |
| `static/css/common.css` | New `.facet-details` styles (mobile accordion); `aside.facet-nav` hidden <800px; `.tag-lane-grid` hidden <800px; `.serp-list.tag-lane-rows` hidden 800px |
| `tests/test_functional.py` | `test_shop_home_lanes_renders_facet_sidebar_and_mobile_rows` |
Mobile rule: shopper opens `shop.foo.com` on phone, taps "Filter & sort"
to open the `<details>` accordion (sort, price, every category), then
scrolls a vertical SERP list with description excerpts under each tag
heading. Desktop rule: 220px left sidebar + Netflix-style horizontal
tile lanes. Same controls, same data, viewport-driven presentation.
### Phase 2.6 — tag-detail facet sidebar + 6-sentence SERP excerpt (shipped 2026-05-15)
Operator feedback after Phase 2.5: tag-detail SERP rows were truncating