Files
intotheeast-com/docs/working/plans/2026-06-19-tuscany-demo-stories.md
T

14 KiB
Raw Blame History

Tuscany Demo Stories 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: Add three Italy 2025 Tuscany demo stories that showcase distinct story-mode composition patterns.

Architecture: Three story.md files in user/docs/demo/trips/italy-2025/04.stories/, committed to the user repo. One Makefile line added to demo-load to copy the folder into pages, committed to the main repo. No image files — shortcode image params reference filenames that won't resolve without real photos, consistent with the existing Japan demo story.

Tech Stack: Grav CMS page frontmatter (YAML), Markdown prose, story-blocks shortcodes (chapter-break, scrolly-section, pull-quote, snap-gallery), Makefile.

Global Constraints

  • Story pages live at user/docs/demo/trips/italy-2025/04.stories/<n>.<slug>/story.md (note: user/ is a separate git repo — all story commits use git -C user ...)
  • Shortcode syntax: [chapter-break title="..." number="..." image="..." alt="..." /], [scrolly-section image="..." alt="..." caption="..."]...[/scrolly-section], [pull-quote image="..."]...[/pull-quote] (image param optional), [snap-gallery images="a.jpg,b.jpg" captions="Cap 1,Cap 2" alts="Alt 1,Alt 2" /]
  • ScrollySection steps separated by --- on its own line inside the shortcode tags
  • All frontmatter fields required: title, date, location_name, location_country, lat, lng, hero_image, hero_alt, published: true
  • end_date optional (Story 2 only)
  • Makefile changes go in the main repo (git add Makefile && git commit ... — no -C user)
  • Dev server: http://localhost:8081, Docker container: intotheeast_grav

Task 1: Three story.md files

Files:

  • Create: user/docs/demo/trips/italy-2025/04.stories/01.val-dorcia-dawn/story.md
  • Create: user/docs/demo/trips/italy-2025/04.stories/02.long-climb-montalcino/story.md
  • Create: user/docs/demo/trips/italy-2025/04.stories/03.one-evening-siena/story.md

Interfaces:

  • Produces: three story pages loadable by make demo-load into user/pages/01.trips/italy-2025/04.stories/

  • Consumed by: Task 2 (Makefile verification)

  • Create the demo stories directory

    mkdir -p user/docs/demo/trips/italy-2025/04.stories/01.val-dorcia-dawn
    mkdir -p user/docs/demo/trips/italy-2025/04.stories/02.long-climb-montalcino
    mkdir -p user/docs/demo/trips/italy-2025/04.stories/03.one-evening-siena
    
  • Create Story 1: 01.val-dorcia-dawn/story.md

    Pattern: gallery-led. Demonstrates two snap-galleries, chapter-break as scene divider, text-only pull-quote (no image param).

    ---
    title: The Val d'Orcia at Dawn
    date: 2025-09-05
    location_name: Val d'Orcia
    location_country: Italy
    lat: 43.078
    lng: 11.676
    hero_image: hero.jpg
    hero_alt: Cypress-lined dirt road at first light, Tuscany
    published: true
    ---
    We left camp before the heat arrived. At six in the morning the Val d'Orcia belongs entirely to the light — long shadows, pale gold, not a car on the white roads. The kind of silence that has texture.
    
    [snap-gallery images="dawn-wide.jpg,rolling-hills.jpg,cypress-allee.jpg,dirt-road.jpg" captions="First light on the valley floor,The hills fold endlessly east,The cypress road — every photo you have ever seen of Tuscany,Dust rising behind us on the gravel" alts="Wide valley at dawn with golden light,Rolling green hills under morning sky,Long avenue of cypress trees,White gravel road with dust cloud" /]
    
    We stopped twice before nine. Once for a puncture, once because the view demanded it.
    
    [chapter-break image="heat-haze.jpg" title="The Hour Before Heat" alt="Hazy hillside shimmering in early morning warmth" /]
    
    By ten the temperature had shifted. The colours changed too — softer, more diffuse, the sky turning white at the edges. We dropped into the lower valley and the road surface changed from gravel to packed earth, then back again.
    
    [snap-gallery images="gravel-detail.jpg,wheel-shadow.jpg,water-bottle.jpg,road-shadow.jpg" captions="The texture of Tuscan gravel — coarser than it looks,Long shadow at the day's first steep pitch,Half a litre left and forty kilometres to go,The road ahead disappears into the heat" alts="Close-up of pale gravel surface,Bicycle wheel casting shadow on road,Half-empty water bottle in cage,Road vanishing into bright haze" /]
    
    [pull-quote]
    The best hours of a cycling day are the ones nobody sees. Four in the morning to ten. Then it belongs to the sun.
    [/pull-quote]
    
    We made Pienza by noon. It was already thirty degrees and the ice cream queue was six deep.
    
  • Create Story 2: 02.long-climb-montalcino/story.md

    Pattern: scrollytelling-led. Demonstrates two scrolly-sections with different step counts (3 vs. 5), pull-quote with image, chapter-break with number.

    ---
    title: The Long Climb to Montalcino
    date: 2025-09-05
    end_date: 2025-09-06
    location_name: Montalcino
    location_country: Italy
    lat: 43.058
    lng: 11.489
    hero_image: hero.jpg
    hero_alt: Hairpin road climbing through olive groves towards a hilltop town
    published: true
    ---
    The profile showed fourteen kilometres at an average of six percent. In practice it was steeper at the bottom and gentler at the top, which is the worst possible arrangement. We started climbing at two in the afternoon, which was also the worst possible decision.
    
    [scrolly-section image="climb-road.jpg" alt="Empty road rising steeply through olive groves" caption="SP55 — 14km, 840m elevation gain"]
    The first kilometre is the most honest. You find out immediately whether your legs have anything to say.
    
    ---
    
    By the halfway point the olive groves had given way to scrub oak and the road had narrowed to a single lane. No cars had passed in forty minutes. The silence was absolute except for breathing.
    
    ---
    
    Then, at the last bend before the top, the town appeared. Just the outline of it — a tower, a wall, rooftops. It was enough.
    [/scrolly-section]
    
    [chapter-break image="town-gate.jpg" title="Montalcino" number="II" alt="Medieval town gate with stone archway" /]
    
    [pull-quote image="vineyard.jpg" alt="Rows of Brunello vines descending from hilltop town"]
    From the top you could see the whole valley we had spent two days riding through. It looked completely flat from up here.
    [/pull-quote]
    
    We found a bar in the main piazza. The owner brought two glasses of water without being asked. Then two more. Then a small plate of bread and oil that nobody ordered. We sat there for an hour.
    
    [scrolly-section image="piazza.jpg" alt="Shaded medieval piazza with stone buildings" caption="Piazza del Popolo, Montalcino"]
    The piazza at five in the afternoon is a different place from the piazza at noon. People have returned from wherever they go during the heat.
    
    ---
    
    A wine shop with barrels in the window and a handwritten list on a chalkboard. We looked at it for a long time and bought nothing. The prices were very reasonable and this felt suspicious.
    
    ---
    
    A cat on a warm stone wall, watching traffic that did not exist. It had clearly been watching this traffic for years.
    
    ---
    
    The fortress walls turn amber just before sunset. You could photograph this from a hundred different angles and it would look the same in all of them: very good.
    
    ---
    
    The descent back to the valley takes twenty minutes. The climb took two and a half hours. This ratio never stops feeling wrong.
    [/scrolly-section]
    
    We found the agriturismo by following a handwritten sign nailed to a cypress tree. It was exactly what it promised to be.
    
  • Create Story 3: 03.one-evening-siena/story.md

    Pattern: mood/fragment piece. Demonstrates pull-quote as opening element, 2-step scrolly-section (minimum), snap-gallery as mid-story element, pull-quote with image as closing element.

    ---
    title: One Evening in Siena
    date: 2025-09-05
    location_name: Siena
    location_country: Italy
    lat: 43.318
    lng: 11.330
    hero_image: hero.jpg
    hero_alt: The Piazza del Campo at dusk, terracotta rooftops fading to blue
    published: true
    ---
    [pull-quote]
    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.
    [/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.
    
    [scrolly-section image="campo.jpg" alt="Piazza del Campo seen from the upper rim, sloping shell-shaped square"]
    The square fills from the edges inward as evening comes. First the locals — people who have been here before and know which bench faces west. Then the tourists, then the pigeons, then the shadows.
    
    ---
    
    A busker with a cello at the top of the slope. A couple arguing quietly in a language I couldn't place. Three children running in a circle for reasons nobody questioned. The ordinary business of a city at the end of a summer day.
    [/scrolly-section]
    
    [snap-gallery images="campo-dusk.jpg,doorway.jpg,gelato.jpg" captions="The Campo at the moment the light goes warm,A doorway on Via di Città — every doorway in Siena looks like this,The mandatory stop: stracciatella, obviously" alts="Wide shot of Campo at golden hour,Ornate stone doorway with iron lantern,Close-up of gelato cone with city behind" /]
    
    We found a place to eat down three flights of stairs in a basement that appeared to have no ventilation and no menu. It was perfect. The relief of sitting down after eight hours on a bike is a specific physical sensation that is difficult to describe to anyone who has not experienced it.
    
    [pull-quote image="sunset.jpg" alt="Sunset view over Siena rooftops from high vantage point"]
    Cycling makes you earn every place you arrive at. Siena earned.
    [/pull-quote]
    
  • Verify shortcode syntax in all three files

    Check that every shortcode tag opens and closes correctly:

    grep -n "\[chapter-break\|\[scrolly-section\|\[/scrolly-section\]\|\[pull-quote\|\[/pull-quote\]\|\[snap-gallery" \
      user/docs/demo/trips/italy-2025/04.stories/01.val-dorcia-dawn/story.md \
      user/docs/demo/trips/italy-2025/04.stories/02.long-climb-montalcino/story.md \
      user/docs/demo/trips/italy-2025/04.stories/03.one-evening-siena/story.md
    

    Expected: every [scrolly-section has a matching [/scrolly-section], every [pull-quote has a matching [/pull-quote].

  • Commit to user repo

    git -C user add docs/demo/trips/italy-2025/04.stories/
    git -C user commit -m "docs: add three Tuscany demo stories (gallery-led, scrollytelling-led, mood-fragment)"
    

Task 2: Makefile update + end-to-end verification

Files:

  • Modify: Makefile (main repo — no -C user)

Interfaces:

  • Consumes: user/docs/demo/trips/italy-2025/04.stories/ from Task 1

  • Produces: make demo-load copies all three stories into pages; stories listing shows 3 cards; each story page renders shortcode HTML

  • Add the stories copy line to demo-load

    In Makefile, find this line:

    	cp user/docs/demo/trips/italy-2025/stories.md user/pages/01.trips/italy-2025/04.stories/stories.md 2>/dev/null || true
    

    Add the following line immediately after it:

    	cp -r user/docs/demo/trips/italy-2025/04.stories/. user/pages/01.trips/italy-2025/04.stories/ 2>/dev/null || true
    

    Note: use 04.stories/. (trailing slash-dot) to copy the contents of the folder into the existing 04.stories/ directory (which already contains stories.md), rather than creating a nested 04.stories/04.stories/ structure.

  • Run make demo-load and clear cache

    make demo-load
    

    Expected output ends with Grav cache cleared.

  • Verify stories listing shows 3 cards

    curl -s http://localhost:8081/trips/italy-2025/stories | grep -c 'story-card'
    

    Expected: 3 (one card per story).

  • Verify Story 1 renders both snap-galleries and text-only pull-quote

    curl -s http://localhost:8081/trips/italy-2025/stories/val-dorcia-dawn | grep -c 'pgallery\|pull-quote'
    

    Expected: at least 3 (2 pgallery divs + 1 pull-quote).

    Also verify the text-only pull-quote (no background image div):

    curl -s http://localhost:8081/trips/italy-2025/stories/val-dorcia-dawn | grep 'pull-quote__inner--no-image'
    

    Expected: one match (the text-only pull-quote variant).

  • Verify Story 2 renders two scrolly-sections

    curl -s http://localhost:8081/trips/italy-2025/stories/long-climb-montalcino | grep -c 'class="scrolly"'
    

    Expected: 2 (two scrolly-section blocks).

    Also verify pull-quote with image (should NOT have --no-image class):

    curl -s http://localhost:8081/trips/italy-2025/stories/long-climb-montalcino | grep 'pull-quote__bg'
    

    Expected: one match (the background image div for the pull-quote).

  • Verify Story 3 renders pull-quote as opener and closer

    curl -s http://localhost:8081/trips/italy-2025/stories/one-evening-siena | grep -c 'pull-quote'
    

    Expected: at least 4 (two pull-quote elements × ~2 class references each).

    Verify the mid-story snap-gallery:

    curl -s http://localhost:8081/trips/italy-2025/stories/one-evening-siena | grep -c 'pgallery'
    

    Expected: at least 1.

  • Run make demo-reset and verify cleanup

    make demo-reset
    

    Verify Italy stories are gone:

    ls user/pages/01.trips/italy-2025/ 2>/dev/null || echo "italy-2025 removed"
    

    Expected: italy-2025 removed (the entire italy-2025 folder is removed by demo-reset).

  • Commit Makefile to main repo

    git add Makefile
    git commit -m "build: add Italy 2025 stories folder to demo-load target"