Read this for UI, UX, layout, theme, and page workflow tasks.
- Quiet, minimal, data-first running dashboard.
- Keep map, static route gallery, activity ledger, statistics, sync, and data-source workflows.
- Avoid old cyber/neon direction for active product surfaces.
- UI should feel like an operational workspace, not a marketing page.
- Root layout:
apps/web/src/app/layout.tsx - Providers:
apps/web/src/app/providers.tsx - Active app shell:
apps/web/src/components/AppLayout.tsx - Global styles/tokens:
apps/web/src/app/globals.css
AppLayout owns:
- grouped sidebar navigation
- sticky contextual header
- mobile drawer
- theme toggle
- language toggle
- contextual quick actions
- Current UI languages: English, Simplified Chinese, and Japanese.
- Translation state lives in
apps/web/src/lib/i18n.tsx. I18nProvideris wired throughapps/web/src/app/providers.tsx; useuseI18n()for visible app copy.- The language toggle is an icon button in
apps/web/src/components/AppLayout.tsxand cyclesen -> zh -> ja. - Locale defaults to the browser language on first visit. Manual language changes are saved as an explicit preference in localStorage and then override browser language on later visits.
- Keep route names, dashboard slogans, empty states, button labels, and map/sync helper copy in the shared dictionaries instead of hard-coding new visible strings.
- Current hero slogan:
- English: "Leave a running trace in every city you reach."
- Chinese: "在每座抵达的城市,留下跑步轨迹。"
- Japanese: "訪れたすべての街に、走った軌跡を残す。"
- Theme provider uses
next-themeswith class strategy. - Use
resolvedThemefor toggles, not rawtheme, becausethemecan besystem. - Typography uses Manrope for Latin/numerics, JetBrains Mono for monospace, Noto Sans SC for Simplified Chinese, and Noto Sans JP for Japanese. Keep CJK fonts neutral and data-friendly; avoid decorative handwritten or rounded display fonts for operational UI.
- Light/dark core tokens live in
globals.css:--bg-0,--bg-1,--bg-2--surface,--surface-2--sidebar-bg,--header-bg--border--text-strong,--text-muted
- Prefer
text-[var(--text-strong)]andtext-[var(--text-muted)]for app-shell pages.
.panel.panel-header.panel-body.metric-label.metric-value.action-primary.action-secondary.action-ghost.section-title.section-subtitle
Use these before adding new one-off card/button styles.
/dashboard:apps/web/src/app/dashboard/page.tsx, implementation indashboard/CyberDashboard.tsxdespite the legacy filename./activities:apps/web/src/app/activities/page.tsx/stats:apps/web/src/app/stats/page.tsx/map:apps/web/src/app/map/page.tsx/sync:apps/web/src/app/sync/page.tsx/data-sources:apps/web/src/app/data-sources/page.tsx/sync-status:apps/web/src/app/sync-status/page.tsx
- Map views:
apps/web/src/components/maps/ - Route visuals:
apps/web/src/components/routes/ - Brand/icons:
apps/web/src/components/icons/
Legacy cyber/template/Catalyst component islands were removed in the 2026-04-30 cleanup. Keep new UI in the active app shell and page-local components unless a shared primitive is genuinely reused.
- Keep sections dense and scannable.
- Do not remove route/map functionality during visual changes.
- Avoid decorative glow, scanlines, and neon-heavy styling.
- Keep tables readable in light and dark mode.
- Avoid introducing new nested card layouts.
- For form controls, make light mode text explicit; do not rely on inherited dark text classes.
- Dashboard route constellations may animate real route polylines, but should stay route-atlas themed: dark map grid, subdued ghost traces, sequential colored route highlights, and
prefers-reduced-motioncompatibility. - Dashboard hero should keep the title large but shallow on desktop: headline spans the top, intro/metrics stay in a compact left rail, the animated constellation keeps a fixed aspect-ratio card on the right, and the runner cameo floats in unused space without covering core metric values.
- Dashboard hero runner animation should preserve the existing high-quality PNG cameo. Use only subtle container motion such as floating/breathing unless a dedicated art pipeline provides matching frame art; do not replace it with Codex-drawn SVG frame loops that clash with the current illustration quality.
- Stats consistency heatmaps should use a GitHub-style calendar: continuous week columns, weekday labels, month markers, fixed small cells, horizontal scrolling for the selected year, and a compact Less/More intensity legend.
- Favorite-runner visuals are generated low-poly character cutouts under
apps/web/public/assets/runners/. They should appear as unlabeled lively cameos woven into dashboard/poster surfaces, not as an explicit "runner muse" module. Use floating layout/layering rather than motion effects; slight overlap with descriptive copy is allowed when it feels intentional and editorial. Keep route glyphs, metric rows, hero headlines, and primary controls readable, and keep silhouettes complete. - Runner asset set: four original runner-inspired characters now have run/stretch/lifestyle/pose coverage in
apps/web/src/lib/runnerMuses.ts. Treat the PNGs as fictional low-poly UI assets, not portraits or real-athlete photos. - Transparent runner PNG QA: verify full-body framing, no text/logo/bib/flag/watermark, no realistic likeness, and alpha extrema including
0before adding a file to the registry. - Poster cards can use low-opacity runner cutouts as deterministic-random background texture. Choose run/stride poses for faster running periods and walk/stretch/lifestyle/pose variants for walk-like or slow periods; keep the background figure subtle in the lower-right third so route data remains primary.