Files
intotheeast-com/docs/reference/design-system-light.md
T

16 KiB

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)