feat(site): blocos 3D da marca, novas ofertas e hero mais abrangente
Hero e movimento - cena 3D em tempo real com os blocos da marca (kit feito no Blender, 3d/blocos.py): marca, tela, integrações e dados; segue a rolagem, tem vida em repouso, reage ao cursor e, parada no topo, passa sozinha pelos estados com legenda - três níveis de aparelho (full, lite, static); sem WebGL fica o pôster - título novo: "Sites e sistemas sob medida para o jeito que a sua empresa trabalha." - faixa de clientes com o ramo, linha do primeiro passo, hero alinhado às seções - rótulos digitados, entrada dos blocos, cortina de blocos entre páginas e capa compartilhada entre a lista de cases e o case Ofertas - atendimento no WhatsApp com IA e nota fiscal para a reforma tributária (páginas de serviço, cartões da home, formulário e aviso com data de validade) - página /ia atualizada, com fontes - peças 3D em loop nos cartões e topos de página (3d/pecas.py) Design - hover por papel (bloco nos botões, barra nos links), rótulos sem caixa alta - um destino por rótulo: "Falar sobre meu projeto" leva ao formulário, "Chamar no WhatsApp" abre o WhatsApp - logo montado em blocos, 404 redesenhado, grades sem célula vazia - ícones do PWA e manifesto novos Specs em specs/, contexto de design em DESIGN.md e PRODUCT.md.
This commit is contained in:
1 parent
4671837c44
commit
c7d09d63d4
165 files changed
+7940
-3790
No files matched your search
@@ -1,9 +1,9 @@
|
||||
import { render, screen, within } from "@testing-library/react";
|
||||
import { render, screen } from "@testing-library/react";
|
||||
import HeroWork from "./HeroWork";
|
||||
|
||||
/**
|
||||
* Os pôsteres do hero: pelo next/image com `sizes` do tamanho em que aparecem, sempre lazy e com prioridade baixa
|
||||
* (o título é o LCP), e o cartão largo e clicável da SEV para as telas abaixo de 1024 px.
|
||||
* O pôster do hero: pelo next/image com `sizes` do tamanho em que aparece, lazy e com prioridade baixa (o título é o
|
||||
* LCP), no cartão largo e clicável da SEV para as telas abaixo de 1024 px. Em tela larga a coluna é da peça 3D.
|
||||
*/
|
||||
|
||||
const original = (image: Element) =>
|
||||
@@ -12,23 +12,9 @@ const original = (image: Element) =>
|
||||
);
|
||||
|
||||
describe("HeroWork: pôsteres no tamanho certo", () => {
|
||||
it("serves the three posters through the image optimizer, each with a `sizes` that matches how it shows", () => {
|
||||
it("serves the SEV poster through the image optimizer, with a `sizes` that matches how it shows", () => {
|
||||
render(<HeroWork />);
|
||||
|
||||
const desktop = within(screen.getByTestId("hero-work")).getAllByRole("img");
|
||||
expect(desktop).toHaveLength(2);
|
||||
expect(original(desktop[0])).toBe("/videos/lavacao-047/desktop.webp");
|
||||
expect(original(desktop[1])).toBe("/videos/as-servicos/mobile.webp");
|
||||
// 1440x900 e 390x844 cheios para quadros de ~491x307 e ~130x299 era banda de sobra
|
||||
expect(desktop[0]).toHaveAttribute(
|
||||
"sizes",
|
||||
"(min-width: 1400px) 500px, 36vw",
|
||||
);
|
||||
expect(desktop[1]).toHaveAttribute(
|
||||
"sizes",
|
||||
"(min-width: 1400px) 136px, 10vw",
|
||||
);
|
||||
|
||||
// o cartão do celular usa o pôster de celular da SEV (o título em letras grandes cabe na faixa de 72 px), na largura
|
||||
// da coluna (a tela menos as duas margens: cerca de 342 px num celular de 390 px), e não 100vw
|
||||
const small = screen
|
||||
@@ -55,23 +41,11 @@ describe("HeroWork: pôsteres no tamanho certo", () => {
|
||||
expect((small.parentElement as HTMLElement).style.height).toBe("72px");
|
||||
});
|
||||
|
||||
it("keeps the dimensions of the files, so the frames reserve their space before the images load", () => {
|
||||
render(<HeroWork />);
|
||||
|
||||
const [browser, phone] = within(
|
||||
screen.getByTestId("hero-work"),
|
||||
).getAllByRole("img");
|
||||
expect(browser).toHaveAttribute("width", "1440");
|
||||
expect(browser).toHaveAttribute("height", "900");
|
||||
expect(phone).toHaveAttribute("width", "390");
|
||||
expect(phone).toHaveAttribute("height", "844");
|
||||
});
|
||||
|
||||
it("never asks for a high priority: lazy, low fetch priority and no preload, so the headline stays the LCP", () => {
|
||||
const { container } = render(<HeroWork />);
|
||||
|
||||
const images = container.querySelectorAll("img");
|
||||
expect(images).toHaveLength(3);
|
||||
expect(images).toHaveLength(1);
|
||||
for (const image of images) {
|
||||
expect(image).toHaveAttribute("loading", "lazy");
|
||||
expect(image).toHaveAttribute("fetchpriority", "low");
|
||||
@@ -82,13 +56,12 @@ describe("HeroWork: pôsteres no tamanho certo", () => {
|
||||
});
|
||||
|
||||
describe("HeroWork: cartão do celular", () => {
|
||||
it("shows a wide card with the SEV poster only below 1024px, while the column stays desktop-only", () => {
|
||||
render(<HeroWork />);
|
||||
|
||||
const column = screen.getByTestId("hero-work");
|
||||
expect(column).toHaveClass("hidden", "lg:block");
|
||||
it("is the whole component: a wide card with the SEV poster, only below 1024px", () => {
|
||||
const { container } = render(<HeroWork />);
|
||||
|
||||
const card = screen.getByTestId("hero-work-mobile");
|
||||
expect(container.firstChild).toBe(card);
|
||||
expect(container.childElementCount).toBe(1);
|
||||
expect(card).toHaveClass("lg:hidden", "w-full");
|
||||
// sem a moldura de celular de 65x160 px: a imagem é larga e ocupa a coluna inteira
|
||||
expect(card.querySelector(".ds-phone")).toBeNull();
|
||||
@@ -119,21 +92,4 @@ describe("HeroWork: cartão do celular", () => {
|
||||
|
||||
expect(screen.getAllByRole("link")).toHaveLength(1);
|
||||
});
|
||||
|
||||
it("keeps the desktop column as a plain picture: not interactive, nothing to click", () => {
|
||||
render(<HeroWork />);
|
||||
|
||||
expect(screen.getByTestId("hero-work")).toHaveClass("pointer-events-none");
|
||||
expect(
|
||||
within(screen.getByTestId("hero-work")).queryByRole("link"),
|
||||
).toBeNull();
|
||||
});
|
||||
|
||||
it("passes the address to the browser bar of the desktop frame", () => {
|
||||
render(<HeroWork url={{ text: "sevmodaintima.com.br", secure: true }} />);
|
||||
|
||||
expect(
|
||||
within(screen.getByTestId("hero-work")).getByText("sevmodaintima.com.br"),
|
||||
).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
Reference in new issue
Block a user