perf(movimento): uma transição, 3D leve e vídeo certo por aparelho

Passagens com fade e 32 px, cena anterior termina em opacidade 0, sem visibility nem clip-path. 3D do hero como fundo ambiente, sob demanda e desligado em toque, aparelho fraco, saveData e movimento reduzido. Lenis fora do toque e salto direto em âncoras distantes. Vitrine só de clientes, até 3 capítulos, fixa só no desktop e carrossel no celular; vídeo só do projeto em cena com preload metadata. Rótulos mono a partir de 12 px e limão só no contato.
This commit is contained in:
Evandro Fonseca Junior committed 2026-10-14 03:32:23 -03:00
1 parent 8d07b8c6bb
commit c9a0b80656
48 files changed
+7210 -1241

No files matched your search

@@ -177,7 +177,7 @@ describe("ProjectLightbox", () => {
);
expect(video.currentTime).toBeCloseTo(
chapterFraction(lavacao, 2, "desktop") * lavacao.durations.desktop,
chapterFraction(lavacao, 1, "desktop") * lavacao.durations.desktop,
5,
);
expect(
@@ -226,14 +226,72 @@ describe("ProjectLightbox", () => {
expect(screen.getByRole("dialog")).toHaveAccessibleName("SEV Moda Íntima");
});
it("offers the site and the code when they exist", () => {
it("offers the case and, when the site exists, a text link to it in a new tab; never the code", () => {
const dialog = setup("lavacao-047");
expect(
within(dialog).getByRole("link", { name: /Abrir projeto/ }),
).toHaveAttribute("href", "https://landing-page-lavacao047.vercel.app");
within(dialog).getByRole("link", { name: /Ver case/ }),
).toHaveAttribute("href", "/cases/lavacao-047");
const site = within(dialog).getByRole("link", { name: /Abrir site/ });
expect(site).toHaveAttribute(
"href",
"https://landing-page-lavacao047.vercel.app",
);
expect(site).toHaveAttribute("target", "_blank");
expect(site).toHaveClass("ds-link-text");
expect(dialog.querySelector(".ds-link-accent")).toBeNull();
expect(within(dialog).queryByRole("link", { name: /código/i })).toBeNull();
expect(dialog.innerHTML).not.toContain("github.com");
});
it("has no site link, and an address bar with only the project name, for a project without a live site", () => {
const dialog = setup("as-servicos");
expect(
within(dialog).queryByRole("link", { name: /Ver codigo/ }),
within(dialog).queryByRole("link", { name: /Abrir site/ }),
).toBeNull();
expect(
within(dialog).getByRole("link", { name: /Ver case/ }),
).toHaveAttribute("href", "/cases/as-servicos");
expect(dialog.querySelector(".ds-bframe-url")?.textContent).toBe(
"AS Serviços",
);
});
it("opens on the phone version below 768 px", () => {
const original = window.matchMedia;
window.matchMedia = jest.fn().mockImplementation((query: string) => ({
matches: query === "(max-width: 767px)",
media: query,
addEventListener() {},
removeEventListener() {},
}));
try {
const dialog = setup();
expect(
within(dialog).getByRole("button", { name: "Celular" }),
).toHaveAttribute("aria-pressed", "true");
expect(dialog.querySelector(".ds-lb-phone")).not.toBeNull();
} finally {
window.matchMedia = original;
}
});
it("does not autoplay, nor preload the whole file, with the data saver on", () => {
Object.defineProperty(navigator, "connection", {
configurable: true,
value: { saveData: true },
});
try {
const dialog = setup();
const video = dialog.querySelector("video") as HTMLVideoElement;
expect(video).not.toHaveAttribute("autoplay");
expect(video).toHaveAttribute("preload", "metadata");
expect(HTMLMediaElement.prototype.play).not.toHaveBeenCalled();
} finally {
Object.defineProperty(navigator, "connection", {
configurable: true,
value: undefined,
});
}
});
it("closes with the close button, with the backdrop or with Esc, and unlocks the page", () => {