Files
intotheeast-com/docs/working/plans/2026-06-20-demo-data-redesign.md

38 KiB
Raw Permalink Blame History

Demo Data Redesign Implementation Plan

For agentic workers: REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (- [ ]) syntax for tracking.

Goal: Replace patchwork demo content with a single high-quality italy-2026-demo trip following the real 8-day Tuscan cycling loop, with 12 journal entries (with photos) and 4 stories exercising all shortcode types.

Architecture: All demo source files live in user/docs/demo/trips/italy-2026-demo/. make demo-load copies them into user/pages/01.trips/italy-2026-demo/ inside Docker. Images are downloaded once and committed to the demo source so the Makefile stays simple (cp -r copies everything). Tests in tests/ui/stories.spec.js reference story slugs that must match the new folder names.

Tech Stack: Grav CMS page files (YAML frontmatter + Markdown), story-blocks shortcodes (snap-gallery, scrolly-section, chapter-break, pull-quote), picsum.photos placeholder images, Playwright tests, Make.

Global Constraints

  • All content paths are relative to project root: /home/mischa/Nextcloud/Projects/travel-blog-intotheeast/
  • user/ is a separate git repo — commit content changes there with git -C user commit
  • Never read .env; never ssh directly to production
  • Demo trip slug: italy-2026-demo; fictional dates: 2026-09-01 to 2026-09-08
  • hero_image: '' in all entry frontmatter — template auto-selects 01.jpg as hero
  • Story images: 1600×1000 from https://picsum.photos/seed/<seed>/1600/1000
  • Entry images: 1200×800 from https://picsum.photos/seed/<seed>/1200/800
  • Dev server: http://localhost:8081

Task 1: Cleanup, GPX rename, trip.md, dailies.md

Files:

  • Delete: user/docs/demo/trips/japan-korea-2026/ (entire folder)

  • Delete: user/docs/demo/trips/italy-2025/dailies/ (entries only)

  • Delete: user/docs/demo/trips/italy-2025/04.stories/ (stories only)

  • Delete: user/docs/demo/trips/italy-2026-demo/dailies/ (replace with new entries in later tasks)

  • Delete: user/docs/demo/trips/italy-2026-demo/04.stories/ (replace with new stories in later tasks)

  • Rename: 4 GPX files in user/docs/demo/trips/italy-2026-demo/

  • Modify: user/docs/demo/trips/italy-2026-demo/trip.md

  • Create: user/docs/demo/trips/italy-2026-demo/dailies/dailies.md

  • Modify: CLAUDE.md (update demo-load description)

  • Step 1: Remove old demo data

rm -rf user/docs/demo/trips/japan-korea-2026
rm -rf user/docs/demo/trips/italy-2025/dailies
rm -rf user/docs/demo/trips/italy-2025/04.stories
rm -rf user/docs/demo/trips/italy-2026-demo/dailies
rm -rf user/docs/demo/trips/italy-2026-demo/04.stories
  • Step 2: Rename the 4 new GPX files
cd user/docs/demo/trips/italy-2026-demo

mv "2025-10-11_2627663255_TGE Tuscany 2025 Final Route - 8 days - Day 1 - from Venturina Terme to Sugherella.gpx" \
   day-1-campiglia-to-sugherella.gpx

mv "2025-10-12_2630489431_TGE Tuscany 2025 Final Route - 8 days - Day 2.gpx" \
   day-2-sugherella-to-orbetello.gpx

mv "2025-10-13_2632495944_TGE Tuscany 2025 Final Route - 8 days - Day 3.gpx" \
   day-3-orbetello-to-sorano.gpx

mv "2025-10-14_2634086364_TGE Tuscany 2025 Final Route - 8 days - Day 4.gpx" \
   day-4-sorano-to-val-dorcia.gpx

cd ../../../..
  • Step 3: Verify 7 GPX files exist with correct names
ls user/docs/demo/trips/italy-2026-demo/*.gpx

Expected output (7 files):

day-1-campiglia-to-sugherella.gpx
day-2-sugherella-to-orbetello.gpx
day-3-orbetello-to-sorano.gpx
day-4-sorano-to-val-dorcia.gpx
day-5-val-dorcia-to-siena.gpx
day-6-siena-to-florence.gpx
day-8-coast-to-piombino.gpx
  • Step 4: Update trip.md

Write user/docs/demo/trips/italy-2026-demo/trip.md:

---
title: 'Tuscany 2026'
template: trip
date: '2026-09-01'
date_start: '2026-09-01'
date_end: '2026-09-08'
cover_image: ''
---
  • Step 5: Create dailies index page

Create user/docs/demo/trips/italy-2026-demo/dailies/dailies.md:

---
title: Journal
template: dailies
---
  • Step 6: Recreate empty story and entry directories
mkdir -p user/docs/demo/trips/italy-2026-demo/dailies
mkdir -p user/docs/demo/trips/italy-2026-demo/04.stories
  • Step 7: Update CLAUDE.md demo-load description

In CLAUDE.md, find the line:

- `make demo-load` — load demo entries for both trips (Japan/Korea 2026 + Italy 2025 with real GPX)

Replace with:

- `make demo-load` — load demo content into `italy-2026-demo` trip (journal entries + stories + GPX)
  • Step 8: Commit
git -C user add -A
git -C user commit -m "chore(demo): cleanup old demo data, rename GPX files, update trip.md"

git add CLAUDE.md
git commit -m "docs: update demo-load description in CLAUDE.md"

Task 2: Update stories.spec.js for new story slugs

Files:

  • Modify: tests/ui/stories.spec.js

The existing tests point to old story slugs (val-dorcia-dawn, long-climb-montalcino). New slugs are val-dorcia-at-dawn and sorano-rock-and-time. The shortcode assertions stay identical — the new stories are designed to match them.

  • Step 1: Update slug constants and comments in stories.spec.js

Replace the top of tests/ui/stories.spec.js (lines up to the first test):

// @ts-check
// Tests: S1S7 — story mode rendering and navigation
// Requires demo data: run `make demo-load` before this suite.
const { test, expect } = require('@playwright/test');

const STORIES_URL    = '/trips/italy-2026-demo/stories';
const STORY_GALLERY  = '/trips/italy-2026-demo/stories/val-dorcia-at-dawn';       // gallery-led: snap-gallery × 2, chapter-break, text-only pull-quote
const STORY_SCROLLY  = '/trips/italy-2026-demo/stories/sorano-rock-and-time';     // scrolly-led: scrolly-section × 2, chapter-break, pull-quote with image
const DEMO_STORY     = '/trips/italy-2026-demo/stories/val-dorcia-at-dawn';       // used for cross-trip hero sanity check
  • Step 2: Update the two hardcoded URLs in S7

In tests/ui/stories.spec.js, find and replace the hardcoded URL in S7:

Old:

test('S7: story body back link has back-pill class', async ({ page }) => {
    await page.goto('/trips/italy-2026-demo/stories/val-dorcia-dawn');

New:

test('S7: story body back link has back-pill class', async ({ page }) => {
    await page.goto('/trips/italy-2026-demo/stories/val-dorcia-at-dawn');
  • Step 3: Verify tests reference correct slugs
grep -n "val-dorcia\|montalcino\|sorano\|florence-without" tests/ui/stories.spec.js

Expected: no references to val-dorcia-dawn or long-climb-montalcino; val-dorcia-at-dawn and sorano-rock-and-time appear.

  • Step 4: Commit
git add tests/ui/stories.spec.js
git commit -m "test(stories): update story slugs to match new demo content"

Task 3: Write Story 1 — Sorano: Rock and Time

Target: user/docs/demo/trips/italy-2026-demo/04.stories/01.sorano-rock-and-time/
Test coverage: STORY_SCROLLY — needs scrolly-section × 2, chapter-break, pull-quote with image

Files:

  • Create: user/docs/demo/trips/italy-2026-demo/04.stories/01.sorano-rock-and-time/story.md

  • Create: user/docs/demo/trips/italy-2026-demo/04.stories/01.sorano-rock-and-time/hero.jpg

  • Create: user/docs/demo/trips/italy-2026-demo/04.stories/01.sorano-rock-and-time/photo-1.jpg

  • Create: user/docs/demo/trips/italy-2026-demo/04.stories/01.sorano-rock-and-time/photo-2.jpg

  • Step 1: Create story directory and download images

mkdir -p user/docs/demo/trips/italy-2026-demo/04.stories/01.sorano-rock-and-time
SDIR=user/docs/demo/trips/italy-2026-demo/04.stories/01.sorano-rock-and-time
curl -sL "https://picsum.photos/seed/demo-s1-hero/1600/1000" -o "$SDIR/hero.jpg"
curl -sL "https://picsum.photos/seed/demo-s1-1/1600/1000"   -o "$SDIR/photo-1.jpg"
curl -sL "https://picsum.photos/seed/demo-s1-2/1600/1000"   -o "$SDIR/photo-2.jpg"
  • Step 2: Write story.md

Write user/docs/demo/trips/italy-2026-demo/04.stories/01.sorano-rock-and-time/story.md:

---
title: 'Sorano: Rock and Time'
date: '2026-09-03'
location_name: Sorano
location_country: Italy
lat: 42.683
lng: 11.715
hero_image: hero.jpg
hero_alt: Medieval town of Sorano clinging to pale tufa cliffs at dusk
published: true
---

The road from Orbetello climbs inland through scrubland and heat. For most of the afternoon there is nothing on the horizon except sky and the occasional electricity pylon. Then, at the top of a ridge, Sorano appears — and the word "appears" does not quite cover it. The town has been carved from a cliff of tufa, a pale volcanic rock so soft you can score it with a fingernail. The buildings are the cliff and the cliff is the buildings.

[scrolly-section image="hero.jpg" alt="Medieval town of Sorano seen from the approach road, perched on pale tufa cliffs" caption="Sorano — tufa cliff town, Grosseto province"]
The approach by bike gives you an unusually long time to study it. The descent into the valley and the climb back up take perhaps forty minutes, and the town is visible for most of that time, doing nothing, requiring nothing.

---

Close up the rock is extraordinary. Hundreds of tomb niches cut into the cliff face — Etruscan graves, most of them open to the sky now, their contents long removed. The people who built this town chose to live surrounded by the evidence of their own mortality. This seems either very brave or very sensible.

---

The gate into the old town is fifteenth century and narrow enough that loaded bikes don't fit without turning sideways. Inside, the air is noticeably cooler and the alleys are steep, paved with the same pale tufa, worn smooth by centuries of feet.
[/scrolly-section]

We found a wall to lean the bikes against and sat looking south over the valley we had come from. The light was going amber. Below us, the road we had ridden was already in shadow.

[chapter-break image="photo-1.jpg" title="After Dark" number="II" alt="Narrow medieval alley in Sorano at dusk, pale stone walls glowing warm" /]

[pull-quote image="photo-1.jpg" alt="Stone alley in Sorano lit by a single lantern at night"]
A town built on rock, carved from rock, returning slowly to rock. Two thousand years of human effort and the cliff remains indifferent.
[/pull-quote]

[scrolly-section image="photo-2.jpg" alt="View south from the tufa cliff walls of Sorano at dusk" caption="Val di Fiora, from the old walls"]
One restaurant was open. The menu was four items. We had the pasta with wild boar and the pasta with truffles and a carafe of local wine that cost six euros and was excellent.

---

The owner sat at the next table watching a football match on his phone without headphones. Nobody minded. The town outside was completely quiet.
[/scrolly-section]

We were in bed before nine. Sorano at night is absolutely silent. It has been this quiet, in approximately this configuration, for a very long time.
  • Step 3: Verify shortcode counts match test S3 expectations
grep -c "scrolly-section" user/docs/demo/trips/italy-2026-demo/04.stories/01.sorano-rock-and-time/story.md
grep -c "chapter-break" user/docs/demo/trips/italy-2026-demo/04.stories/01.sorano-rock-and-time/story.md
grep -c "pull-quote image=" user/docs/demo/trips/italy-2026-demo/04.stories/01.sorano-rock-and-time/story.md

Expected: 2 scrolly-section tags (opening tags only), 1 chapter-break, 1 pull-quote with image.

  • Step 4: Commit
git -C user add -A
git -C user commit -m "feat(demo): add story 1 — Sorano: Rock and Time"

Task 4: Write Story 2 — Val d'Orcia at Dawn

Target: user/docs/demo/trips/italy-2026-demo/04.stories/02.val-dorcia-at-dawn/
Test coverage: STORY_GALLERY — needs snap-gallery × 2, chapter-break, text-only pull-quote

Files:

  • Create: user/docs/demo/trips/italy-2026-demo/04.stories/02.val-dorcia-at-dawn/story.md

  • Create: hero.jpg, photo-1.jpg, photo-2.jpg (same directory)

  • Step 1: Create story directory and download images

mkdir -p user/docs/demo/trips/italy-2026-demo/04.stories/02.val-dorcia-at-dawn
SDIR=user/docs/demo/trips/italy-2026-demo/04.stories/02.val-dorcia-at-dawn
curl -sL "https://picsum.photos/seed/demo-s2-hero/1600/1000" -o "$SDIR/hero.jpg"
curl -sL "https://picsum.photos/seed/demo-s2-1/1600/1000"   -o "$SDIR/photo-1.jpg"
curl -sL "https://picsum.photos/seed/demo-s2-2/1600/1000"   -o "$SDIR/photo-2.jpg"
  • Step 2: Write story.md

Write user/docs/demo/trips/italy-2026-demo/04.stories/02.val-dorcia-at-dawn/story.md:

---
title: "Val d'Orcia at Dawn"
date: '2026-09-05'
location_name: Val d'Orcia
location_country: Italy
lat: 43.078
lng: 11.676
hero_image: hero.jpg
hero_alt: Wide Tuscan valley at dawn, long cypress shadows across pale gravel road
published: true
---

We left before the heat arrived. The alarm was five-thirty and the sky outside the tent was still more grey than blue. The valley was invisible in the dark except as an absence — a vast silence below us where the shapes of hills ought to be. By six the light had changed. The Val d'Orcia is one of those landscapes that photographers wait years to shoot at this hour, and you can see why: the light arrives at an angle that makes everything look like something from a different century.

[snap-gallery images="hero.jpg,photo-1.jpg,photo-2.jpg" captions="Six in the morning: the valley belongs entirely to the light,The Cypress Road — every photograph of Tuscany was taken here or somewhere like it,A farmhouse that has been sitting on this hill for four hundred years" alts="Wide misty Tuscan valley at dawn with long shadows,Straight road lined by tall cypress trees in morning light,Stone farmhouse on a hilltop with rolling landscape behind" /]

The roads down here are white gravel — strade bianche — and the tyres make a particular sound on them that you don't get anywhere else. We rode for two hours without seeing a car. The only other people were two elderly men walking a dog in the opposite direction. They waved.

[chapter-break image="photo-1.jpg" title="The Hour Before Heat" alt="Cypress road vanishing into a hazy summer morning" /]

By nine the temperature had already shifted. The quality of the light changed — softer, more diffuse, the sky turning white at the edges. The windows of the farmhouses began to open. Dogs that had been invisible in the dark became visible on walls and in doorways, watching us with professional detachment.

[snap-gallery images="photo-2.jpg,hero.jpg" captions="The road changes from asphalt to gravel to packed earth and back again without warning,The valley floor at nine: the shadows have shortened, the colours have flattened" alts="Farmhouse detail with terracotta roof and single cypress tree,Tuscan valley road in mid-morning haze" /]

[pull-quote]
The best hours of a cycling day are the ones nobody else sees. Before the heat arrives, before the cafes open, before the traffic comes. Everything belongs to you then.
[/pull-quote]

We reached Pienza at eleven-thirty. The ice-cream queue was eight deep and entirely justified.
  • Step 3: Verify shortcode counts match test S2 expectations
grep -c "snap-gallery" user/docs/demo/trips/italy-2026-demo/04.stories/02.val-dorcia-at-dawn/story.md
grep -c "chapter-break" user/docs/demo/trips/italy-2026-demo/04.stories/02.val-dorcia-at-dawn/story.md
grep -c "pull-quote__inner--no-image\|^\[pull-quote\]" user/docs/demo/trips/italy-2026-demo/04.stories/02.val-dorcia-at-dawn/story.md

Simpler check — verify exactly 2 [snap-gallery tags and 1 [pull-quote] (no image=):

grep -c "\[snap-gallery" user/docs/demo/trips/italy-2026-demo/04.stories/02.val-dorcia-at-dawn/story.md
grep "\[pull-quote" user/docs/demo/trips/italy-2026-demo/04.stories/02.val-dorcia-at-dawn/story.md

Expected: 2 snap-gallery, and the pull-quote line has no image= attribute.

  • Step 4: Commit
git -C user add -A
git -C user commit -m "feat(demo): add story 2 — Val d'Orcia at Dawn"

Task 5: Write Story 3 — One Evening in Siena

Target: user/docs/demo/trips/italy-2026-demo/04.stories/03.one-evening-siena/
Primary shortcode: pull-quote with background image; also uses chapter-break and scrolly-section

Files:

  • Create: user/docs/demo/trips/italy-2026-demo/04.stories/03.one-evening-siena/story.md

  • Create: hero.jpg, photo-1.jpg (same directory)

  • Step 1: Create story directory and download images

mkdir -p user/docs/demo/trips/italy-2026-demo/04.stories/03.one-evening-siena
SDIR=user/docs/demo/trips/italy-2026-demo/04.stories/03.one-evening-siena
curl -sL "https://picsum.photos/seed/demo-s3-hero/1600/1000" -o "$SDIR/hero.jpg"
curl -sL "https://picsum.photos/seed/demo-s3-1/1600/1000"   -o "$SDIR/photo-1.jpg"
  • Step 2: Write story.md

Write user/docs/demo/trips/italy-2026-demo/04.stories/03.one-evening-siena/story.md:

---
title: 'One Evening in Siena'
date: '2026-09-05'
location_name: Siena
location_country: Italy
lat: 43.318
lng: 11.330
hero_image: hero.jpg
hero_alt: Piazza del Campo at dusk, terracotta paving fading from gold to shadow
published: true
---

[pull-quote image="hero.jpg" alt="Piazza del Campo seen from the upper rim at golden hour"]
Siena is not a city that tries to impress you. It has been here for a thousand years and intends to be here for a thousand more. You fit around it, not the other way.
[/pull-quote]

We rolled in at half past six, legs finished, panniers heavier than they started. The Campo appeared without warning at the end of a narrow street and we both stopped pedalling at exactly the same moment. That particular square does something to people. It is partly the shape — a shallow bowl, a scallop shell, the way it holds you — and partly the light at that hour, which turns the terracotta pavement the colour of old copper.

[chapter-break image="photo-1.jpg" title="The Campo" number="I" alt="Detail of Siena's herringbone brick pavement catching the last light" /]

[scrolly-section image="hero.jpg" alt="Piazza del Campo filling with people as evening comes" caption="Campo, 19:00 — the square fills from the edges inward"]
The locals arrive first. They know which spot faces west and which benches stay in the shade longest. Then the tourists, then the pigeons, then the long shadows.

---

A busker with an accordion near the Fonte Gaia. A group of students lying on the slope reading. Three children running in a circle for reasons nobody questioned.

---

We sat on the pavement with our backs against the warm brickwork of the Palazzo Pubblico and did not move for forty minutes. The relief of sitting still after eight hours on a bike is a specific physical sensation. It travels upward from your legs and settles somewhere just behind the sternum.
[/scrolly-section]

We found a place for dinner three streets away, down a flight of steps with no sign outside. The pasta was handmade, the wine was local, the bill was reasonable. We were in bed by ten. Tomorrow: Florence.
  • Step 3: Commit
git -C user add -A
git -C user commit -m "feat(demo): add story 3 — One Evening in Siena"

Task 6: Write Story 4 — Florence Without a Map

Target: user/docs/demo/trips/italy-2026-demo/04.stories/04.florence-without-a-map/
Primary shortcode: chapter-break as structural divider; also uses snap-gallery, pull-quote (text-only), scrolly-section

Files:

  • Create: user/docs/demo/trips/italy-2026-demo/04.stories/04.florence-without-a-map/story.md

  • Create: hero.jpg, photo-1.jpg (same directory)

  • Step 1: Create story directory and download images

mkdir -p user/docs/demo/trips/italy-2026-demo/04.stories/04.florence-without-a-map
SDIR=user/docs/demo/trips/italy-2026-demo/04.stories/04.florence-without-a-map
curl -sL "https://picsum.photos/seed/demo-s4-hero/1600/1000" -o "$SDIR/hero.jpg"
curl -sL "https://picsum.photos/seed/demo-s4-1/1600/1000"   -o "$SDIR/photo-1.jpg"
  • Step 2: Write story.md

Write user/docs/demo/trips/italy-2026-demo/04.stories/04.florence-without-a-map/story.md:

---
title: 'Florence Without a Map'
date: '2026-09-07'
location_name: Florence
location_country: Italy
lat: 43.769
lng: 11.255
hero_image: hero.jpg
hero_alt: Arno river at midday with Ponte Vecchio, ochre buildings reflected in still water
published: true
---

No route today. No GPS, no distance target, no reason to be anywhere by any particular time. After six days of forward motion this felt almost wrong — the instinct to check the elevation profile arriving at nothing. We put the bikes in the hotel basement and walked out into Florence on foot.

[chapter-break image="hero.jpg" title="Day Seven" number="VII" alt="Arno river and Ponte Vecchio from Ponte Santa Trinita at midday" /]

[snap-gallery images="hero.jpg,photo-1.jpg" captions="The Arno at noon — greener than expected, the bridges older than you remember,Via dei Servi: washing lines, shutters, a cat on a warm stone ledge that had been warm since morning" alts="Arno river with Ponte Vecchio reflected in still water at midday,Narrow Florence street with laundry strung between buildings" /]

[pull-quote]
Cycling makes you earn every city you arrive at. Florence, we got for free. It felt like a gift and a debt simultaneously.
[/pull-quote]

[scrolly-section image="photo-1.jpg" alt="Narrow Oltrarno street in afternoon light" caption="Oltrarno, 14:00"]
The Uffizi had a queue that stretched around two corners and disappeared into a side street. We looked at it for a moment and went to find coffee instead. This felt correct.

---

A covered market in the Oltrarno that nobody had told us about. A man selling leather goods from a table he clearly reassembled each morning from identical components. A small dog sleeping under a fruit stall in a precisely calculated patch of shade.

---

We crossed the Ponte Vecchio at two in the afternoon, which is exactly the wrong time to cross the Ponte Vecchio, and it was still worth it. The light off the Arno at that hour is genuinely extraordinary and all the photographs in the world do not prepare you for it.
[/scrolly-section]

Dinner near the apartment, early. Feet sore in a different way from legs sore — a smaller, more concentrated complaint. Tomorrow: the last day. The coast road home.
  • Step 3: Commit
git -C user add -A
git -C user commit -m "feat(demo): add story 4 — Florence Without a Map"

Task 7: Write Journal Entries — Days 14 (entries 16)

Target: user/docs/demo/trips/italy-2026-demo/dailies/

Each entry directory name: <slug>.entry/
Each entry contains: entry.md + numbered images 01.jpg, 02.jpg, …

  • Step 1: Entry 1 — Setting Off from Campiglia (2 photos)
EDIR=user/docs/demo/trips/italy-2026-demo/dailies/2026-09-01-0700-setting-off-from-campiglia.entry
mkdir -p "$EDIR"
curl -sL "https://picsum.photos/seed/demo-d1-1/1200/800" -o "$EDIR/01.jpg"
curl -sL "https://picsum.photos/seed/demo-d1-2/1200/800" -o "$EDIR/02.jpg"

Write $EDIR/entry.md:

---
title: 'Setting Off from Campiglia'
date: '2026-09-01 07:00'
template: entry
published: true
hero_image: ''
lat: 43.024
lng: 10.603
location_city: Campiglia Marittima
location_country: Italy
weather_temp_c: 27
weather_desc: Sunny
---

Seven in the morning and the coast road is still cool. We loaded the bikes in the car park below the old town, the panniers heavier than they should be and the weather forecast saying nine consecutive days of sun. The route heads south first — down into the Maremma, then east, then a long loop back. Eight days. Nobody goes this way in September except cyclists and people who have got lost.
  • Step 2: Entry 2 — Maremma in Full Sun (3 photos)
EDIR=user/docs/demo/trips/italy-2026-demo/dailies/2026-09-02-1130-maremma-in-full-sun.entry
mkdir -p "$EDIR"
curl -sL "https://picsum.photos/seed/demo-d2a-1/1200/800" -o "$EDIR/01.jpg"
curl -sL "https://picsum.photos/seed/demo-d2a-2/1200/800" -o "$EDIR/02.jpg"
curl -sL "https://picsum.photos/seed/demo-d2a-3/1200/800" -o "$EDIR/03.jpg"

Write $EDIR/entry.md:

---
title: 'Maremma in Full Sun'
date: '2026-09-02 11:30'
template: entry
published: true
hero_image: ''
lat: 42.612
lng: 11.171
location_city: Maremma
location_country: Italy
weather_temp_c: 29
weather_desc: Sunny
---

Eleven-thirty and already thirty degrees. The Maremma is agricultural land and scrubland and very little else, and in September it has the quality of a landscape that has given up trying. The road is straight, the sun is direct, the shadows are almost vertical. We stopped at a petrol station and drank two cans of something cold each. The man at the counter looked at us like people who had made a series of questionable decisions.
  • Step 3: Entry 3 — The Lagoon at Dusk (3 photos)
EDIR=user/docs/demo/trips/italy-2026-demo/dailies/2026-09-02-1900-the-lagoon-at-dusk.entry
mkdir -p "$EDIR"
curl -sL "https://picsum.photos/seed/demo-d2b-1/1200/800" -o "$EDIR/01.jpg"
curl -sL "https://picsum.photos/seed/demo-d2b-2/1200/800" -o "$EDIR/02.jpg"
curl -sL "https://picsum.photos/seed/demo-d2b-3/1200/800" -o "$EDIR/03.jpg"

Write $EDIR/entry.md:

---
title: 'The Lagoon at Dusk'
date: '2026-09-02 19:00'
template: entry
published: true
hero_image: ''
lat: 42.442
lng: 11.218
location_city: Orbetello
location_country: Italy
weather_temp_c: 24
weather_desc: Partly cloudy
---

Orbetello sits on a causeway between two lagoons and at dusk the light does something remarkable to the water. Pink flamingos — real ones, not ornamental — were standing in the shallows on the western side, perfectly still. We ate at a table outside overlooking the eastern lagoon. The sky turned orange and then purple and then a deep blue that was almost indistinguishable from the water. The wine was cold and the pasta had clams.
  • Step 4: Entry 4 — Orbetello Morning (2 photos)
EDIR=user/docs/demo/trips/italy-2026-demo/dailies/2026-09-03-0800-orbetello-morning.entry
mkdir -p "$EDIR"
curl -sL "https://picsum.photos/seed/demo-d3a-1/1200/800" -o "$EDIR/01.jpg"
curl -sL "https://picsum.photos/seed/demo-d3a-2/1200/800" -o "$EDIR/02.jpg"

Write $EDIR/entry.md:

---
title: 'Orbetello Morning'
date: '2026-09-03 08:00'
template: entry
published: true
hero_image: ''
lat: 42.442
lng: 11.217
location_city: Orbetello
location_country: Italy
weather_temp_c: 22
weather_desc: Sunny
---

The lagoon at eight in the morning is a different thing from the lagoon at eight in the evening. Flat, silver, nearly silent. A single fisherman in a small boat about two hundred metres out, not appearing to fish. We left before the town had properly woken up, heading northeast on roads that climbed immediately and steeply into a landscape of oak and limestone that felt nothing like the coast we had left behind twenty minutes before.
  • Step 5: Entry 5 — Tufa and Towers (2 photos)
EDIR=user/docs/demo/trips/italy-2026-demo/dailies/2026-09-03-1700-tufa-and-towers.entry
mkdir -p "$EDIR"
curl -sL "https://picsum.photos/seed/demo-d3b-1/1200/800" -o "$EDIR/01.jpg"
curl -sL "https://picsum.photos/seed/demo-d3b-2/1200/800" -o "$EDIR/02.jpg"

Write $EDIR/entry.md:

---
title: 'Tufa and Towers'
date: '2026-09-03 17:00'
template: entry
published: true
hero_image: ''
lat: 42.683
lng: 11.715
location_city: Sorano
location_country: Italy
weather_temp_c: 26
weather_desc: Sunny
---

Sorano appears on the horizon an hour before you reach it: a cluster of towers and walls on a pale cliff, floating above the valley. The closer you get the stranger it becomes. The town is not built on rock — the town is rock, volcanic tufa carved and inhabited over two thousand years. The Etruscans started it. Everyone since has just kept adding floors. We are staying the night and it already feels like somewhere that requires more time than we have.
  • Step 6: Entry 6 — The Long Climb North (4 photos)
EDIR=user/docs/demo/trips/italy-2026-demo/dailies/2026-09-04-1500-the-long-climb-north.entry
mkdir -p "$EDIR"
curl -sL "https://picsum.photos/seed/demo-d4-1/1200/800" -o "$EDIR/01.jpg"
curl -sL "https://picsum.photos/seed/demo-d4-2/1200/800" -o "$EDIR/02.jpg"
curl -sL "https://picsum.photos/seed/demo-d4-3/1200/800" -o "$EDIR/03.jpg"
curl -sL "https://picsum.photos/seed/demo-d4-4/1200/800" -o "$EDIR/04.jpg"

Write $EDIR/entry.md:

---
title: 'The Long Climb North'
date: '2026-09-04 15:00'
template: entry
published: true
hero_image: ''
lat: 43.077
lng: 11.678
location_city: "Val d'Orcia"
location_country: Italy
weather_temp_c: 23
weather_desc: Partly cloudy
---

Today was the hardest day. The route from Sorano to the Val d'Orcia crosses the eastern slope of Monte Amiata, which sounds manageable on a map and is not manageable at all. By noon we had climbed eleven hundred metres. By two we were somewhere above Seggiano in thin cloud, the views long gone, legs complaining in a language that had become very specific. Then the cloud lifted and the Val d'Orcia was simply there below us: pale roads, dark cypress, the whole thing exactly as advertised. Sometimes the landscapes that have been photographed to death are still worth arriving at.
  • Step 7: Commit entries 16
git -C user add -A
git -C user commit -m "feat(demo): add journal entries days 14 with photos"

Task 8: Write Journal Entries — Days 58 (entries 712)

  • Step 1: Entry 7 — Before the Heat Arrives (2 photos)
EDIR=user/docs/demo/trips/italy-2026-demo/dailies/2026-09-05-0830-before-the-heat-arrives.entry
mkdir -p "$EDIR"
curl -sL "https://picsum.photos/seed/demo-d5a-1/1200/800" -o "$EDIR/01.jpg"
curl -sL "https://picsum.photos/seed/demo-d5a-2/1200/800" -o "$EDIR/02.jpg"

Write $EDIR/entry.md:

---
title: 'Before the Heat Arrives'
date: '2026-09-05 08:30'
template: entry
published: true
hero_image: ''
lat: 43.078
lng: 11.676
location_city: Pienza
location_country: Italy
weather_temp_c: 21
weather_desc: Sunny
---

Six o'clock and the valley below Pienza is still in shadow. We left camp early on purpose — the route to Siena is long and September sun waits for no one. On the strade bianche the tyres make a sound like distant applause. No cars for the first two hours. Just the road and the light doing things to the cypress trees that would be embarrassing to describe in any other context.
  • Step 2: Entry 8 — Into Siena (3 photos)
EDIR=user/docs/demo/trips/italy-2026-demo/dailies/2026-09-05-1800-into-siena.entry
mkdir -p "$EDIR"
curl -sL "https://picsum.photos/seed/demo-d5b-1/1200/800" -o "$EDIR/01.jpg"
curl -sL "https://picsum.photos/seed/demo-d5b-2/1200/800" -o "$EDIR/02.jpg"
curl -sL "https://picsum.photos/seed/demo-d5b-3/1200/800" -o "$EDIR/03.jpg"

Write $EDIR/entry.md:

---
title: 'Into Siena'
date: '2026-09-05 18:00'
template: entry
published: true
hero_image: ''
lat: 43.318
lng: 11.335
location_city: Siena
location_country: Italy
weather_temp_c: 25
weather_desc: Sunny
---

The approach to Siena by bike is through streets that get progressively older and steeper until suddenly the Campo is there. We had both seen it in photographs and the photographs are accurate in every way except one: they do not tell you how the square smells — stone and frying onions and the particular warm stillness of a Sienese summer evening. We sat on the pavement with our backs against the Palazzo Pubblico for forty minutes and did not want to be anywhere else.
  • Step 3: Entry 9 — Florence by Nightfall (3 photos)
EDIR=user/docs/demo/trips/italy-2026-demo/dailies/2026-09-06-2000-florence-by-nightfall.entry
mkdir -p "$EDIR"
curl -sL "https://picsum.photos/seed/demo-d6-1/1200/800" -o "$EDIR/01.jpg"
curl -sL "https://picsum.photos/seed/demo-d6-2/1200/800" -o "$EDIR/02.jpg"
curl -sL "https://picsum.photos/seed/demo-d6-3/1200/800" -o "$EDIR/03.jpg"

Write $EDIR/entry.md:

---
title: 'Florence by Nightfall'
date: '2026-09-06 20:00'
template: entry
published: true
hero_image: ''
lat: 43.767
lng: 11.253
location_city: Florence
location_country: Italy
weather_temp_c: 21
weather_desc: Cloudy
---

A long day. Siena to Florence is ninety kilometres and involves two significant climbs before you reach the Chianti hills, after which it becomes more manageable but you have already used the legs you needed. We came in from the south as the light was going, the city materialising from a distance as a density of rooftops and towers. The Arno appeared between buildings and we crossed it and then we were in, which is always a slightly surprising moment after a long day.
  • Step 4: Entry 10 — One Rest Day (2 photos)
EDIR=user/docs/demo/trips/italy-2026-demo/dailies/2026-09-07-1400-one-rest-day.entry
mkdir -p "$EDIR"
curl -sL "https://picsum.photos/seed/demo-d7-1/1200/800" -o "$EDIR/01.jpg"
curl -sL "https://picsum.photos/seed/demo-d7-2/1200/800" -o "$EDIR/02.jpg"

Write $EDIR/entry.md:

---
title: 'One Rest Day'
date: '2026-09-07 14:00'
template: entry
published: true
hero_image: ''
lat: 43.769
lng: 11.255
location_city: Florence
location_country: Italy
weather_temp_c: 22
weather_desc: Partly cloudy
---

The bikes stayed in the basement. We walked instead, which after six days of cycling felt simultaneously easier and harder — easier on the legs, harder on the feet, which are used to being passive. Florence does not require a plan. Every street contains something. We crossed the Arno four times from different bridges, each one giving a slightly different version of the same view, all of them good.
  • Step 5: Entry 11 — Dawn on the Cecina Coast (1 photo)
EDIR=user/docs/demo/trips/italy-2026-demo/dailies/2026-09-08-0730-dawn-on-the-cecina-coast.entry
mkdir -p "$EDIR"
curl -sL "https://picsum.photos/seed/demo-d8a-1/1200/800" -o "$EDIR/01.jpg"

Write $EDIR/entry.md:

---
title: 'Dawn on the Cecina Coast'
date: '2026-09-08 07:30'
template: entry
published: true
hero_image: ''
lat: 43.553
lng: 10.313
location_city: Cecina
location_country: Italy
weather_temp_c: 20
weather_desc: Sunny
---

The last day starts on the coast road south of Cecina, the sea visible between the pine trees. We have been inland for most of the week and the smell of salt water is a surprise. The road is flat, which after eight days of Tuscan hills feels almost suspicious. We rode in silence for the first hour. There was nothing that needed saying.
  • Step 6: Entry 12 — Home (2 photos)
EDIR=user/docs/demo/trips/italy-2026-demo/dailies/2026-09-08-1630-home.entry
mkdir -p "$EDIR"
curl -sL "https://picsum.photos/seed/demo-d8b-1/1200/800" -o "$EDIR/01.jpg"
curl -sL "https://picsum.photos/seed/demo-d8b-2/1200/800" -o "$EDIR/02.jpg"

Write $EDIR/entry.md:

---
title: 'Home'
date: '2026-09-08 16:30'
template: entry
published: true
hero_image: ''
lat: 43.017
lng: 10.587
location_city: Campiglia Marittima
location_country: Italy
weather_temp_c: 26
weather_desc: Sunny
---

The old town of Campiglia was visible on its hill for the last twenty kilometres, appearing and disappearing between the trees the way it had appeared on the horizon eight days ago when we left. The loop is complete: same car park, same view across the coast, different legs. The bikes went back in the car and we sat on a wall and counted the countries and the kilometres and the pasta dishes. Eight days, one loop, Tuscany in September. It was exactly what it was supposed to be.
  • Step 7: Verify 12 entry directories exist
ls user/docs/demo/trips/italy-2026-demo/dailies/ | grep -c "\.entry$"

Expected: 12

  • Step 8: Commit entries 712
git -C user add -A
git -C user commit -m "feat(demo): add journal entries days 58 with photos"

Task 9: Verify with demo-load and run tests

Prerequisite: Docker dev server running at http://localhost:8081

  • Step 1: Reset any existing demo content
make demo-reset
  • Step 2: Load demo content
make demo-load

Expected: no errors; ends with Cache cleared.

  • Step 3: Smoke check in browser

Open http://localhost:8081/trips/italy-2026-demo — verify:

  • Trip page shows "Tuscany 2026"
  • Filter bar shows All / Journal / Stories
  • Journal entries visible (should show most recent first)
  • Stories tab shows 4 story cards

Open one entry (e.g. Entry 6 with 4 photos) and verify:

  • Hero image renders (01.jpg)
  • Gallery grid shows all 4 photos
  • Lightbox opens on click

Open http://localhost:8081/trips/italy-2026-demo/stories/sorano-rock-and-time and verify:

  • scrolly sections render
  • chapter-break renders
  • pull-quote with background image renders

Open http://localhost:8081/trips/italy-2026-demo/map and verify:

  • All 7 GPX routes render on the map

  • Entry markers appear at the correct coordinates

  • Step 4: Run the full test suite

npm run test:ui

Expected: all tests pass. Key tests to watch:

  • S1: stories listing shows ≥ 3 cards → passes (4 stories)
  • S2: gallery story has 2 snap-galleries, chapter-break, text-only pull-quote
  • S3: scrolly story has 2 scrolly-sections, chapter-break, pull-quote with image
  • S4: no JS errors on scrolly story
  • S5: back button navigates to stories listing
  • S6/S7: demo story hero renders, back-pill present

If a test fails, diagnose before moving on — do not proceed to final commit with failing tests.

  • Step 5: Final commit
git -C user add -A
git -C user commit -m "chore(demo): verify demo content complete — all tests passing"

Self-Review Checklist

  • Spec § 1 Cleanup → Task 1
  • Spec § 2 GPX rename (4 files) → Task 1, Step 23
  • Spec § 3 Journal entries (12) → Tasks 78
  • Spec § 4 Stories (4) → Tasks 36; shortcode counts designed to match S2/S3 test assertions
  • Spec § 5 Makefile — existing cp -r commands already handle images; no Makefile changes needed
  • Spec § 6 trip.md update → Task 1, Step 4
  • Spec § 7 What is NOT changing — italy-2025 pages untouched, japan-korea-2026 pages untouched ✓
  • stories.spec.js slug update → Task 2 (covers both constants and the hardcoded S7 URL)
  • dailies.md index page → Task 1, Step 5 (needed for Grav to render the dailies listing after demo-reset)
  • No placeholder text in any step
  • All 4 shortcode types appear across 4 stories, with STORY_GALLERY and STORY_SCROLLY matching test assertion counts