# Frontend Polish 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 (`- [x]`) syntax for tracking. **Status:** ✅ Complete — implemented 2026-06-24 **Spec:** `docs/working/specs/2026-06-24-frontend-polish-design.md` **Goal:** Visual polish across the five primary page templates: pill grammar, stats field-notes style, header identity, emoji replacement, trip card cover images, story progress bar, and story opening transition. **Architecture:** Tasks 1–2 are pure CSS (style.css only). Task 3 touches one partial (emoji). Task 4 adds a blueprint field and updates one template. Tasks 5–6 each add CSS + a small Twig block to story.html.twig. **Already done (this session):** - `entry.html.twig` unified with feed partial — hero removed, PhotoSwipe replaces broken lightbox - Dead CSS from old entry layout stripped from `style.css` --- ## Global Constraints - All changes in `user/` — commit with `git -C user`, not main-repo git - All new CSS uses token variables only — no hardcoded hex values - Changes must degrade gracefully when optional data (cover image, location) is absent - `prefers-reduced-motion` must be respected for any animations in Tasks 5–6 - Clear Grav cache after each template change: `make remote-cache-clear` or via Admin --- ## Task 1: Pure CSS — Pill grammar + Stats style + Header identity **Files:** - Modify: `user/themes/intotheeast/css/style.css` **Interfaces:** - Produces: visual changes to trip filter buttons, stats blocks, and site header across all pages - [x] **Step 1: Pill grammar — change filter/sort buttons to rounded-rect** Find `.trip-filter-btn,` selector block: ```css .trip-filter-btn, .trip-stats-btn { ... border-radius: var(--radius-full); ... } ``` Change only `border-radius` to `var(--radius-sm)`. Leave all other properties unchanged. - [x] **Step 2: Stats — remove box, add left rule** Find `.stat-block` rule: ```css .stat-block { background: var(--color-canvas); border: 1px solid var(--color-border); border-radius: var(--radius-md); padding: var(--space-6) var(--space-5); text-align: center; box-shadow: var(--shadow-sm); } ``` Replace with: ```css .stat-block { border-left: 2px solid var(--color-accent); padding: var(--space-2) 0 var(--space-2) var(--space-4); text-align: left; } ``` - [x] **Step 3: Stats — change number color from accent to ink** Find `.stat-value` rule. It contains `color: var(--color-accent)`. Change to `color: var(--color-ink)`. Leave all other properties unchanged. - [x] **Step 4: Header — widen site title tracking and size** Find `.site-title` rule: ```css .site-title { font-family: var(--font-display); font-size: var(--text-lg); font-weight: 400; letter-spacing: -0.01em; ... } ``` Change: - `font-size: var(--text-lg)` → `font-size: var(--text-xl)` - `letter-spacing: -0.01em` → `letter-spacing: 0.06em` - [x] **Step 5: Header — thicken and gradient the accent stripe** Find `.site-header` rule. It contains `border-top: 3px solid var(--color-accent)`. Change to: ```css border-top: 4px solid transparent; border-image: linear-gradient(90deg, var(--color-accent), var(--color-accent-hover)) 1; ``` - [x] **Step 6: Visual smoke check** Open browser and verify: - `/trips` — trip filter buttons are square-cornered (not pill-shaped) - `/trips/` — stats panel shows left accent stripe, cream numbers, no box border - Header — "into the east" is slightly larger with wider tracking; accent stripe has gradient - [x] **Step 7: Commit** ```bash git -C user add themes/intotheeast/css/style.css git -C user commit -m "style: pill grammar, stats field-notes, header identity" ``` --- ## Task 2: Replace emoji icons in journal entry partial **Files:** - Modify: `user/themes/intotheeast/templates/partials/entry-journal.html.twig` **Interfaces:** - Affects: every journal entry in the home feed, trip feed, and standalone entry page - [x] **Step 1: Replace location emoji with SVG pin** Find in the partial: ```twig · 📍 ``` Replace with: ```twig · ``` - [x] **Step 2: Strip weather emoji prefix** Find in the partial: ```twig · {{ weather_icons[entry.header.weather_desc] ?? '' }} {{ entry.header.weather_desc }} ``` Replace with: ```twig · {{ entry.header.weather_desc }} ``` The `weather_icons` map at the top of the partial can stay (removing it is optional cleanup); it will simply go unused. - [x] **Step 3: Smoke check** Open any trip page in browser. Confirm: - Location shows small SVG pin instead of 📍 - Weather shows plain text (e.g. "· Sunny") with no emoji - [x] **Step 4: Commit** ```bash git -C user add themes/intotheeast/templates/partials/entry-journal.html.twig git -C user commit -m "style: replace emoji icons with SVG pin and plain weather text" ``` --- ## Task 3: Trip cards — cover image **Files:** - Modify: `user/themes/intotheeast/blueprints/trip.yaml` - Modify: `user/themes/intotheeast/templates/trips.html.twig` - Modify: `user/themes/intotheeast/css/style.css` **Interfaces:** - Produces: optional cover image banner on each trip card - Consumes: `trip.header.cover_image` (new field) or first image from first published entry - [x] **Step 1: Read the current trip blueprint** ```bash cat user/themes/intotheeast/blueprints/trip.yaml ``` Locate the correct position to insert the new field (after `tagline` or near other media fields). - [x] **Step 2: Add cover_image field to blueprint** Insert in `trip.yaml` at an appropriate location: ```yaml cover_image: type: filepicker label: Cover Image preview_images: true folder: '@self' accept: - image/* ``` - [x] **Step 3: Add cover image CSS to style.css** In the `/* ── Past trips archive */` section, add after `.trip-card-counts`: ```css .trip-card-cover { aspect-ratio: 3 / 1; overflow: hidden; border-radius: var(--radius-md) var(--radius-md) 0 0; background: var(--color-border); margin: calc(-1 * var(--space-6)) calc(-1 * var(--space-6)) var(--space-5); } .trip-card-cover img { width: 100%; height: 100%; object-fit: cover; display: block; transition: transform 0.45s ease; } .trip-card:hover .trip-card-cover img { transform: scale(1.04); } ``` - [x] **Step 4: Update trips.html.twig to render cover image** Inside the `{% for trip in trips %}` loop, before the `.trip-card-title` div, add: ```twig {# Cover image: explicit field first, then first entry's first image #} {% set cover = null %} {% if trip.header.cover_image and trip.media[trip.header.cover_image] is defined %} {% set cover = trip.media[trip.header.cover_image] %} {% elseif dailies_page %} {% set first_entry = dailies_page.children.published()|first %} {% if first_entry and first_entry.media.images|length > 0 %} {% set cover = first_entry.media.images|first %} {% endif %} {% endif %} {% if cover %}
{{ trip.title }}
{% endif %} ``` - [x] **Step 5: Smoke check** Open `/trips` in browser. Confirm: - Trips with media show a 3:1 cover photo banner - Trips without media show text-only card (no broken image element) - Hover scales the image slightly - [x] **Step 6: Commit** ```bash git -C user add themes/intotheeast/blueprints/trip.yaml themes/intotheeast/templates/trips.html.twig themes/intotheeast/css/style.css git -C user commit -m "feat: trip cards show cover image with 3:1 crop and hover zoom" ``` --- ## Task 4: Story opening transition **Files:** - Modify: `user/themes/intotheeast/templates/story.html.twig` - Modify: `user/themes/intotheeast/css/style.css` **Interfaces:** - Consumes: `date_str` and `location` already computed at the top of `story.html.twig` - Produces: a centered location/date block at the top of `.story-body` with fade-in animation - [x] **Step 1: Add story-opener CSS to style.css** In the `/* ── Story pages */` section, after `.story-body p` rules, add: ```css .story-opener { text-align: center; padding-bottom: var(--space-12); margin-bottom: var(--space-12); border-bottom: 1px solid var(--color-border); opacity: 0; animation: storyReveal 0.9s cubic-bezier(.16,1,.3,1) 0.8s both; } .story-opener__text { font-family: var(--font-ui); font-size: var(--text-sm); color: var(--color-ink-muted); letter-spacing: 0.06em; text-transform: uppercase; } @media (prefers-reduced-motion: reduce) { .story-opener { opacity: 1; animation: none; } } ``` - [x] **Step 2: Add opener block to story.html.twig** Inside `.story-body`, immediately before `{{ page.content|raw }}`, add: ```twig {% if location or date_str %}
{{- date_str -}} {%- if location and date_str %} · {% endif -%} {{- location -}}
{% endif %} ``` - [x] **Step 3: Smoke check** Open any published story in browser. Confirm: - A small uppercase line showing date and location appears below the hero spacer - It is separated from the prose by a thin horizontal rule - It fades in after the hero title animation completes - On a story with no location set: only date appears (or nothing if both are absent) - [x] **Step 4: Commit** ```bash git -C user add themes/intotheeast/templates/story.html.twig themes/intotheeast/css/style.css git -C user commit -m "feat: story opening transition with location and date eyebrow" ``` --- ## Task 5: Reading progress bar on story pages **Files:** - Modify: `user/themes/intotheeast/templates/story.html.twig` - Modify: `user/themes/intotheeast/css/style.css` **Interfaces:** - Produces: 2px teal bar fixed at bottom of site header, progress tied to `.story-body` scroll position - No bar rendered at all if `prefers-reduced-motion` is set (JS skips creating it) - [x] **Step 1: Add progress bar CSS to style.css** In the `/* ── Story pages */` section, add: ```css .story-progress { position: fixed; top: var(--site-header-height); left: 0; height: 2px; width: 0%; background: var(--color-accent); z-index: 200; pointer-events: none; will-change: width; } ``` - [x] **Step 2: Add progress bar element and JS to story.html.twig** Immediately after `{% block content %}` (before the hero markup), add: ```twig
``` In the `