10 KiB
Feature Specification: Redesign da Lista de Imóveis com Carrossel 3D
Feature Branch: 017-properties-list-3d-carousel
Created: 2026-04-16
Status: Draft
Input: Redesenhar a página /imoveis para exibir imóveis em linhas com carrossel 3D de fotos empilhadas em efeito fan/stack
User Scenarios & Testing (mandatory)
User Story 1 - Visualizar Lista de Imóveis com Cards em Linha (Priority: P1)
Um visitante acessa a página /imoveis e vê os imóveis dispostos em uma lista vertical de cards horizontais. Cada card ocupa a largura total disponível e exibe as informações principais ao lado de um carrossel 3D de fotos.
Why this priority: É a mudança central da feature — sem o novo layout de lista, todo o restante não existe. Entrega valor imediato ao usuário que busca escanear imóveis com mais informação visível por item.
Independent Test: Pode ser testado acessando /imoveis e verificando que os imóveis aparecem em linhas horizontais (não em grid), cada uma com altura ~260px no desktop, com foto à esquerda e informações à direita.
Acceptance Scenarios:
- Given o usuário acessa
/imoveis, When a página carrega, Then os imóveis são apresentados em uma lista vertical com cards horizontais de altura fixa ~260px no desktop. - Given o card está visível, When o usuário o visualiza, Then vê à esquerda um bloco de fotos (~320px de largura) e à direita as informações do imóvel ocupando o espaço restante.
- Given o usuário está em dispositivo móvel, When visualiza um card, Then o carrossel de fotos aparece acima e as informações aparecem abaixo (layout empilhado vertical).
- Given os imóveis estão carregando, When a requisição ainda não completou, Then um skeleton no formato de linha é exibido no lugar dos cards.
User Story 2 - Interagir com o Carrossel 3D de Fotos (Priority: P2)
Um visitante deseja ver diferentes fotos de um imóvel na listagem sem precisar entrar na página de detalhe. Ele clica nas fotos empilhadas atrás da principal para trazê-las à frente.
Why this priority: O carrossel 3D é o diferencial visual desta feature. Sem ele, os cards de linha seriam comuns; com ele, o usuário pode pré-visualizar fotos diretamente na listagem, reduzindo a necessidade de navegar para a página de detalhe.
Independent Test: Pode ser testado clicando em qualquer uma das fotos de fundo no carrossel de um card e verificando que a foto clicada passa para a posição frontal com animação suave.
Acceptance Scenarios:
- Given um card de imóvel está visível, When o usuário o carrega, Then exibe 3 fotos empilhadas em perspectiva 3D: a primeira na frente (posição destaque) e as demais levemente rotacionadas e deslocadas atrás.
- Given o carrossel exibe 3 fotos em stack, When o usuário clica em uma foto de fundo, Then ela é trazida para a posição frontal com animação de 300ms e as demais redistribuem-se para as posições de fundo.
- Given o imóvel possui menos de 3 fotos, When o carrossel é renderizado, Then as posições restantes são preenchidas com a última foto disponível ou com um placeholder visual.
- Given o imóvel possui 1 ou mais fotos, When o carrossel é renderizado, Then a animação de rotação ocorre apenas quando há mais de uma foto disponível.
User Story 3 - Visualizar Informações e Navegar para Detalhe do Imóvel (Priority: P2)
Um visitante vê as informações essenciais do imóvel diretamente no card da listagem e pode, a partir dele, navegar para a página de detalhe ou acionar a comparação.
Why this priority: O card precisa transmitir informação suficiente para o usuário decidir se vale a pena ver o detalhe completo, sem sobrecarregar visualmente o layout de lista.
Independent Test: Pode ser testado verificando que cada card exibe título, localização, badge de tipo, preço, stats e contém links/botões funcionais para detalhe e comparação.
Acceptance Scenarios:
- Given um card de imóvel está visível, When o usuário o vê, Then encontra: título do imóvel (até 2 linhas), bairro e cidade, badge Venda ou Aluguel, preço em destaque, e stats de quartos, banheiros, área m² e vagas.
- Given o usuário vê o card, When clica no título ou no link de detalhe, Then é redirecionado para a página de detalhe do imóvel.
- Given o usuário vê o card, When clica no botão "Comparar", Then o imóvel é adicionado à lista de comparação (comportamento existente mantido).
User Story 4 - Filtrar Imóveis com Sidebar Preservada (Priority: P1)
Um visitante usa os filtros da sidebar para refinar os resultados. O novo layout de lista deve preservar a sidebar e atualizar os cards de forma idêntica ao comportamento atual.
Why this priority: A sidebar de filtros é funcionalidade central da página /imoveis. Qualquer redesign que quebre os filtros compromete o fluxo de busca do usuário.
Independent Test: Pode ser testado aplicando filtros na sidebar e verificando que os cards em linha refletem corretamente os resultados filtrados.
Acceptance Scenarios:
- Given o usuário está na página
/imoveis, When visualiza o layout, Then a FilterSidebar permanece à esquerda com largura fixa (w-56) e os cards de linha ocupam o espaço restante à direita. - Given o usuário aplica um filtro na sidebar, When os resultados atualizam, Then os cards em linha exibem apenas os imóveis que correspondem aos filtros selecionados.
Edge Cases
- O que acontece quando um imóvel não possui nenhuma foto? → O carrossel exibe 3 placeholders visuais e a interação de clique fica desabilitada.
- O que acontece com a animação 3D em browsers sem suporte a
perspectiveCSS? → O carrossel exibe as fotos em layout flat (sem 3D) como fallback gracioso. - O que acontece quando a lista de imóveis retorna 0 resultados? → O estado vazio existente é exibido, adaptado para o novo layout de lista.
- O que acontece quando o usuário clica rapidamente em múltiplas fotos? → A animação de 300ms é respeitada; cliques durante a transição são enfileirados ou ignorados para evitar estados visuais inconsistentes.
- O que acontece com imóveis que possuem exatamente 1 foto? → A foto única ocupa a posição frontal; as 2 posições de fundo são preenchidas com a mesma foto ou placeholder.
Requirements (mandatory)
Functional Requirements
- FR-001: A página
/imoveisDEVE exibir imóveis em layout de lista vertical (linha por linha) ao invés do grid atual. - FR-002: Cada card DEVE ter altura fixa de ~260px no desktop e layout responsivo empilhado (foto acima, info abaixo) no mobile.
- FR-003: A seção de fotos de cada card DEVE ter largura fixa de ~320px no desktop e ocupar a largura total no mobile.
- FR-004: O carrossel 3D DEVE sempre exibir 3 fotos em efeito fan/stack com perspectiva CSS: a primeira na frente (translateZ maior, sem rotação), e as demais atrás (rotateY + translateX progressivos).
- FR-005: Clicar em uma foto de fundo DEVE trazê-la para a posição frontal com animação smooth de 300ms via CSS transition.
- FR-006: Imóveis com menos de 3 fotos DEVEM preencher as posições faltantes repetindo a última foto disponível ou exibindo placeholder visual neutro.
- FR-007: Cada card DEVE exibir: título do imóvel (máx. 2 linhas), bairro e cidade, badge de tipo (Venda/Aluguel), preço em destaque, número de quartos, banheiros, área m² e vagas de garagem.
- FR-008: Cada card DEVE conter botão "Comparar" e link de navegação para a página de detalhe do imóvel.
- FR-009: A FilterSidebar DEVE ser preservada com largura fixa à esquerda da lista de cards.
- FR-010: O skeleton de carregamento DEVE ser atualizado para refletir o formato de linha (retângulo largo com seção de foto à esquerda e barras de texto à direita).
- FR-011: A interação de clique no carrossel NÃO DEVE disparar navegação para a página de detalhe.
Key Entities
- PropertyCard: Representa um imóvel na listagem; contém dados de exibição (título, localização, preço, stats) e referência às fotos.
- PhotoCarousel3D: Componente visual do carrossel; gerencia o estado de qual foto está na posição frontal e as posições de fundo das demais.
- CarouselPhoto: Foto individual dentro do carrossel; possui posição (front/back-1/back-2) e índice de rotação 3D.
Success Criteria (mandatory)
Measurable Outcomes
- SC-001: A página
/imoveisexibe todos os imóveis no novo formato de lista sem perda de dados ou funcionalidade em relação ao layout anterior. - SC-002: A transição de fotos no carrossel é visualmente fluida e completa em até 300ms, sem saltos ou flickering.
- SC-003: O layout é totalmente utilizável em dispositivos móveis: foto e informações acessíveis sem scroll horizontal.
- SC-004: Os filtros da sidebar continuam funcionando corretamente — os resultados em lista refletem exatamente os critérios selecionados.
- SC-005: Cards com imóveis de 0, 1, 2 ou 3+ fotos são renderizados sem erros visuais ou de console.
- SC-006: O tempo de carregamento percebido pelo usuário não aumenta em relação ao layout de grid anterior (skeleton mantém a experiência progressiva).
Assumptions
- O componente
FilterSidebarexistente não precisa de alterações — somente o layout à direita é redesenhado. - As fotos dos imóveis já estão acessíveis via as propriedades existentes do modelo
Property(relaçãophotos). - O efeito 3D é implementado exclusivamente com CSS (
perspective,rotateY,translateZ,transition) sem bibliotecas externas de animação. - A funcionalidade de comparação (botão "Comparar") já existe e será reutilizada sem modificações de lógica.
- O comportamento de paginação ou scroll infinito existente é mantido sem alterações.
- O layout mobile usa breakpoint
mddo Tailwind CSS como ponto de corte entre desktop (horizontal) e mobile (empilhado). - Imóveis sem nenhuma foto recebem um placeholder visual genérico (ícone de câmera ou cor sólida) nas 3 posições do carrossel.