Web Developer Pedro Batista Cases | Resume | Hire me
Home | Cases | Brasilia, Brazil (UTC−3) | Available for remote work Português

Cases

Six projects, told as problem, build and result.

Some of this work is for public institutions and private clients, so the code isn't public. I'm happy to walk through any of it on a call.

On this page: This portfolio · Renejum calendar · ENAM portal · ENFAM redesign · Cypay · IESP Tradutor


This portfolio

Personal project · Three.js, Windows XP and this résumé

If you came in through the 3D office, you're looking at it right now: this page is open in Internet Explorer, inside Windows XP, on the office monitor. On a phone, it opens in a pocket version of Internet Explorer instead.

The problem
A PDF can say “web developer” without proving it. I wanted the portfolio itself to be the proof, and the résumé to stay readable, printable and indexable for people who don't have time for a 3D scene.
What I built
Two apps that talk to each other.
  • The room. A 3D office in Three.js, TypeScript and Vite. The model went from 31.4 MB to 1.54 MB with Draco-compressed geometry and re-encoded textures. The camera moves between named keyframes (room, desk, monitor) with tween.js, and there's a free-camera mode.
  • The screen. A working Windows XP runs in an iframe that CSS3DRenderer places on the monitor. The screen mesh uses an invisible material that still writes depth, so it cuts the hole the iframe shows through and the bezel keeps hiding the edges as the camera moves. Size and angle come from the mesh's own vertices, and the model is scaled 1000x so CSS3D works in real pixels and text stays sharp.
  • The OS. A trimmed fork of win32.run (SvelteKit). I removed unused programs and their orphaned libraries, cut static assets from 239 MB to about 26 MB, and moved every CDN dependency into the project, since dragging and resizing windows depended on a CDN copy of jQuery UI.
  • The bridges. The XP forwards mouse and keyboard events to the room with postMessage, which is how the scene knows someone is using the computer. The language button travels the other way: room, XP, then this page.
  • The phone version. Phones skip the 3D, and the three.js bundle with it, and open this résumé inside a pocket Internet Explorer in the style of Windows Mobile 2003, with its own back button, menus and language switch. If WebGL fails on a computer, the loader says so and links the résumé instead of showing a blank page.
  • One source. The pages, the PDFs and the text search engines read all come from one content file. A script writes the site in English and Portuguese, and Playwright prints the PDFs from it.
  • The deploy. Two Hostinger apps, a static Vite build and a Node server for the XP, on subdomains of the same domain so the XP's virtual disk in IndexedDB isn't blocked inside the iframe. A Playwright smoke test walks through boot, desk, monitor, Esc and free camera, and reports console errors.
Result
A résumé you can open inside a working OS inside a 3D room, which still degrades to plain HTML when it has to. This page follows the same idea: plain HTML and CSS styled like an early-2000s personal site, because that's what Internet Explorer 6 would have shown.

Stack: Three.js, TypeScript, Vite, tween.js, CSS3DRenderer, SvelteKit, Tailwind CSS, postMessage, Playwright, gltf-transform, sharp

Visit: batistapedro.acheme.me

Renejum Calendar Plugin

ENFAM · Renejum, the national network of judicial schools

Renejum calendar for September 2026, with filters for month, category, modality and school, and monthly totals of events and seats
The problem
Courses offered across the network lived in separate systems run by different courts, so building one calendar meant consolidating them by hand.
What I built
A custom WordPress plugin with two shortcodes: an interactive monthly calendar and a list view. A PHP proxy fetches three external APIs on the server (SINEMAF from the Federal Justice Council, Educa from ENFAM and SIGA from the Minas Gerais Court of Justice) and caches each source by month in WordPress transients, so visitors don't hit the courts' APIs on every page view. Visitors filter by month, category, modality and school, switch between course start dates and open registrations, and see monthly totals. ARIA roles and labels throughout.
Result
One calendar for the whole network, with no manual consolidation. The September 2026 view lists 87 events and 3,456 seats.

Stack: PHP, WordPress Plugin API, shortcodes, Transients API, REST APIs, JavaScript, Bootstrap 5

Visit: renejum.enfam.jus.br

ENAM Exam Portal

ENFAM · National Magistracy Exam

ENAM portal home page, with the exam title, links to the current edition and a presentation video
The problem
ENAM is Brazil's unified national exam that qualifies candidates for judicial careers in federal, labor, military and state courts. Its portal had to stay up and accessible when candidates from across the country arrive at the same time, on registration and results days.
What I built
An accessible WordPress and Elementor front end organized around what candidates look for (the exam, data, regulations, certificate, results, news and FAQ), with caching and server configuration handled on our own LAMP stack.
Result
30,000+ visits in the first month. The same portal now runs the exam's 6th edition.

Stack: WordPress, Elementor, PHP, HTML, CSS, WCAG and eMAG, LAMP, server-side caching

Visit: enfam.jus.br/enam

ENFAM Institutional Redesign

ENFAM · public website

ENFAM home page with the 20-year logo, the main navigation and the courses and events section
The problem
The website of Brazil's national school for judges was hard to navigate and slow, and new pages took too long to build.
What I built
A UX-driven redesign of information architecture, navigation and page templates, backed by a Figma component library that I turned into reusable WordPress templates. I also refactored the legacy theme, optimized assets and added server-side caching.
Result
Daily visits grew 300%, and Core Web Vitals moved into the “Good” range.

Stack: Figma, WordPress, Elementor, PHP, CSS, performance optimization

Visit: enfam.jus.br

Cypay

Freelance · landing page for a self-custodial crypto app

Cypay home page hero reading All-in-One Crypto App
The problem
Cypay puts swaps, yield, trading, bridging and a card across nine blockchains into one self-custodial wallet. The landing page had to explain all of that without turning into a wall of text.
What I built
A scroll-driven single page. Sections, feature cards and app mockups enter and leave the screen as you scroll, tied to scroll position with requestAnimationFrame and IntersectionObserver rather than timers. Hand-written HTML, CSS and vanilla JavaScript, no framework. The first version also had a scroll progress bar and a 3D mascot, the Cypay logo extruded from SVG with Three.js, that travelled across the page as you scrolled.
Result
Live at cypay.io. The content has changed since launch, but the scroll choreography is still how the page works.

Stack: HTML, CSS, vanilla JavaScript, IntersectionObserver, requestAnimationFrame, Canvas, Three.js

Visit: cypay.io

IESP Tradutor

Freelance · translation plugin for IESP-UERJ, the Institute of Social and Political Studies

IESP Tradutor manual, showing the plugin's General Settings tab in the WordPress admin
The problem
The institute's WordPress site needed to be readable in English, Spanish and French by international researchers, at zero translation cost and without mangling institutional names and terms.
What I built
A WordPress plugin in PHP 8 with three layers. By default, the free Google Translate widget, with no character limit. On top of it, a glossary and “segments” (HTML blocks tagged with data-iesp-key) for fixed human translations. And, per page, an optional server-side mode with Google Cloud Translation for SEO: translations stored in the database, invalidated by a content hash on save and reprocessed by a WP-Cron queue, all behind a quota guard with a safe limit and a hard stop below the free tier, plus alerts at 70, 85, 95 and 100%. Editors control it from Gutenberg panels, an eight-tab admin, CSV and Excel import and WP-CLI; the quota guard, import and segments have automated tests.
Result
Four languages managed from inside WordPress, with zero API cost by design. The plugin is at version 3.1.

Stack: PHP 8, WordPress Plugin API, Gutenberg, Google Cloud Translation API, WP-Cron, WP-CLI, PHPUnit

Visit: plugin manual

Plain HTML and CSS. No frameworks, no trackers. · Credits and licences
Pedro Batista · Brasilia, Brazil · Last updated September 2026