Vibe-A-Palette

Designing and publishing a web-app (in two days) that converts vibe prompts into dynamic, shareable gradients and color palettes using Google’s Gemini API, Grok, Supabase, and Lovable.

URL

Image Generation

The sequence of images above show the progression of quality in PNG downloads from the site. At first, the idea was to capture the current state of the screen to save as an image, but the heavy-lifting to generate the smooth gradients with no stepping is done by the browser, not the styling. To fix this, I shifted to generating brand new PNG’s that are representative of the same effect seen on screen. To improve the blur, I first generate the underlying design in SVG, apply the effects, then convert that resulting graphic into a PNG for download.

The following images represent two of the exported assets available to users of Vibe-A-Palette. Palette hex values are stored once returned from Gemini and used to generate wholly new assets in SVG format.

SVG was chosen for its superior blur preservation over PNG (through integrated gaussianBlur properties) as well as its ability to provide the simplest method for bringing these palettes/gradients into Figma. The site generates a canvas and renders the SVG objects within it, providing a clean export that preserves each individual shape and even wraps them in a frame by default.

Prompting & Fallback Logic

The first draft of the prompt sent to Gemini, including the vibe entered by the user, was verbose in an attempt to generate thoughtful and creative outputs:

const prompt = `You are a color palette generator. Based on the following vibe or description: "${vibe.trim()}", please generate exactly 5 complementary hex color codes that capture the essence and mood of this vibe. Please return your response in the following exact JSON array format with no additional text or explanation: ["#hex1", "#hex2", "#hex3", "#hex4", "#hex5"]

This approach was eating up to 150 tokens per request, and oftentimes, Gemini would refuse to even generate a response. The revised prompt is far more straightforward, consumes around 20 tokens, and in my testing, remains a reliable way to generate creative palettes quickly:

const prompt = `Generate 5 hex colors for: ${vibe.trim()}. Return only: ["#hex1","#hex2","#hex3","#hex4","#hex5"]`;

Retry logic and a fallback palette were also integrated in the event Gemini returns an error. Visual feedback to the user is immediate through the dynamically updated animated background, which shifts colors used for ‘blobs’ as soon as the palette is returned. Navigation is also made incredibly simple by utilizing a single-page design, static input fields, and button label updates for export confirmation.

Interface Design

Below is a selection of interface elements from initial concept to final design.

Initially, the submit button was designed to nest within the input field to provide more balance to the centered UI. Due to readability concerns and issues with potentially lengthy prompts becoming cut off, it was later moved. To facilitate users quickly trying new prompts, or tweaking their current prompt, the input field remains active after the prompt is submitted. This way, the user can simply continue typing.

This element is the switcher. I had planned to generate three palettes for every prompt that users could switch between at-will. However, I realized this would result in three times the requests to Gemini, and due to limitations with prompt/reply length through the API, decided to save it for a future version. If feedback makes the interest in this feature apparent, I will look into increasing rate limits through a higher tier or endeavor to train my own model for this task.

It was important to me from the start to incorporate a simple method for bringing generated palettes or gradients into Figma. Copying to a user’s clipboard is a well-known computer interaction, and with SVG code, it was possible. However, the icon-based buttons for export options shown in this concept failed to provide enough context for their actions. These were changed to include text labels, particularly for state changes, with words like ‘copied’ and ‘downloaded’ to better indicate the action that had taken place.

Conclusion

Vibe-A-Palette provided hands on experience integrating AI tools, API’s, and workflows into my process, enabling me to prototype and publish ideas much faster than before. It also presented an opportunity to further explore prompt-based, natural language experiences in design, which I believe will be a predominant interface method in future applications.