ChromaForge from Mandelbrot Metal
  • Home
  • Story
  • White Paper
  • User Guide
  • Beta Application
  • About Us
  • More
    • Home
    • Story
    • White Paper
    • User Guide
    • Beta Application
    • About Us
ChromaForge from Mandelbrot Metal
  • Home
  • Story
  • White Paper
  • User Guide
  • Beta Application
  • About Us

From Fractal Palettes to ChromaForge

How a color engine built for Mandelbrot Metal became a native color compiler for developers and desi

Some ideas begin as tools inside other ideas.


PaletteWright began that way.


It did not start as a standalone product, a design-system platform, or a deliberate attempt to build another color app. It started inside Mandelbrot Metal, where color was never just decoration. In a fractal renderer, color is how mathematical behavior becomes visible. A palette is not paint applied after the fact. It is part of the rendering pipeline.


That realization changed how I thought about color.


In Mandelbrot Metal, every pixel begins as a mathematical result: an escape value, an iteration count, a continuous signal derived from the behavior of a point in the complex plane. But that signal is not yet an image. It has to pass through interpolation, lookup tables, smoothing, display color spaces, HDR presentation, and export logic before it becomes something a person can see, save, and share.


The more I worked on that pipeline, the more obvious one thing became: Color is data.


And if color is data, it deserves engineering.


The Palette Problem


At first, the palette system in Mandelbrot Metal had a very specific purpose: turn numerical fractal structure into beautiful, stable, repeatable images.


That meant building tools for gradient stops, wide-gamut color, smooth interpolation, exact lookup-table preview, stepped palettes, dithering, export stability, and reproducible rendering. A fractal bookmark only makes sense if the image can be reconstructed. A palette only works if it behaves predictably across interactive rendering and high-resolution export.


So the palette system became more serious than a simple picker.


  • It needed to know where colors lived.
  • It needed to preserve relationships between colors.
  • It needed to preview what would happen before committing to an export.
  • It needed to treat color not as a loose collection of swatches, but as a structured input to a larger system.


That was the first seed of PaletteWright.


Color Outside the Fractal


Once you start thinking about color this way, it is hard to stop seeing the same problem everywhere.


App developers do not just need attractive colors. They need colors that survive real interface requirements.


Web designers do not just need inspiration. They need CSS variables, dark-mode behavior, accessible contrast, component roles, and tokens that can move into production.

Design-system teams do not just need a palette. They need a reliable translation layer between creative intent and implementation.


The usual workflow is surprisingly fragile. A palette begins as a screenshot, a photo, a website, a CSS file, or a few manually chosen swatches. Then it gets copied into a design tool, renamed by hand, adjusted by eye, pasted into code, checked for contrast, patched for dark mode, translated into framework-specific roles, and eventually exported into five different formats that all want the same truth expressed differently.


That is not a color workflow.


That is a chain of opportunities for drift.


PaletteWright grew out of the belief that this should be treated more like compilation.


A Color Compiler


The name is literal.


PaletteWright is built to forge color into code.


A source palette goes in. It might come from manual stops, a photo, a website, CSS, a design-token file, a Mandelbrot Metal palette, a CSV, a GIMP GPL file, or Adobe ASE swatches.


Then the app does what a compiler should do.


It normalizes the input.


It converts colors through perceptual models like OKLab, OKLCH, CIELAB, and CIELCH.


It analyzes contrast, accessibility, color-vision resilience, semantic roles, component usage, and export readiness.


It maps raw swatches into practical interface concepts: background, foreground, surface, border, primary, secondary, accent, success, warning, danger, links, focus rings, buttons, cards, alerts, sidebars, charts, and more.


Then it emits something usable.


CSS variables. Semantic CSS. Modern CSS with OKLCH and Display-P3 output. Tailwind themes. shadcn/ui roles. SwiftUI colors. Android XML. Jetpack Compose. Flutter. React Native. DTCG design-token JSON. Tokens Studio. Style Dictionary. Figma Variables.


The goal is not to make another place to admire swatches.


The goal is to move color from inspiration to implementation without losing meaning along the way.


Accessibility as Part of the System


One of the strongest lessons from building software for years is that visual decisions become engineering decisions eventually.


Contrast is a perfect example.


It is easy to choose a beautiful foreground and background pair that fails in actual use. It is easy to make a palette that looks strong in a hero image and collapses inside a form, a table, a warning badge, or a disabled button. It is easy to build a lovely light theme and then discover that the dark theme is not a true counterpart, but a separate improvisation.


PaletteWright treats those problems as part of the core workflow.


It can inspect WCAG contrast pairs, preview experimental APCA-style readability, simulate protanopia, deuteranopia, and tritanopia, and test colors in component contexts instead of only isolated swatches.


It can compile light, dark, and high-contrast variants from the same source palette.


It can repair failing WCAG AA semantic pairs with OKLCH-aware foreground adjustments.


That repair step matters because accessibility should not feel like punishment. It should feel like refinement. The designer should still recognize the palette. The developer should still get usable tokens. The app should help bring the system into compliance without flattening its character.


That is the balance I wanted PaletteWright to strike.


The Bridge From Art to Engineering


There is a funny continuity between Mandelbrot Metal and PaletteWright.


Mandelbrot Metal turns mathematics into visual experience.


PaletteWright turns visual intent into production systems.


They sound like different problems, but they share the same underlying principle: beauty becomes more powerful when the pipeline behind it is disciplined.


In Mandelbrot Metal, the equation is not enough. You need precision, interpolation, palette lookup, color management, display handling, and export consistency.


In PaletteWright, a good palette is not enough. You need semantic roles, accessibility checks, dark-mode behavior, component previews, framework mapping, token output, and automation hooks.


Both apps are about respecting the path from raw source to finished result.


One starts with mathematical structure.


The other starts with color inspiration.


Both ask the same question:


How do we preserve the original spark while making it reliable enough to ship?


Why Native Matters


PaletteWright is a native SwiftUI app because color work benefits from immediacy.


When you are shaping a palette, you should be able to see the gradient, inspect the stops, simulate color-vision differences, preview UI components, adjust roles, repair contrast, and export code without feeling like the tool is fighting you.


The app is designed for Mac and iPad and also supports iPhone because color work happens in different modes. Sometimes you are sampling inspiration from a photo. Sometimes you are auditing a client site. Sometimes you are preparing a design-token package for a production repo. Sometimes you just want to see whether a palette actually survives contact with buttons, forms, cards, charts, and sidebars.


The same color system should travel across all of those moments.


That is why PaletteWright also includes a command-line audit helper. The native app is the authoring surface. The CLI is the automation surface. Together, they let color live both in the designer’s hands and in the developer’s build process.


From Side Project to System


The most interesting software often emerges from pressure.


Mandelbrot Metal needed a better palette engine because fractal images depend on color in unusually deep ways. That pressure created reusable ideas: perceptual interpolation, LUT previews, export stability, wide-gamut handling, palette metadata, and a serious respect for reproducibility.


PaletteWright is what happened when those ideas stepped outside the fractal.


It is a product born from a practical question:


What if color palettes were treated like real build artifacts?


Not screenshots.


Not vibes.


Not a row of disconnected swatches.


Artifacts — Inputs that can be imported, normalized, analyzed, transformed, repaired, mapped, exported, audited, and reused.


That is the heart of PaletteWright.


Conclusion


Mandelbrot Metal began with a lifelong fascination with mathematical beauty and the technology needed to finally explore it in real time.


PaletteWright begins from a related fascination: the point where beauty becomes usable.


Color has always carried emotion. It gives software identity, mood, hierarchy, warmth, urgency, calm, delight, and clarity. But in modern apps and websites, color also has a job to do. It has to adapt. It has to pass contrast checks. It has to survive dark mode. It has to become tokens. It has to compile into multiple frameworks. It has to remain recognizable after all of that transformation.


That is the problem PaletteWright is built to solve.


It takes color seriously because color is not the last step.


Color is part of the system.


And when the system is built well, the original inspiration does not get lost.


It gets forged into something that can ship.


Michael


© 2026 Mandelbrot Metal. All Rights Reserved.

This website uses cookies.

We use cookies to analyze website traffic and optimize your website experience. By accepting our use of cookies, your data will be aggregated with all other user data.

Accept