Landing Page Enhancement Project Plan
Goal
Extend app/views/static/index.html.erb with new feature sections that showcase Vision, Leaderboard, Focus Timer, the Gamer Dashboard, and the year-grid framing borrowed from loggd.life — without abandoning Lifehub's existing PT-BR finance-first hero and brand. The result is a landing page that tells the full "organize your life, see your year, compete with the community" story while preserving everything we already ship today.
Inspiration
Visual reference: the loggd.life landing page (https://loggd.life/). We borrow the year-heatmap visualization, gamified social proof framing, and the "see your year" narrative beat. We do not copy the language (we stay PT-BR), the pricing tiers (Lifehub uses Stripe + Pay), or the testimonial format (we don't have user testimonials yet).
User Experience
The visitor should understand, in order:
- Lifehub is a complete personal-life platform (existing hero — keep).
- Lifehub already covers finances, goals, habits, tasks (existing feature blocks — keep).
- NEW: Lifehub helps you define your long-term direction (Vision section).
- NEW: Lifehub turns daily action into visible progress (Year heatmap section).
- NEW: Lifehub gives you focused time blocks (Focus Timer section).
- NEW: Lifehub ranks you against the community (Leaderboard section).
- NEW: Lifehub looks like a game (Gamer Dashboard section, expanding the existing tease).
- NEW: Lifehub has 50 levels and 65+ badges (Levels & Badges strip).
- Existing CTA, footer, pricing — keep.
Each new section follows the same pattern as existing feature sections: tag chip, bilingual-friendly headline, supporting paragraph, mockup illustration, and a small CTA where appropriate.
Scope
This plan modifies the existing landing page in place. No new controller, no new route. Visual mockups are shipped as PNG assets (generated like the gamer-dashboard map), and supporting CSS is added to app/assets/tailwind/application.css.
New Sections (in render order)
A. Year Heatmap Hero Strip (after the existing dashboard mockup)
- Tag chip:
Veja seu ano - Headline:
Cada dia conta. Cada hábito ganha cor. - Subhead:
Acompanhe sua consistência ao longo de 365 dias e veja onde sua vida está acendendo. - Visual: a 53×7 contribution grid with realistic-looking color density (Tailwind cells, no PNG needed) plus tooltips.
- CTA: anchor link to "Hábitos" feature block.
B. Vision section ("Defina sua estrela-norte")
- Tag chip:
Visão - Headline:
Defina sua estrela-norte. Construa a vida que você quer. - Subhead:
Carta dos 100, lista dos sonhos, missão pessoal, definição de sucesso e plano Odyssey — todos em um lugar. - Mockup: stylized Vision page screenshot with the six sections laid out (PNG generated).
- Bullet list of the six exercises (Letter from 100, Bucket List, Mission, Definition of Success, Odyssey Plan, Future Calendar).
- CTA:
Começar grátis→ registration.
C. Focus Timer section ("Foque no que importa")
- Tag chip:
Foco - Headline:
Pomodoro com propósito. - Subhead:
Sessões ligadas a tarefas, hábitos ou objetivos. Cada minuto vira XP. Veja seus picos e padrões. - Mockup: focus timer dashboard PNG (timer hero + sessions list + 365-day heatmap).
- Three-column feature highlight:
Pomodoro 25/50/custom,Heatmap anual,Distribuição por tarefa/hábito/meta. - CTA anchor to gamification block.
D. Leaderboard section ("Compita com a comunidade")
- Tag chip:
Comunidade - Headline:
Você não está sozinho. Veja onde você está. - Subhead:
Ranking mensal, hall da fama e atividade da comunidade. Mantenha-se motivado vendo seu progresso ao lado dos outros. - Mockup: leaderboard podium + ranked list PNG.
- Inline live-feeling activity strip (3-4 fake events with avatars).
- CTA:
Veja o leaderboard ao vivo→/leaderboard(only visible/enabled when authenticated; fallback to/users/sign_upotherwise).
E. Gamer Dashboard tease (expanded)
The existing landing page has a small mention of Nível 14 in the dashboard mockup. We expand this with a dedicated section.
- Tag chip:
Painel Gamer - Headline:
Sua vida com cara de RPG. - Subhead:
Personagens pixel, mapa do mundo Lifehub, missões diárias e próximas conquistas — tudo no painel/gamer. - Mockup: gamer dashboard PNG (reusing
app/assets/images/gamer/maps/lifehub-world.pngif visually fitting, otherwise a new dashboard composite).
F. Levels & Badges strip
- Tag chip:
Conquistas - Headline:
50 níveis. 11 personagens. 65+ medalhas. - Visual: a horizontal strip of the eleven character PNGs from
app/assets/images/gamer/characters/followed by a 4×4 grid of badge tile mockups. - Subhead linking to gamification page after sign-up.
Architecture
This is purely a view + asset change.
app/views/static/index.html.erb # add 6 new sections
app/views/static/_year_heatmap.html.erb # extracted partial (reusable)
app/views/static/_vision_preview.html.erb # new
app/views/static/_focus_timer_preview.html.erb # new
app/views/static/_leaderboard_preview.html.erb # new
app/views/static/_gamer_dashboard_preview.html.erb # new
app/views/static/_levels_badges_strip.html.erb # new
app/assets/images/landing/vision-mockup.png # generated
app/assets/images/landing/focus-timer-mockup.png # generated
app/assets/images/landing/leaderboard-mockup.png # generated
app/assets/images/landing/gamer-dashboard-mockup.png # generated
app/assets/images/landing/badge-tiles.png # generated (or inline SVG)
app/assets/tailwind/application.css # add `.heatmap-cell` utilities, scroll behavior
The existing _navbar.html.erb gets new anchor links to the new sections.
DRY pattern: _landing_section helper
The existing index file currently inlines six near-identical section wrappers. This plan adds six more, which would push duplication past the breaking point. Extract a single helper or partial:
<%= render "static/landing_section",
anchor: "vision",
tag: "Visão",
headline: "Defina sua estrela-norte. Construa a vida que você quer.",
subhead: "Carta dos 100, lista dos sonhos, ...",
mockup: "landing/vision-mockup.png" do %>
<%# Optional inline content (bullets, callouts) %>
<% end %>
The partial owns the chip, heading, subhead, and a yield-block for inline content + a mockup image slot. We refactor the existing six sections to use it as part of this work, which leaves the page strictly cleaner than we found it.
Performance
- All mockups are exported as appropriately sized PNGs (
max-w-5xl, ~1600px wide, optimized to <200KB each viaimage_processing). - The year heatmap is rendered as ~371 small
<div>cells; this is well under 16KB of HTML. - No JavaScript added beyond what already runs on the landing page.
- Above-the-fold weight increases by less than 50KB once mockup images are below-the-fold and lazy-loaded with
loading="lazy".
Security
This is a public, unauthenticated page; no user input flows into it. The only writes are to app/views/static/index.html.erb and partials, which are reviewed code, not runtime data.
CSP considerations: all mockups are served from same-origin asset paths. No third-party embeds added.
Visual Style
- Continue the existing light theme of
static/index.html.erb. The new sections use the same gray/white background as their neighbors with strategic dark mockups inside cards. - Each new section uses the existing
<section>rhythm:pt-24 pb-12,max-w-6xl, centered hero, mockup beneath. - Heatmap cells use a 5-step emerald scale (
emerald-100→emerald-700) plus agray-100empty cell — matching gamification accents. - Mockup images use the same
mockup-browserchrome already defined in the landing CSS (browser dots + URL pill + content area).
Internationalization
The landing page is currently PT-BR only. We keep that for this milestone — no new locale plumbing.
We do, however, structure the new sections so that t("static.landing.vision.headline") can replace inline copy in a future bilingual pass. All new copy moves to config/locales/pt-BR.yml under static.landing.* keys; the partial reads from that namespace via t().
This is a one-time cleanup that pays for itself the moment we add an EN landing page.
Testing Plan
- Static page renders successfully unauthenticated.
- All new section anchors are present in the navbar.
- No console errors when scrolling through the page (system test).
- Mockup images respond with 200 and
image/png. - Lazy-loading attribute is applied to all below-the-fold mockups.
- HTML validates (no broken markup) — assert via system test that all
<section>tags close.
bin/rails test test/system/static_index_test.rb
bin/ci
Implementation Phases
Phase 1 — Refactor existing sections to a shared partial
- Extract
_landing_section.html.erb. - Migrate the existing six finance/goals/habits/tasks/tools/dashboard sections to use it.
- Run system test → ensure visual parity (snapshot diff if available, otherwise manual check).
Phase 2 — Add new sections
- Build
_year_heatmap.html.erb(no mockup; pure HTML/CSS). - Add Vision, Focus Timer, Leaderboard, Gamer Dashboard, Levels & Badges sections, each via the shared partial.
Phase 3 — Generate mockup PNGs
- Generate 4 new mockup PNGs under
app/assets/images/landing/using the same image-generation flow that produced the gamer-dashboard map. - Optimize for size (<200KB each).
Phase 4 — i18n cleanup
- Move all new section copy to
config/locales/pt-BR.ymlunderstatic.landing.*. - Refactor partial to read via
t().
Phase 5 — Polish & verification
- Confirm navbar anchors scroll to new sections.
- Confirm dark-mockup-on-light-section visual rhythm.
- Run
bin/ci.
Open Decisions
- Whether to anchor the Leaderboard CTA to
/leaderboardfor unauthenticated users (which forces a sign-in redirect) or to a teaser-only modal that previews the live data without exposing identities. Initial plan: link directly to/leaderboard; the sign-in flow is friction-light enough. - Whether the year heatmap should preview real data when a logged-in user visits the marketing page. Initial plan: no — landing page stays static and unauthenticated; logged-in users get redirected to
/dashboardbyauthenticated_rootanyway. - Whether to ship a small EN locale alongside PT-BR. Initial plan: not yet; the i18n cleanup makes it a one-PR follow-up.