d190094e80
Design direction: Field Notes — DM Serif Display + DM Sans typography, deep teal (#1F6B5A) accent, full-bleed entry card photos with overlay. 9-task implementation plan covering tokens, header, feed, entry page, post form, stats/map, mobile polish, and visual QA checklist. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
369 lines
16 KiB
Markdown
369 lines
16 KiB
Markdown
# Into the East — Design Spec
|
|
|
|
**Date:** 2026-06-18
|
|
**Status:** Approved for implementation
|
|
|
|
---
|
|
|
|
## 1. Direction
|
|
|
|
**The brief:** A personal travel journal, sole author, trip to East Asia. Three weeks to implement before departure. Audience is both friends/family and the occasional curious stranger.
|
|
|
|
**The position:** Neither Polarsteps nor FindPenguins. Both optimize for social sharing of travel data. This site optimizes for **the story** — and should feel like reading a well-edited travel journal, not using an app.
|
|
|
|
**What we steal from each:**
|
|
- Polarsteps: photography-first hierarchy, airy whitespace, map as the emotional spine of the trip
|
|
- FindPenguins: typography as brand identity, stats as trophy case, hierarchical trip → entry structure
|
|
|
|
**What we do better than both:**
|
|
- Web-native: fast, linkable, no install, works on any browser
|
|
- Single author = pure editorial voice, no social noise
|
|
- Full CSS control = real typographic identity, not generic app chrome
|
|
- Editorial feel: more travel magazine, less productivity dashboard
|
|
|
|
**Aesthetic direction:** Field notes. The kind of journal a thoughtful traveler would carry — clean, direct, lets the photography speak. Sophisticated without effort.
|
|
|
|
**The one aesthetic risk:** Full-bleed hero photography with a translucent date+location overlay at the bottom of each card. The photo IS the entry card — not a thumbnail beside text. This is the single element that distinguishes this design from both reference apps and from typical blog layouts.
|
|
|
|
---
|
|
|
|
## 2. Color System
|
|
|
|
### Palette
|
|
|
|
| Token | Hex | Usage |
|
|
|---|---|---|
|
|
| `--color-ink` | `#17171A` | Primary text (near-black with cool undertone, like ink) |
|
|
| `--color-ink-2` | `#4A4850` | Secondary text, body paragraphs |
|
|
| `--color-ink-muted` | `#9896A0` | Labels, timestamps, captions, placeholder text |
|
|
| `--color-paper` | `#F7F5F2` | Page background (warm paper white, not blue-white) |
|
|
| `--color-canvas` | `#FFFFFF` | Card backgrounds, modals, form surfaces |
|
|
| `--color-border` | `#E8E6E3` | Standard dividers, card borders |
|
|
| `--color-border-soft` | `#F0EDEA` | Subtle section dividers |
|
|
| `--color-accent` | `#1F6B5A` | Deep teal — brand color, links, CTAs, active states |
|
|
| `--color-accent-hover` | `#185647` | Darkened accent for hover/pressed states |
|
|
| `--color-accent-light` | `#EBF5F2` | Pale teal for highlight backgrounds |
|
|
| `--color-accent-on` | `#FFFFFF` | Text on accent-colored surfaces |
|
|
|
|
### Rationale for accent color
|
|
|
|
Deep teal `#1F6B5A` was chosen over:
|
|
- Blue (#0066cc current): too generic, too tech
|
|
- Orange/saffron: clichéd for "Asia" travel design
|
|
- Terracotta/cream: the most common default for lifestyle/travel blogs
|
|
|
|
Teal evokes bamboo, celadon porcelain, ancient jade, the color of temple gardens — all without being literal or kitsch. It works cleanly against both the warm paper background and white card surfaces.
|
|
|
|
---
|
|
|
|
## 3. Typography
|
|
|
|
### Fonts
|
|
|
|
| Role | Family | Fallback | Source |
|
|
|---|---|---|---|
|
|
| Display / Headings | DM Serif Display | Georgia, serif | Google Fonts |
|
|
| UI / Body / Labels | DM Sans | -apple-system, BlinkMacSystemFont, sans-serif | Google Fonts |
|
|
|
|
**Google Fonts URL:**
|
|
```
|
|
https://fonts.googleapis.com/css2?family=DM+Sans:ital,opsz,wght@0,9..40,400;0,9..40,500;0,9..40,600;1,9..40,400&family=DM+Serif+Display:ital@0;1&display=swap
|
|
```
|
|
|
|
**Why this pairing:**
|
|
DM Serif Display has a calligraphic quality — slightly editorial, authoritative but not stiff. Paired with DM Sans (its designed companion) the system is cohesive. DM Sans is neutral and highly legible at all sizes. Both are under-used relative to Inter/Lato/Playfair, so the combination has a distinctive voice without being trendy.
|
|
|
|
### Type Scale
|
|
|
|
| Token | Size | Line Height | Usage |
|
|
|---|---|---|---|
|
|
| `--text-xs` | 0.75rem (12px) | 1.5 | Badges, captions |
|
|
| `--text-sm` | 0.875rem (14px) | 1.5 | Meta, timestamps, labels |
|
|
| `--text-base` | 1rem (16px) | 1.65 | Body paragraphs |
|
|
| `--text-md` | 1.125rem (18px) | 1.55 | Lead text, intro paragraphs |
|
|
| `--text-lg` | 1.375rem (22px) | 1.35 | Subheadings, card titles (mobile) |
|
|
| `--text-xl` | 1.75rem (28px) | 1.25 | Entry card titles |
|
|
| `--text-2xl` | 2.25rem (36px) | 1.2 | Page headings, entry titles (desktop) |
|
|
| `--text-3xl` | 3rem (48px) | 1.1 | Hero entry title |
|
|
|
|
### Usage rules
|
|
|
|
- Entry titles: `--font-display`, `--text-xl` (mobile) / `--text-2xl` (desktop)
|
|
- Site title in header: `--font-display`, `--text-lg`
|
|
- All other UI text: `--font-ui`
|
|
- Body paragraphs: `--font-ui`, `--text-base`, `--leading-normal`
|
|
- Timestamps/badges: `--font-ui`, `--text-xs`, uppercase, `letter-spacing: 0.07em`
|
|
|
|
---
|
|
|
|
## 4. Spacing & Layout
|
|
|
|
### Spacing scale (4px base unit)
|
|
|
|
| Token | Value |
|
|
|---|---|
|
|
| `--space-1` | 0.25rem (4px) |
|
|
| `--space-2` | 0.5rem (8px) |
|
|
| `--space-3` | 0.75rem (12px) |
|
|
| `--space-4` | 1rem (16px) |
|
|
| `--space-5` | 1.25rem (20px) |
|
|
| `--space-6` | 1.5rem (24px) |
|
|
| `--space-8` | 2rem (32px) |
|
|
| `--space-10` | 2.5rem (40px) |
|
|
| `--space-12` | 3rem (48px) |
|
|
| `--space-16` | 4rem (64px) |
|
|
|
|
### Layout
|
|
|
|
- Content max-width: `720px` (comfortable reading at any font size)
|
|
- Page horizontal padding: `1.25rem` (mobile), `1.5rem` (desktop ≥520px)
|
|
- Header height: `60px` (fixed, for JS offset calculations)
|
|
- Map page: full viewport, no content max-width constraint
|
|
|
|
### Border radius
|
|
|
|
| Token | Value | Usage |
|
|
|---|---|---|
|
|
| `--radius-sm` | 4px | Photo corners, small chips |
|
|
| `--radius-md` | 8px | Cards, buttons, inputs |
|
|
| `--radius-lg` | 12px | Large cards, modals |
|
|
| `--radius-full` | 9999px | Pills, badges |
|
|
|
|
### Shadows
|
|
|
|
| Token | Value | Usage |
|
|
|---|---|---|
|
|
| `--shadow-sm` | `0 1px 3px rgba(0,0,0,0.08)` | Stat blocks, subtle elevation |
|
|
| `--shadow-md` | `0 4px 12px rgba(0,0,0,0.10)` | Cards on hover, dropdowns |
|
|
| `--shadow-lg` | `0 8px 24px rgba(0,0,0,0.14)` | Lightbox, modals |
|
|
|
|
---
|
|
|
|
## 5. Component Inventory
|
|
|
|
### 5.1 Site Header
|
|
|
|
```
|
|
[ into the east ] [ Journal Map Stats ]
|
|
← accent bar across top (3px) ───────────────────────────────
|
|
```
|
|
|
|
- Top border: `3px solid var(--color-accent)` — thin accent bar signals the brand color without decorating
|
|
- Site title: DM Serif Display, `--text-lg`, no decoration
|
|
- Nav links: DM Sans, `--text-sm`, weight 500, `--color-ink-2`
|
|
- Active nav link: `--color-accent`, weight 600
|
|
- Mobile: same layout, title slightly smaller, nav links compact
|
|
- Background: `--color-canvas` (white), bottom border `1px solid var(--color-border)`
|
|
|
|
### 5.2 Entry Feed Card — With Photo
|
|
|
|
```
|
|
┌─────────────────────────────────────┐
|
|
│ │
|
|
│ [photo] │ ← full-width, 16:9, rounded corners
|
|
│ │
|
|
│ 18 JUN · 📍 Kyoto, Japan │ ← overlaid at bottom, gradient mask
|
|
└─────────────────────────────────────┘
|
|
Arrived in Tokyo ← DM Serif Display, --text-xl
|
|
After 14 hours of flying I finally ← body excerpt, --color-ink-2
|
|
set foot on Japanese soil...
|
|
Read entry → ← --color-accent, --text-sm
|
|
```
|
|
|
|
- Photo: `aspect-ratio: 16/9`, `object-fit: cover`, `border-radius: var(--radius-md)`
|
|
- Photo has a `linear-gradient(to top, rgba(0,0,0,0.55), transparent)` overlay at the bottom 40%
|
|
- Date + location sit on top of gradient in white text (`rgba(255,255,255,0.92)`)
|
|
- On hover: photo scales to 1.03 (subtle zoom, 0.4s ease)
|
|
- Title below photo: DM Serif Display, hover turns `--color-accent`
|
|
- Card separation: `padding-bottom: var(--space-12)` + `border-bottom: 1px solid var(--color-border)`
|
|
|
|
### 5.3 Entry Feed Card — No Photo
|
|
|
|
When no photo is available, fall back to a text-only layout:
|
|
|
|
```
|
|
18 JUN 2026 · 📍 Kyoto, Japan ← meta row, --text-sm, --color-ink-muted
|
|
|
|
Arrived in Tokyo ← DM Serif Display, --text-xl
|
|
After 14 hours of flying...
|
|
Read entry →
|
|
```
|
|
|
|
- No photo container
|
|
- Meta (date + location) on one line above title, small + muted
|
|
|
|
### 5.4 Single Entry Page
|
|
|
|
```
|
|
Wednesday, 18 June 2026 ← --text-sm, --color-ink-muted, uppercase
|
|
📍 Kyoto, Japan · ⛅ Partly cloudy · 22°C
|
|
|
|
Arrived in Tokyo ← DM Serif Display, --text-2xl / --text-3xl
|
|
─────────────────────────────────────
|
|
Body text content... ← --font-ui, --text-base/md
|
|
|
|
[Photo gallery — 2 or 3 col grid]
|
|
|
|
← Back to journal
|
|
```
|
|
|
|
- The entry title uses `--font-display` at largest scale
|
|
- A thin `--color-border` rule separates the header from the body
|
|
- Body text is `--text-md` (18px) for comfortable long-form reading
|
|
- Full-bleed hero option: if a `hero_image` is set, it spans the full content width with a bottom margin
|
|
|
|
### 5.5 Post Form (Author View)
|
|
|
|
```
|
|
New Entry
|
|
|
|
Title * [________________________]
|
|
Date & Time [2026-06-18 14:30 ]
|
|
What happened [ ]
|
|
today? [ ]
|
|
[ ]
|
|
|
|
Photos [ + Add photos (max 4) ]
|
|
|
|
City [________________________]
|
|
Country [________________________]
|
|
|
|
[ 📍 Get Location ] [ 🌤 Get Weather ]
|
|
✓ Location captured: Kyoto, Japan ← status line
|
|
|
|
[ Post Entry ]
|
|
```
|
|
|
|
UX changes from current:
|
|
- Lat/lng inputs **hidden from the UI** (remain in the form as `display:none` for data capture, filled by JS)
|
|
- Location status shows captured city/country + coordinates in a single line (not separate status paragraphs)
|
|
- Photo upload area: larger touch target, visual indication of count
|
|
- "Post Entry" button: `--color-accent` background, full-width on mobile, `min-height: 52px`
|
|
- Form fields: `--radius-md` corners, `--color-border` border, focus ring in `--color-accent`
|
|
- Section spacing: generous vertical rhythm on mobile
|
|
|
|
### 5.6 Stats Page
|
|
|
|
```
|
|
┌────────────┐ ┌────────────┐
|
|
│ 42 │ │ 18 │
|
|
│ days on │ │ entries │
|
|
│ the road │ │ posted │
|
|
└────────────┘ └────────────┘
|
|
┌────────────┐ ┌────────────┐
|
|
│ 6 │ │ ~14,200 │
|
|
│ countries │ │ km │
|
|
│ visited │ │ traveled │
|
|
└────────────┘ └────────────┘
|
|
|
|
Countries visited
|
|
Japan · South Korea · Mongolia · Russia · Finland · Estonia
|
|
```
|
|
|
|
- Numbers: `--font-display`, `--text-3xl`, `--color-accent`
|
|
- Labels: `--font-ui`, `--text-xs`, uppercase, `--color-ink-muted`
|
|
- Cards: white, `--shadow-sm`, `--radius-md`, centered
|
|
|
|
### 5.7 Map Page
|
|
|
|
Minimal changes — the map itself is good. Style improvements:
|
|
- Leaflet popups: match the new design (DM Sans, `--radius-md`, `--shadow-md`)
|
|
- Markers: keep current circle style, update color to `--color-accent`
|
|
- Feed mini-map wrapper: match `--radius-md`, `--border`
|
|
|
|
---
|
|
|
|
## 6. UX Flows
|
|
|
|
### 6.1 Reader — First Visit
|
|
|
|
1. Land on `/tracker` (journal feed)
|
|
2. See mini-map above fold (if entries exist) — route tells the geographic story at a glance
|
|
3. First entry card: full-bleed hero photo with date/location overlay — immediate emotional pull
|
|
4. Scroll through chronological entries
|
|
5. Tap/click entry → entry detail page
|
|
6. Navigate back via "← Back to journal"
|
|
|
|
**Key principle:** The reader should understand the journey spatially (mini-map) and emotionally (hero photo) before reading a single word.
|
|
|
|
### 6.2 Reader — Navigation
|
|
|
|
- Journal: primary destination, the feed
|
|
- Map: geographic exploration mode
|
|
- Stats: quick numbers, satisfying progress indicator
|
|
- No account required, no social friction, no login prompt for readers
|
|
|
|
### 6.3 Author — Posting from Mobile
|
|
|
|
1. Navigate to `/post` (bookmark on home screen)
|
|
2. Already logged in (Grav session persists) — form loads directly
|
|
3. **Title**: tap → type (autofocused)
|
|
4. **Date & Time**: auto-filled to now, adjust if needed
|
|
5. **Content**: write what happened
|
|
6. **Photos**: tap "Add photos" → camera or gallery → select up to 4
|
|
7. **Location**: tap "📍 Get Location" → GPS fires → status shows "Kyoto, Japan · 34.985, 135.758" in one line
|
|
8. **Weather**: tap "🌤 Get Weather" (works only if location was captured) → status shows "Partly cloudy · 22°C"
|
|
9. **City/Country**: auto-populated from GPS is a nice-to-have for v2; in v1 type manually if needed
|
|
10. Tap "Post Entry" → success message → 2-second pause → redirect to /tracker (new entry visible at top)
|
|
|
|
**Key principles:**
|
|
- One-thumb operation for all critical actions on mobile
|
|
- Location/weather are conveniences, not blockers — can skip both
|
|
- Visual feedback is immediate (status line updates on GPS response)
|
|
- After submit: don't leave author on a success message page; redirect to see their new post
|
|
|
|
---
|
|
|
|
## 7. Mobile Specifics
|
|
|
|
### Touch targets
|
|
- All interactive elements: `min-height: 44px`, `min-width: 44px` (Apple HIG standard)
|
|
- Form buttons: `min-height: 52px` on the post form (primary CTA)
|
|
- Nav links: `padding: 0.5rem 0.75rem`
|
|
|
|
### Viewport concerns
|
|
- Map page: `height: calc(100vh - 60px)`, `touch-action: none` on map container — prevents scroll trap
|
|
- Photo lightbox: full viewport overlay, swipe-friendly (keyboard + click already implemented)
|
|
- Form on mobile: single-column, generous input padding `0.875rem 1rem`, `font-size: 1rem` (prevents iOS zoom on focus)
|
|
|
|
### Performance
|
|
- Google Fonts: loaded with `preconnect` hints
|
|
- Images: `loading="lazy"` on all non-above-fold images (already in place)
|
|
- Leaflet: loaded from CDN, only on pages that need it
|
|
- No new JS frameworks — vanilla JS throughout
|
|
|
|
---
|
|
|
|
## 8. Tech Stack Decision
|
|
|
|
**Keep Grav CMS.** With a 3-week timeline, replacing it would consume all available time on migration rather than design improvements.
|
|
|
|
| Layer | Decision | Rationale |
|
|
|---|---|---|
|
|
| Backend | Grav CMS (PHP, Twig) — unchanged | Works, flat-file, no DB |
|
|
| CSS | Vanilla CSS + custom properties (design tokens) | No build step, full control, ships as one file |
|
|
| JS | Vanilla JS — unchanged | Current JS is well-structured, scope doesn't justify a framework |
|
|
| Icons | Unicode + emoji (current) | No dependency, works everywhere |
|
|
| Fonts | Google Fonts via CDN | Two fonts, display-swap, negligible impact |
|
|
| Maps | Leaflet.js (current) | Already in use, no reason to change |
|
|
| Build | None — no build pipeline | Grav's asset pipeline handles minification if needed |
|
|
|
|
**No Alpine.js, no TypeScript, no Tailwind.** The site has clean vanilla JS and CSS today; a redesign is about visual quality, not framework migration. Introducing a build pipeline on a 3-week timeline is a distraction.
|
|
|
|
---
|
|
|
|
## 9. What Changes From Current Design
|
|
|
|
| Area | Current | New |
|
|
|---|---|---|
|
|
| Typography | System sans-serif only | DM Serif Display for headings + DM Sans for UI |
|
|
| Accent color | `#0066cc` (generic blue) | `#1F6B5A` (deep teal) |
|
|
| Background | `#ffffff` (pure white) | `#F7F5F2` (warm paper) |
|
|
| Entry cards | Thumbnail + text below | Full-bleed 16:9 photo with overlay |
|
|
| Header | No visual identity | Accent top-border, typographic title |
|
|
| Design tokens | Hardcoded values throughout | CSS custom properties throughout |
|
|
| Post form | Lat/lng visible inputs | Lat/lng hidden, single status line |
|
|
| Font loading | None | Google Fonts DM pairing |
|
|
| Hover states | Minimal | Photo zoom, title color change |
|
|
| Stat numbers | `#0066cc` | `--color-accent` (#1F6B5A) |
|