Case Study · 2026
Chromaterra
A personal React web app that turns travel photos into color palettes. Every place has a palette. Chromaterra extracts it, names it, and saves it to your atlas.
Two Practices, One Tool
I make art with paper, quilling in particular — the tight rolling of thin strips of paper into shapes and designs. Color is a huge part of the work, and I often find myself pulling colors from photos of places I've traveled to use as reference. But the process of extracting and organizing those colors was a pain, and I wanted a more streamlined choice. I'd been using Shutterstock palette tools for years, but I wanted something more specfic to my tastes and interests. What I actually wanted was color pulled from places I know by heart and places I dream of visiting. I wanted to recreate the feeling of a place through its colors, like the greens of São Miguel in the Açores, the haint blue porch ceilings and faded coral shotguns of Bywater.
The idea was simple: upload photos from places you've been and extract a palette you can actually use. I tested the concept with TripAdvisor photos organized into albums by city, island, and region. It worked well enough that I started using one of the palettes in an active quilling project before I'd finished building the app.
Chromaterra became the project where my life as a visual artist and my work as a developer converged. It's a tool I built for myself that turned into a study in React architecture, API security, Firebase auth, and accessibility.
French Quarter and Garden District palettes, locales generated in the app.
Building the Architecture
The most consequential decision in this project was security. The original build called the Anthropic API directly from the client — which meant the API key was exposed in the browser. Fixing that meant building a Vercel serverless proxy to sit between the client and the API, with CORS locked to the production domain. That one change reframed how I think about third-party API integration entirely.
Component organization followed the same instinct toward structure.
The original flat component directory was reorganized into
subdirectories — buttons/,
modals/,
panels/,
layout/,
icons/ — and inline styles were replaced
with CSS Modules across the board. Firebase auth was reverted from
signInWithRedirect to
signInWithPopup after cross-browser
issues surfaced in testing.
A Pa11y WCAG 2AA audit found contrast violations across several components. All were resolved — the final audit returned zero errors.
| Framework | React 19 + Vite |
| Language | JavaScript |
| AI | Claude API via Vercel serverless proxy |
| Auth & DB | Firebase (Google Auth + Firestore) |
| Styling | CSS Modules |
| Accessibility | Pa11y · WCAG 2AA · Zero errors |
| Hosting | Vercel |
| Security | Serverless proxy · CORS locked · No client-side API key |
Key Lesson
Exposing an API key in the client is an easy mistake when moving fast on a personal project. Building the serverless proxy was a security fix.
What It Does
- AI Palette Generation The Claude API analyzes location-based imagery and returns a named, curated color palette — not just hex codes, but colors with context and a gradient built from the scene.
- Font Pairing Each generated locale includes AI-suggested font pairings derived from the mood and visual character of the uploaded photos.
- Personal Atlas Palettes are saved to a personal collection via Firebase Firestore, organized by region and area, tied to a Google Auth account.
- Gradient Builder Each locale detail view includes a gradient tool built from the extracted palette colors.
- Responsive Layout Full desktop and mobile layouts across landing, locale detail, profile, and atlas views.
- WCAG 2AA Accessible Full Pa11y audit completed. All contrast values meet AA standards. Zero violations on final pass.
The Road Ahead
Chromaterra began as a personal color tool and became a study in production-grade React development. The next phase is about deepening the personal use case — bringing in real travel photography and building toward something usable as a daily artist reference.
Own Photography Upload
The original vision: upload your own travel photos, not pulled reference imagery. A direct upload flow with Firebase Storage would complete the personal use case.
Album Organization
Group palettes by trip, region, or project. A single Azores trip might generate a dozen palettes that need to live together for quilling reference.
Palette Export Formats
Export as ASE (Adobe Swatch Exchange), CSS custom properties, or a PNG swatch sheet — so palettes move directly into design tools without manual re-entry.
TypeScript Migration
The project is currently in JavaScript. A TypeScript migration would enforce the data model and close the gap toward more structured codebases.
Screen Gallery
A curated walkthrough of the app: landing page, atlas view, locale generation, palette detail, and user profile.
About Chromaterra
Chromaterra is a personal project built with React. The idea came from wanting a way to document the visual identity of places I've traveled — not just photos, but the actual colors. You upload reference images from a location, and the app uses AI to extract a named color palette, suggest font pairings, and build a gradient from the scene. Each palette is saved to your personal atlas, organized by region and area.
This gallery is a static snapshot of the UI as it currently stands.
Palette
Colors pulled from real places — Azorean greens, volcanic stone, Atlantic mist, and terracotta from the road.