142 lines
12 KiB
Markdown
142 lines
12 KiB
Markdown
# Feature Specification: Homepage Imersiva com Scroll — Hero + Destaque de Imóveis
|
|
|
|
**Feature Branch**: `018-homepage-scroll-hero`
|
|
**Created**: 2026-04-17
|
|
**Status**: Draft
|
|
**Input**: User description: "Homepage imersiva com scroll — hero + imagem de fundo + destaque de imóveis"
|
|
|
|
## User Scenarios & Testing *(mandatory)*
|
|
|
|
### User Story 1 — Visitante visualiza a hero fullscreen ao acessar a homepage (Priority: P1)
|
|
|
|
Ao entrar na homepage, o visitante vê uma imagem de fundo ocupando 100% da altura da tela com o texto principal (headline, subheadline e CTA) centralizado por cima. Um overlay semitransparente escuro garante que o texto branco seja legível independente da imagem usada.
|
|
|
|
**Why this priority**: É a primeira impressão do produto. Sem isso, toda a experiência de scroll não existe.
|
|
|
|
**Independent Test**: Pode ser testado acessando a homepage com e sem `hero_image_url` configurado no painel. Valor entregue: apresentação visual impactante imediata.
|
|
|
|
**Acceptance Scenarios**:
|
|
|
|
1. **Given** o administrador configurou `hero_image_url` no HomepageConfig, **When** um visitante acessa a homepage, **Then** a imagem aparece como fundo fullscreen (100vh), com overlay escuro semitransparente e o texto (headline, subheadline, CTA) centralizado sobre ela em cor branca.
|
|
2. **Given** `hero_image_url` não está configurado, **When** um visitante acessa a homepage, **Then** uma imagem padrão do sistema é exibida como fundo, mantendo o mesmo layout e legibilidade.
|
|
3. **Given** o visitante acessa a homepage em dispositivo móvel, **When** a página carrega, **Then** a imagem de fundo cobre 100% da altura da viewport sem distorção ou corte indesejado.
|
|
|
|
---
|
|
|
|
### User Story 2 — Visitante rola a tela e os cards de imóveis emergem sobre o hero (Priority: P1)
|
|
|
|
Ao começar a rolar a página para baixo, a imagem hero permanece "presa" (sticky) na tela enquanto os cards de imóveis em destaque sobem por cima dela, criando a sensação de que os imóveis emergem da cena. Cada card aparece com animação suave ao entrar no viewport.
|
|
|
|
**Why this priority**: É a interação central da feature — sem o scroll sticky + cards animados, a experiência imersiva não existe.
|
|
|
|
**Independent Test**: Pode ser testado rolando a página com imóveis em destaque cadastrados. Valor entregue: diferenciação visual clara da homepage.
|
|
|
|
**Acceptance Scenarios**:
|
|
|
|
1. **Given** o visitante está na homepage com imóveis em destaque cadastrados, **When** rola a tela para baixo, **Then** a imagem hero permanece visível e fixa enquanto a lista de cards sobe por cima dela.
|
|
2. **Given** os cards estão fora do viewport inicial, **When** cada card entra na área visível da tela durante o scroll, **Then** ele aparece com animação de `opacity 0→1` combinada com `translateY(48px→0)`, com stagger de 60ms entre os cards.
|
|
3. **Given** não há imóveis em destaque cadastrados, **When** o visitante acessa a homepage, **Then** a seção de cards não é exibida e a experiência de sticky hero ainda funciona normalmente.
|
|
|
|
---
|
|
|
|
### User Story 3 — Indicador visual guia o visitante a rolar a tela (Priority: P2)
|
|
|
|
Enquanto a imagem hero está visível na tela, um indicador de "Role para ver os destaques" aparece com três chevrons animados em cascata, incentivando o visitante a rolar.
|
|
|
|
**Why this priority**: Melhora a usabilidade e descoberta, mas a feature principal funciona sem ele.
|
|
|
|
**Independent Test**: Pode ser testado verificando a presença e visibilidade do indicador enquanto o hero está visível, e sua ausência após o scroll. Valor entregue: orientação visual ao usuário.
|
|
|
|
**Acceptance Scenarios**:
|
|
|
|
1. **Given** o visitante está na homepage com a imagem hero visível, **When** a página carrega, **Then** aparece a mensagem "Role para ver os destaques" com 3 chevrons animados em cascata (animação encadeada, não simultânea).
|
|
2. **Given** o indicador está visível, **When** o visitante rola até a imagem hero sair completamente do viewport, **Then** o indicador desaparece ou some com transição suave.
|
|
|
|
---
|
|
|
|
### User Story 4 — Visitante é redirecionado automaticamente para a listagem completa ao fim dos destaques (Priority: P2)
|
|
|
|
Ao chegar ao fim da lista de imóveis em destaque, o visitante é automaticamente levado para a página de listagem completa (`/imoveis`) após uma breve pausa, com um overlay de transição visual.
|
|
|
|
**Why this priority**: Cria um fluxo contínuo e natural entre a homepage e o catálogo, mas não bloqueia as funcionalidades principais.
|
|
|
|
**Independent Test**: Pode ser testado chegando ao fim dos cards e aguardando o redirecionamento. Valor entregue: redução de fricção no funil de aquisição.
|
|
|
|
**Acceptance Scenarios**:
|
|
|
|
1. **Given** o visitante rolou até o fim da lista de destaques, **When** o marcador invisível ao fim da lista fica 100% visível no viewport, **Then** após 800ms o visitante é redirecionado para `/imoveis` com overlay de transição (blur + spinner).
|
|
2. **Given** o redirecionamento foi acionado, **When** o overlay de transição aparece, **Then** a tela exibe um efeito de blur sobre o conteúdo atual e um spinner indicando carregamento.
|
|
3. **Given** o visitante não chegou ao fim da lista, **When** rola para cima novamente, **Then** nenhum redirecionamento é acionado.
|
|
|
|
---
|
|
|
|
### User Story 5 — Administrador configura a imagem de fundo do hero (Priority: P3)
|
|
|
|
O administrador pode definir a URL da imagem de fundo do hero através do painel de configuração da homepage, persistindo a informação no backend.
|
|
|
|
**Why this priority**: Permite customização, mas a homepage funciona com imagem padrão enquanto não configurada.
|
|
|
|
**Independent Test**: Pode ser testado salvando uma URL de imagem no painel e verificando que ela aparece na homepage. Valor entregue: controle editorial da vitrine principal.
|
|
|
|
**Acceptance Scenarios**:
|
|
|
|
1. **Given** o administrador acessa o painel de configuração da homepage, **When** informa uma URL válida no campo de imagem do hero e salva, **Then** a homepage passa a exibir essa imagem como fundo.
|
|
2. **Given** o administrador informa uma URL inválida ou vazia, **When** salva, **Then** o sistema usa a imagem padrão e não exibe erro ao visitante.
|
|
3. **Given** a configuração foi salva, **When** a API de configuração da homepage é consultada, **Then** o campo `hero_image_url` aparece na resposta com o valor configurado.
|
|
|
|
---
|
|
|
|
### Edge Cases
|
|
|
|
- O que acontece quando a URL da `hero_image_url` aponta para uma imagem que não carrega (404, timeout)? → A imagem padrão deve ser exibida como fallback.
|
|
- O que acontece quando há apenas 1 imóvel em destaque? → A animação e o scroll redirect devem funcionar normalmente.
|
|
- O que acontece quando o visitante tem preferência por `prefers-reduced-motion`? → As animações de entrada dos cards e dos chevrons devem ser suprimidas ou substituídas por transições simples de opacidade.
|
|
- O que acontece quando `hero_image_url` é uma string vazia (`""`)?→ Tratada como `null`, usando a imagem padrão.
|
|
- O que acontece quando o usuário rola rapidamente até o fim antes das animações terminarem? → Os cards já visíveis devem aparecer sem aguardar o stagger completo; o redirecionamento dispara normalmente.
|
|
|
|
## Requirements *(mandatory)*
|
|
|
|
### Functional Requirements
|
|
|
|
- **FR-001**: O sistema DEVE exibir a seção hero ocupando 100% da altura do viewport (100vh) ao carregar a homepage.
|
|
- **FR-002**: O sistema DEVE exibir um overlay escuro semitransparente sobre a imagem do hero para garantir legibilidade do texto branco.
|
|
- **FR-003**: O sistema DEVE exibir headline, subheadline e CTA configuráveis (via `HomepageConfig`) centralizados sobre o hero.
|
|
- **FR-004**: O sistema DEVE usar `hero_image_url` da configuração como imagem de fundo do hero quando disponível, e uma imagem padrão quando não configurado ou inválido.
|
|
- **FR-005**: O sistema DEVE manter a imagem hero "sticky" durante o scroll enquanto os cards de imóveis sobem por cima dela.
|
|
- **FR-006**: O sistema DEVE exibir os imóveis em destaque como cards em layout de linha horizontal (`PropertyRowCard`).
|
|
- **FR-007**: Cada card de imóvel em destaque DEVE ter animação de entrada (`opacity 0→1` + `translateY 48px→0`) ativada por `IntersectionObserver` com `threshold 0.05` quando o card entra no viewport.
|
|
- **FR-008**: O stagger entre animações de cards consecutivos DEVE ser de 60ms.
|
|
- **FR-009**: O sistema DEVE exibir um indicador "Role para ver os destaques" com 3 chevrons animados em cascata enquanto o hero estiver visível.
|
|
- **FR-010**: O sistema DEVE ocultar o indicador de scroll quando a imagem hero sair do viewport.
|
|
- **FR-011**: O sistema DEVE redirecionar automaticamente para `/imoveis` após 800ms quando um marcador invisível ao fim da lista de cards estiver 100% visível no viewport (`IntersectionObserver`, `threshold 1.0`).
|
|
- **FR-012**: O redirecionamento DEVE ser acompanhado por um overlay de transição (blur + spinner) antes de navegar.
|
|
- **FR-013**: A tabela `homepage_config` no banco de dados DEVE receber a nova coluna `hero_image_url` (texto de até 512 caracteres, opcional/nullable) via migration Alembic.
|
|
- **FR-014**: A API `GET /homepage-config` DEVE incluir o campo `hero_image_url` na resposta.
|
|
- **FR-015**: O sistema DEVE respeitar `prefers-reduced-motion` suprimindo ou simplificando animações de entrada para usuários que assim preferirem.
|
|
|
|
### Key Entities
|
|
|
|
- **HomepageConfig**: Registro único de configuração da homepage. Passa a incluir `hero_image_url` (URL da imagem de fundo do hero, opcional). Demais campos existentes (headline, subheadline, CTA) permanecem inalterados.
|
|
- **FeaturedProperty** (imóvel em destaque): Imóvel marcado para aparecer na seção de destaques da homepage. Sem alteração de modelo; apenas o modo de exibição muda.
|
|
|
|
## Success Criteria *(mandatory)*
|
|
|
|
### Measurable Outcomes
|
|
|
|
- **SC-001**: O tempo de carregamento inicial da homepage (até a imagem hero ser visível) não ultrapassa 3 segundos em conexões padrão.
|
|
- **SC-002**: 100% dos imóveis em destaque exibem animação de entrada ao entrar no viewport durante o scroll.
|
|
- **SC-003**: O redirecionamento automático para `/imoveis` ocorre dentro de 800ms (±100ms) a partir do momento em que o marcador final é 100% visível.
|
|
- **SC-004**: A imagem padrão é exibida corretamente em 100% dos acessos onde `hero_image_url` não está configurado ou não carrega.
|
|
- **SC-005**: A experiência de scroll sticky funciona corretamente nos navegadores modernos (Chrome, Firefox, Safari, Edge — versões dos últimos 2 anos).
|
|
- **SC-006**: Em dispositivos com `prefers-reduced-motion` ativado, nenhuma animação de movimento (translateY, chevron cascade) é executada.
|
|
|
|
## Assumptions
|
|
|
|
- O componente `HomeScrollScene.tsx` já existe no codebase mas ainda sem integração completa com o hero text — a spec assume que ele será refatorado para receber todo o conteúdo (hero + lista) como uma única unidade.
|
|
- O `PropertyRowCard` já existe e está funcional; a spec não envolve alteração em seu layout interno.
|
|
- A imagem padrão do sistema está disponível como asset estático no frontend.
|
|
- O painel de administração já possui interface para editar configurações da `HomepageConfig`; a adição do campo `hero_image_url` segue o mesmo padrão já existente.
|
|
- O endpoint `GET /homepage-config` já existe; a mudança é apenas aditiva (novo campo na resposta).
|
|
- Os imóveis em destaque já são retornados por uma rota existente; não é necessário criar um novo endpoint.
|
|
- A administração de `hero_image_url` é feita informando uma URL externa ou um path de asset já hospedado (upload de imagem está fora do escopo desta feature).
|
|
- A migration Alembic será executada como parte do processo de deploy padrão do projeto.
|