Disponível para novos projetos

Ezequiel Regino Monção

Desenvolvedor Full-Stack & Designer

Projetos digitais de ponta a ponta: sites, painéis CMS e aplicações sob medida com performance, acessibilidade e design que convertem.

React, Next.js, TypeScript, Node.js, .NET, Angular, PHP, Laravel, SQL Server, Firebase, Docker, Git, Figma, SEO, UX/UI, WCAG

Trabalhos e aplicações

Ferramentas que crio, uso e estão no ar

Uma amostra de produtos em produção — para clientes e de uso próprio — todos com a mesma base técnica.

Para clientes

Sites Institucionais — Institutional Sites
WEB

Sites Institucionais

Sites rápidos, acessíveis e fáceis de atualizar — com CMS próprio para o cliente editar sem depender de ninguém.

  • SEO e desempenho desde o primeiro commit
  • Editor visual de conteúdo
  • Totalmente responsivo
  • Multi-idioma (pt/en/es)
Ver site
Painel CMS Multi-Site — Multi-Site CMS Panel
CMS

Painel CMS Multi-Site

Um painel para gerenciar hero, sobre, portfólio e contato de vários sites em um só lugar — com login e publicação em um clique.

  • Login e permissões por cliente
  • Upload de imagens na nuvem
  • Publicação imediata no site
  • Backup e histórico automático
Ver painel

Aplicações próprias

Dashboard — Dashboard
SaaS

Dashboard

Minha própria ferramenta de gestão: projeto, tarefas e equipe em um único place de trabalho.

  • Kanban com time-tracking
  • Diagramas de Gantt
  • Painel analítico em tempo real
  • Multi-workspace com permissões
Abrir produto
Teleprompt — Teleprompt
SaaS

Teleprompt

Plataforma para roteiros de vídeo com teleprompter ao vivo: editor estruturado por cenas, rolagem inteligente e espelhos sincronizados.

  • Editor de roteiro por cenas e marcadores
  • Rolagem inteligente com controle remoto
  • Espelhos sincronizados (operador + gravação)
  • Controle por acessibilidade e pronúncia
Escolher versão
O que eu faço

Do briefing ao deploy, entrego o projeto completo

Front-end, back-end, design de interfaces, acessibilidade e infraestrutura — tudo em um só lugar.

Desenvolvimento Mobile-First

Sites e apps otimizados para dispositivos móveis, com carregamento rápido, navegação fluida e design responsivo.

Otimização de SEO

SEO técnico e de conteúdo para o site ser encontrado no Google, maximizando visibilidade e cliques.

Acessibilidade Digital

Interfaces acessíveis (WCAG 2.1) para que qualquer pessoa use seu produto, tornando o projeto inclusivo de verdade.

Usabilidade e UX

Interfaces intuitivas, fluxos simples e CTAs claros — projetados para converter visitantes em clientes.

Sistemas e Gerenciadores

Ferramentas sob medida para gerenciar projetos, tarefas e regras de negócio — como o meu próprio Dashboard e o Teleprompt.

Performance e Escalabilidade

Código limpo e otimizado, pronto para crescer com o negócio — velocidade e suporte a picos de tráfego.

Stack que impulsiona resultados

Tecnologias escolhidas por necessidade, não por modismo

Do protótipo no Figma ao front-end com React/Next.js, passando por back-end com .NET, Laravel e Node.js até a orquestração com Docker e o deploy na nuvem.

Ver currículo completo
Código em destaque

Os bastidores deste site, em código real

Acessibilidade, GSAP e integrações que estão no ar agora — explicados com o arquivo de verdade e o código completo.

Acessibilidade: VLibras carregado sob demanda

O widget de Libras (terceiros, ~200KB) só é baixado na primeira interação real do usuário. Assim a acessibilidade existe de verdade sem sacrificar o carregamento — e o TypeScript entende os atributos customizados do plugin.

  • a11y
  • Libras
  • Lazy loading
  • TypeScript
src/components/layout/VlibrasWidget.tsx
declare global {
  interface Window {
    VLibras?: { Widget: new (src: string) => unknown };
  }
}

const start = () => {
  if (started) return;
  started = true;

  // Só baixa a biblioteca de Libras na primeira interação real
  scriptEl = document.createElement("script");
  scriptEl.src = "https://vlibras.gov.br/app/vlibras-plugin.js";
  scriptEl.async = true;
  scriptEl.addEventListener("load", () => {
    if (window.VLibras?.Widget) {
      new window.VLibras.Widget("https://vlibras.gov.br/app");
    }
  });
  document.head.appendChild(scriptEl);
};

window.addEventListener("pointerdown", start);
window.addEventListener("scroll", start, { passive: true });
window.addEventListener("keydown", start);

GSAP: reveals à prova de falha

Os cards de cada seção entram suavemente via ScrollTrigger. A chave é o immediateRender: false — o estado oculto só é aplicado quando o gatilho de verdade dispara, então nenhum conteúdo fica invisível se a medição falhar.

  • GSAP
  • ScrollTrigger
  • Core Web Vitals
src/components/effects/HomeFX.tsx
gsap.utils.toArray<HTMLElement>(".reveal").forEach((el) => {
  gsap.fromTo(
    el,
    { opacity: 0, y: 40 },
    {
      opacity: 1, y: 0, duration: 0.8, ease: "power3.out",
      // Só esconde quando o gatilho dispara — nunca trava conteúdo invisível
      immediateRender: false,
      scrollTrigger: {
        trigger: el,
        start: "top 92%",
        toggleActions: "play none none none",
      },
    }
  );
});

// Rede de segurança: se qualquer trigger falhar, nada fica invisível
gsap.delayedCall(2.5, () => {
  gsap.set([".reveal", ".product-card", ".service-card"], {
    opacity: 1, y: 0, scale: 1,
    clearProps: "opacity,transform,visibility",
  });
  ScrollTrigger.refresh();
});

Integração: upload autenticado (Firebase + Cloudinary)

A rota de upload valida o token do Firebase no servidor antes de tocar em qualquer arquivo, sanitiza a pasta e envia o buffer em stream para o Cloudinary — sem ocupar memória e sem expor o secret.

  • Next.js Route Handlers
  • Firebase Admin
  • Cloudinary
  • Segurança
src/app/api/upload/route.ts
cloudinary.config({
  cloud_name: process.env.NEXT_PUBLIC_CLOUDINARY_CLOUD_NAME,
  api_key: process.env.NEXT_PUBLIC_CLOUDINARY_API_KEY,
  api_secret: process.env.CLOUDINARY_API_SECRET, // só no servidor
});

export async function POST(request: Request) {
  // 1. Autentica antes de tocar em qualquer arquivo (Firebase Admin)
  let uid: string;
  try {
    uid = await getAuthenticatedUid(request);
  } catch {
    return NextResponse.json({ error: "Não autorizado." }, { status: 401 });
  }

  const formData = await request.formData();
  const file = formData.get("file") as File;
  const folder = (formData.get("folder") as string) || "clients_portfolio";

  // 2. Sanitiza a pasta: nunca sai do diretório esperado
  const safeFolder = folder
    .replace(/[^a-zA-Z0-9_\-\/]/g, "")
    .replace(/\.\./g, "")
    .replace(/^\/+/, "");

  if (!file) {
    return NextResponse.json({ error: "Nenhum arquivo enviado." }, { status: 400 });
  }

  // 3. Buffer vai em stream direto pro Cloudinary (memória estável)
  const bytes = await file.arrayBuffer();
  const buffer = Buffer.from(bytes);

  const response = await new Promise((resolve, reject) => {
    const uploadStream = cloudinary.uploader.upload_stream(
      { folder: safeFolder, public_id: `${uid}_${Date.now()}` },
      (error, result) => (error ? reject(error) : resolve(result))
    );
    uploadStream.end(buffer);
  });

  return NextResponse.json(response);
}

Smooth scroll no mesmo loop do GSAP

O Lenis cuida da rolagem suave e é plugado no ticker do GSAP. Resultado: ScrollTriggers sincronizadas, scroll com respeito a prefers-reduced-motion e tudo num único loop de animação.

  • Lenis
  • GSAP
  • ScrollTrigger
  • a11y
src/components/layout/LenisSmoothScroll.tsx
const lenis = new Lenis({
  lerp: 0.09,              // suavidade da rolagem
  smoothWheel: true,
  wheelMultiplier: 0.9,
  anchors: { offset: -72 },
  respectReducedMotion: true, // a11y: sensível à rolagem convencional
});

lenis.on("scroll", ScrollTrigger.update);

// Um único loop: o ticker do GSAP roda o Lenis
gsap.ticker.add((time) => lenis.raf(time * 1000));
gsap.ticker.lagSmoothing(0);

i18n no servidor com cookies

Todo o texto deste site é traduzido no SSR. O Next lê o cookie de idioma, decide qual texto renderizar e envia HTML pronto — sem flash do idioma errado e com SEO recebendo o conteúdo final.

  • React Server Components
  • SSR
  • Cookies
  • SEO
src/lib/locale.ts
import { cookies } from "next/headers";

export type Locale = "ptBR" | "en" | "es";
const SUPPORTED: Locale[] = ["ptBR", "en", "es"];

// 1. Lê o idioma escolhido no cookie (server-side)
export async function getLang(): Promise<Locale> {
  const chosen = (await cookies()).get("lang")?.value as Locale | undefined;
  return chosen && SUPPORTED.includes(chosen) ? chosen : "ptBR";
}

// 2. pick() devolve o texto certo na hora de renderizar
export function pick<T>(lang: Locale, obj: Record<string, T>): T {
  return obj[lang] ?? obj["ptBR"];
}

Performance: chunk só quando a seção se aproxima

O TechParticles pesado (react-icons + GSAP) só é baixado quando a seção #habilidades entra numa margem de 600px da viewport. Menos JS no caminho crítico = melhor LCP e TBT.

  • Dynamic Import
  • IntersectionObserver
  • Core Web Vitals
src/components/layout/LazyTechParticles.tsx
const TechParticles = dynamic(
  () => import("@/components/effects/TechParticles"),
  { ssr: false, loading: () => null }
);

export function LazyTechParticles() {
  const [near, setNear] = useState(false);
  const holderRef = useRef<HTMLDivElement>(null);

  useEffect(() => {
    const el = holderRef.current;
    const observer = new IntersectionObserver(
      ([entry]) => {
        if (entry.isIntersecting) {
          setNear(true); // chunk só baixa quando a seção se aproxima
          observer.disconnect();
        }
      },
      { rootMargin: "600px 0px" }
    );
    observer.observe(el);
    return () => observer.disconnect();
  }, []);

  return (
    <div ref={holderRef} className="relative h-full w-full">
      {near ? <TechParticles /> : null}
    </div>
  );
}

Sobre Mim

Transformo problemas em soluções digitais que geram resultado.

Sou desenvolvedor full-stack com mais de 13 anos de experiência. Trabalho lado a lado com cada cliente para entregar muito além de um site bonito: uma ferramenta que cresce com ele.

ReactNext.jsTypeScriptNode.js.NETAngularPHPLaravel
Conheça Minha História
+13Anos de Experiência
+25Projetos Entregues
100%Foco Mobile-First
WCAGAcessibilidade Digital

Disponível para novos projetos. Vamos criar algo incrível juntos?

Entrar em Contato
Minha jornada

A árvore de habilidades que cresceu com cada experiência

Estudos, experiências e projetos conectados em um fluxograma vivo. Filtre por tipo, toque numa habilidade e veja por onde ela floresceu — da origem até hoje.