Files
intotheeast-com/docs/working/specs/2026-06-21-homepage-redesign.md

206 lines
7.5 KiB
Markdown

# Homepage Redesign Spec
**Date:** 2026-06-21
**Goal:** Make the homepage context-aware: a persistent two-column map+feed layout that switches its right column between an active-trip feed and a curated highlights grid depending on whether Mischa is currently travelling.
---
## 1. Mode switch
A `travelling` toggle in `user/config/site.yaml` controls which mode the homepage renders. It is exposed in Admin2's Site Configuration panel via a new site config blueprint.
| `travelling` | Homepage mode |
|---|---|
| `true` | Active trip — map + live feed |
| `false` | Between trips — map + highlights grid |
The `active_trip` value changes format: it now stores the full page route (`/trips/italy-2026-demo`) instead of the bare slug (`italy-2026-demo`), because it will be managed via a `type: pages` dropdown in Admin2 rather than a free-text field.
---
## 2. Data model changes
### 2a. New file: `user/blueprints/config/site.yaml`
Exposes site config fields in Admin2:
```yaml
active_trip:
type: pages
label: Active Trip
start_route: '/trips'
show_root: false
show_slug: true
travelling:
type: toggle
label: Currently Travelling
highlight: 1
default: false
```
### 2b. `user/config/site.yaml` — value format update
```yaml
# Before
active_trip: italy-2026-demo
# After
active_trip: /trips/italy-2026-demo
travelling: false
```
### 2c. Trip page blueprint (`user/themes/intotheeast/blueprints/trip.yaml`)
Add one field:
```yaml
tagline:
type: text
label: Tagline
help: Short description shown on homepage highlight cards (e.g. "6 weeks from Venice to Sicily by train")
```
### 2d. Entry blueprint (`user/themes/intotheeast/blueprints/entry.yaml`)
Add one field:
```yaml
featured:
type: toggle
label: Featured highlight
help: Show this entry as a homepage highlight when not travelling
default: false
```
### 2e. Story blueprint (`user/themes/intotheeast/blueprints/story.yaml`)
Add the same `featured` toggle (identical definition). Stories are not auto-included — they opt in the same way as journal entries.
---
## 3. Layout
The two-column structure is always present regardless of mode.
```
┌────────────────────────┬────────────────────────────────┐
│ │ │
│ MapLibre map │ Right column │
│ (sticky, │ (switches by mode) │
│ always visible) │ │
│ │ │
└────────────────────────┴────────────────────────────────┘
```
- Map: left column, ~45% width, `position: sticky; top: 0; height: 100vh`
- Right column: ~55% width, scrollable
- Mobile: map stacks on top at `40vh`, right column scrolls below
---
## 4. Active trip mode (`travelling: true`)
### Right column
Chronological feed, newest first. Merges journal entries and story cards from the active trip's `/dailies` and `/stories` sub-pages. This is the existing feed behaviour — no changes to card markup or order logic.
Trip title and entry counts shown above the feed.
### Map
- Marker per journal entry with `lat`/`lng` in frontmatter
- Journey line connecting markers in order
- GPX route files loaded from the active trip page media (same pattern as `map.html.twig`, including the smart connector-suppression logic from the GPX connector spec)
- Clicking a marker scrolls to that entry card in the feed
### Template change (`home.html.twig`)
The slug-based path construction is replaced with direct route usage:
```twig
{# Before #}
{% set slug = config.site.active_trip %}
{% set trip = grav.pages.find('/trips/' ~ slug) %}
{% set dailies_page = grav.pages.find('/trips/' ~ slug ~ '/dailies') %}
{% set stories_page = grav.pages.find('/trips/' ~ slug ~ '/stories') %}
{# After #}
{% set trip_route = config.site.active_trip %}
{% set trip = grav.pages.find(trip_route) %}
{% set dailies_page = grav.pages.find(trip_route ~ '/dailies') %}
{% set stories_page = grav.pages.find(trip_route ~ '/stories') %}
```
---
## 5. Between-trips mode (`travelling: false`)
### Highlight selection logic
1. Collect all published trip pages from `/trips`
2. For each trip, collect all published children from `/dailies` and `/stories` where `featured: true`
3. From each trip's candidates, pick one at random (`random()`)
4. Gather the per-trip picks into a pool; if more than 6 trips have candidates, randomly discard down to 6
5. Shuffle the final pool so cards appear in random order (not grouped by trip)
### Right column
A grid of highlight cards. Below the grid, a "Explore all past trips →" CTA linking to `/trips`.
**Grid layout:** 3 columns on desktop, 2 on tablet, 1 on mobile.
### Highlight card anatomy
```
┌──────────────────────────┐
│ [hero image] │
├──────────────────────────┤
│ ✦ Story / ◎ Journal │ ← type badge
│ Entry title │ ← links to entry page
│ Italy 2025 │ ← trip title
│ "tagline from trip" │ ← trip tagline
│ → View trip │ ← links to trip page
└──────────────────────────┘
```
- Hero image: `entry.media.images|first` if no `hero_image` frontmatter field; cropped to 16:9
- Type badge: `✦ Story` (accent colour) or `◎ Journal` (muted)
- Entry title: full clickable link to the entry URL
- Trip title + tagline: small secondary text; trip title links to the trip page
- "→ View trip": explicit CTA link to the trip page
Cards with no hero image still render but without an image block.
### Map
- Marker per highlighted entry that has `lat`/`lng` in frontmatter
- No journey line between markers (entries are from different trips)
- No GPX data loaded
- Map fits bounds across all markers; falls back to a world-level zoom if no entries have coordinates
- Clicking a marker scrolls to that highlight card
---
## 6. Files changed
| File | Change |
|---|---|
| `user/blueprints/config/site.yaml` | **Create** — exposes `active_trip` (pages) + `travelling` (toggle) in Admin2 |
| `user/config/site.yaml` | **Update**`active_trip` value to full route; add `travelling: false` |
| `user/themes/intotheeast/blueprints/trip.yaml` | **Update** — add `tagline` text field |
| `user/themes/intotheeast/blueprints/entry.yaml` | **Update** — add `featured` toggle |
| `user/themes/intotheeast/blueprints/story.yaml` | **Update** — add `featured` toggle |
| `user/themes/intotheeast/templates/home.html.twig` | **Update** — mode branch, route-based lookup, highlights logic, GPX loading |
| `user/themes/intotheeast/css/style.css` | **Update** — highlight card styles, grid layout |
No new plugins. No build pipeline. All changes in `user/`.
---
## 7. Constraints
- `post-form.md` (`pageconfig.parent`) remains manually synced with `active_trip` — this is unchanged behaviour documented in CLAUDE.md
- The `type: pages` field in Admin2 is confirmed present in the bundle but untested in a user site config blueprint; if it does not render, fall back to `type: select` with static trip slug options (one-minute fix, no other code changes needed)
- Random selection uses Twig's `random()` — order varies per page load; this is intentional