Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 14 additions & 3 deletions src/app/__tests__/home-conversion.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@ vi.mock("@/lib/analytics", () => ({
const SECTION_ORDER = [
"hero-heading",
"problem-solution-heading",
"ownership-heading",
"routing-heading",
"handoff-heading",
"how-it-works-hub-heading",
"whatsapp-product-heading",
"faq-heading",
Expand Down Expand Up @@ -69,15 +72,23 @@ describe("home conversion cleanup", () => {

expect(text).toContain("Dados ilustrativos");
expect(text).toContain("Demonstração da plataforma");
expect(text).toContain("Quer entender como isso funcionaria na sua operação?");
expect(text).not.toContain("SLA");
expect(text).not.toContain("dashboard operacional");
expect(text).not.toContain("Próximo produto");
expect(text).not.toContain("Quero saber");
expect(text).toContain("API oficial da Meta");
expect(text).toContain("Inbox multiatendente");
expect(text).toContain("Responsáveis e filas");
expect(text).toContain("Handoff humano");
expect(text).toContain("Quer entender como essa operação funcionaria na sua empresa?");
expect(screen.getByRole("heading", { name: "O que entra na operação" })).toBeTruthy();
expect(screen.getByRole("heading", { name: "Como sua operação de WhatsApp sai do improviso" })).toBeTruthy();
expect(screen.getByRole("heading", { name: "Perguntas frequentes" })).toBeTruthy();
});

it("separa CTA primário, demo e WhatsApp no hero", () => {
render(<Home />);
const hero = screen.getByRole("region", { name: /Menos mensagem perdida/i });
const hero = screen.getByRole("region", { name: /Organize cada conversa/i });

const primary = within(hero).getByRole("link", {
name: "Agendar diagnóstico da operação no WhatsApp",
Expand Down Expand Up @@ -115,7 +126,7 @@ describe("home conversion cleanup", () => {
it("mantém o CTA final imediatamente relevante e rastreado", () => {
render(<Home />);
const finalCta = screen.getByRole("region", {
name: "Quer entender como isso funcionaria na sua operação?",
name: "Quer entender como essa operação funcionaria na sua empresa?",
});

const primary = within(finalCta).getByRole("link", {
Expand Down
16 changes: 6 additions & 10 deletions src/app/contato/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ const baseUrl = "https://devflowlabs.com.br";
const ogImage = `${baseUrl}/og-devflow.png`;

const contactDescription =
"Solicite um diagnóstico da sua operação de atendimento e vendas no WhatsApp. Mapeamos gargalos, automações possíveis, handoff humano, SLA e dashboard operacional.";
"Solicite um diagnóstico da sua operação de atendimento e vendas no WhatsApp. Mapeamos gargalos, automações possíveis, handoff humano, fila e responsáveis.";

export const metadata: Metadata = {
title: "Agendar Diagnóstico WhatsApp | DevFlow Labs",
Expand Down Expand Up @@ -52,11 +52,7 @@ const sidebarCard =

export default function ContatoPage() {
return (
<main className="relative overflow-hidden">
<div className="pointer-events-none absolute inset-0 -z-10 opacity-40" aria-hidden>
<div className="df-decor-radial-brand-soft absolute -top-40 right-0 h-96 w-96 rounded-full blur-3xl" />
<div className="df-decor-radial-ink-soft absolute -bottom-32 left-0 h-80 w-80 rounded-full blur-3xl" />
</div>
<main className="df-brand-v2 relative">

<div className="mx-auto max-w-[1200px] px-4 py-16 sm:px-6 sm:py-20 lg:px-8 lg:py-24">
<header className="mx-auto max-w-3xl text-center">
Expand All @@ -68,7 +64,7 @@ export default function ContatoPage() {
</h1>
<p className="df-text-secondary mx-auto mt-4 max-w-2xl text-base leading-relaxed sm:text-lg">
Entenda onde sua operação perde mensagens, tempo e vendas — e veja como organizar atendimento com IA,
humano e dashboard.
responsáveis e handoff humano.
</p>
</header>

Expand Down Expand Up @@ -118,7 +114,7 @@ export default function ContatoPage() {
<Link href="/demo" className="font-semibold text-primary underline-offset-2 hover:underline">
{PRIMARY_DEMO_CTA_LABEL}
</Link>{" "}
mostra fila, handoff e dashboard em poucos minutos.
mostra fila, responsáveis e handoff em poucos minutos.
</p>
<Link
href="/demo"
Expand All @@ -135,8 +131,8 @@ export default function ContatoPage() {
</div>

<p className="df-text-secondary mx-auto mt-10 max-w-xl text-center text-xs font-medium leading-relaxed sm:text-sm">
Diagnóstico consultivo focado em atendimento e vendas no WhatsApp — IA no repetitivo, handoff humano, SLA e
dashboard operacional.
Diagnóstico consultivo focado em atendimento e vendas no WhatsApp — IA no repetitivo, handoff humano, fila e
responsáveis.
</p>

<p className="mt-10 text-center">
Expand Down
183 changes: 183 additions & 0 deletions src/app/globals.css
Original file line number Diff line number Diff line change
Expand Up @@ -648,4 +648,187 @@ html[data-theme="client_branded"] {
.df-shadow-cta-soft:hover {
box-shadow: 0 6px 22px rgba(0, 208, 132, 0.42);
}
}

/* Brand V2 — scoped. Does not restyle ApplyFlow, Financeiro or WhatsApp apps. */
.df-brand-v2 {
background: var(--df-v2-canvas);
color: var(--df-v2-ink);
--df-text-primary-current: var(--df-v2-ink);
--df-text-secondary-current: var(--df-v2-ink-soft);
--df-text-muted-current: var(--df-v2-muted);
--df-link-current: var(--df-v2-brand);
--df-link-hover-current: var(--df-v2-brand-hover);
--background: var(--df-v2-canvas);
--foreground: var(--df-v2-ink);
--card: var(--df-v2-surface);
--card-foreground: var(--df-v2-ink);
--primary: var(--df-v2-brand);
--primary-foreground: #ffffff;
--muted: var(--df-v2-surface-muted);
--muted-foreground: var(--df-v2-muted);
--border: var(--df-v2-border);
font-family: var(--font-inter), ui-sans-serif, system-ui, sans-serif;
}

.df-brand-v2 h1,
.df-brand-v2 h2,
.df-brand-v2 h3,
.df-header-v2 {
font-family: var(--font-manrope), var(--font-inter), ui-sans-serif, system-ui, sans-serif;
}

.df-v2-container {
width: min(100% - 2rem, var(--df-v2-container));
margin-inline: auto;
}

.df-v2-section {
padding-block: 4rem;
}

@media (min-width: 1024px) {
.df-v2-section {
padding-block: 6.5rem;
}
}

.df-brand-v2 .df-v2-h1 {
font-size: clamp(2.5rem, 4.6vw, 4.25rem);
font-weight: 800;
line-height: 1.02;
letter-spacing: -0.035em;
color: var(--df-v2-ink);
}

.df-brand-v2 .df-v2-h2 {
font-size: clamp(1.875rem, 3vw, 3rem);
font-weight: 700;
line-height: 1.08;
letter-spacing: -0.03em;
color: var(--df-v2-ink);
}

.df-brand-v2 .df-v2-h3 {
font-size: clamp(1.3125rem, 1.6vw, 1.625rem);
font-weight: 700;
line-height: 1.2;
letter-spacing: -0.02em;
color: var(--df-v2-ink);
}

.df-brand-v2 .df-v2-lead {
font-size: 1.125rem;
line-height: 1.6;
color: var(--df-v2-ink-soft);
}

@media (min-width: 1024px) {
.df-brand-v2 .df-v2-lead {
font-size: 1.25rem;
}
}

.df-brand-v2 .df-btn-primary,
.df-header-v2 .df-btn-primary {
border-radius: var(--df-v2-radius-btn);
background: var(--df-v2-brand);
color: #ffffff;
box-shadow: none;
}

.df-brand-v2 .df-btn-primary:hover,
.df-header-v2 .df-btn-primary:hover {
background: var(--df-v2-brand-hover);
transform: none;
}

.df-brand-v2 .df-btn-secondary,
.df-header-v2 .df-btn-secondary {
border-radius: var(--df-v2-radius-btn);
border-color: var(--df-v2-border-strong);
background: var(--df-v2-surface);
color: var(--df-v2-ink);
}

.df-brand-v2 .df-btn-secondary:hover,
.df-header-v2 .df-btn-secondary:hover {
background: var(--df-v2-surface-muted);
}

.df-brand-v2 .df-btn-primary:focus-visible,
.df-brand-v2 .df-btn-secondary:focus-visible,
.df-header-v2 .df-btn-primary:focus-visible,
.df-header-v2 .df-btn-secondary:focus-visible,
.df-brand-v2 a:focus-visible,
.df-header-v2 a:focus-visible,
.df-brand-v2 summary:focus-visible {
outline: none;
box-shadow: 0 0 0 2px var(--df-v2-canvas), 0 0 0 4px var(--df-v2-brand);
}

.df-v2-fill {
background: var(--df-v2-surface);
}

.df-v2-panel {
border-radius: var(--df-v2-radius-panel);
border: 1px solid var(--df-v2-border);
background: var(--df-v2-surface);
box-shadow: var(--df-v2-shadow-panel);
}

.df-v2-dark {
background: var(--df-v2-dark);
color: var(--df-v2-on-dark);
--df-text-primary-current: var(--df-v2-on-dark);
--df-text-secondary-current: var(--df-v2-on-dark-muted);
--df-text-muted-current: var(--df-v2-on-dark-muted);
}

.df-v2-dark .df-v2-h2 {
color: var(--df-v2-on-dark);
}

.df-v2-dark .df-btn-secondary {
border-color: rgba(244, 247, 246, 0.28);
background: transparent;
color: var(--df-v2-on-dark);
}

.df-v2-dark .df-btn-secondary:hover {
background: rgba(244, 247, 246, 0.08);
}

.df-header-v2 {
background: rgba(247, 250, 249, 0.94);
border-color: var(--df-v2-border);
color: var(--df-v2-ink);
box-shadow: none;
--df-text-primary-current: var(--df-v2-ink);
--df-text-secondary-current: var(--df-v2-ink-soft);
--foreground: var(--df-v2-ink);
--background: var(--df-v2-canvas);
--border: var(--df-v2-border);
--primary: var(--df-v2-brand);
}

.df-v2-timeline {
display: grid;
gap: 0;
}

@media (min-width: 1024px) {
.df-v2-timeline {
grid-template-columns: repeat(4, minmax(0, 1fr));
}
}

@media (prefers-reduced-motion: reduce) {
.df-brand-v2 *,
.df-header-v2 * {
scroll-behavior: auto !important;
transition-duration: 0.01ms !important;
animation-duration: 0.01ms !important;
}
}
11 changes: 9 additions & 2 deletions src/app/layout.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type { Metadata } from "next";
import { Inter } from "next/font/google";
import { Inter, Manrope } from "next/font/google";
import { BodyChrome } from "@/components/layout/body-chrome";
import { Analytics } from "@vercel/analytics/next";
import { MetaPixel } from "@/components/analytics/meta-pixel";
Expand All @@ -11,6 +11,13 @@ const inter = Inter({
display: "swap",
});

const manrope = Manrope({
variable: "--font-manrope",
subsets: ["latin"],
display: "swap",
weight: ["600", "700", "800"],
});

const baseUrl = "https://devflowlabs.com.br";

export const metadata: Metadata = {
Expand Down Expand Up @@ -89,7 +96,7 @@ export default function RootLayout({
return (
<html lang="pt-BR" data-theme={themeMode}>
<body
className={`${inter.variable} df-page font-sans flex min-h-screen flex-col antialiased`}
className={`${inter.variable} ${manrope.variable} df-page font-sans flex min-h-screen flex-col antialiased`}
>
<script
type="application/ld+json"
Expand Down
11 changes: 8 additions & 3 deletions src/app/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { ScrollTracker } from "@/components/shared/scroll-tracker";
import { HeroV2 } from "@/components/sections/hero-v2";
import { TechnicalTrustStrip } from "@/components/sections/technical-trust-strip";
import { ProblemSolutionSection } from "@/components/sections/problem-solution-section";
import { ProductStories } from "@/components/sections/product-stories";
import { HowItWorksHub } from "@/components/sections/how-it-works-hub";
import { WhatsAppProductSection } from "@/components/sections/whatsapp-product-section";
import { Faq } from "@/components/sections/faq";
Expand All @@ -19,7 +20,7 @@ const ogImage = `${baseUrl}/og-devflow.png`;

const homeTitle = "DevFlow Labs | Automação WhatsApp com IA, Inbox e Handoff Humano";
const homeDescription =
"Transforme seu WhatsApp em uma operação previsível de atendimento e vendas com IA no repetitivo, inbox multiatendente, handoff humano, SLA e dashboard operacional.";
"Transforme seu WhatsApp em uma operação de atendimento e vendas com inbox compartilhada, responsáveis, filas e handoff humano.";

export const metadata: Metadata = {
title: homeTitle,
Expand All @@ -36,8 +37,8 @@ export const metadata: Metadata = {
"WhatsApp Cloud API",
"chatbot WhatsApp",
"handoff humano",
"SLA atendimento",
"dashboard atendimento",
"fila de atendimento",
"inbox compartilhada",
],
openGraph: {
type: "website",
Expand Down Expand Up @@ -77,12 +78,15 @@ export default function Home() {
<>
<ScrollTracker />

<main className="df-brand-v2">
<HeroV2 />

<TechnicalTrustStrip />

<ProblemSolutionSection />

<ProductStories />

<HowItWorksHub />

<WhatsAppProductSection />
Expand All @@ -96,6 +100,7 @@ export default function Home() {

<ProductsSection />
</HomeEcosystemStack>
</main>
</>
);
}
Loading
Loading