Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 55 additions & 0 deletions skills/featured/color-palette/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
---
name: color-palette
description: Generates a beautiful, visual color palette card from a theme, mood, or description provided by the user.
---

# Color Palette Generator

## Instructions

You are a color expert. When the user describes a mood, theme, style, or concept, you generate a harmonious color palette and render it visually using the `run_js` tool.

### How to Generate a Palette

1. Analyze the user's request to determine the intended mood or theme.
2. Choose 5 colors that work well together and match the description.
3. Call `run_js` with `index.html` and a JSON payload.

### JSON Payload

Your JSON payload MUST use the following fields:

- **title**: String, Required. A short descriptive name for the palette (e.g., "Ocean Breeze", "Autumn Forest").
- **colors**: Array of exactly 5 objects, Required. Each object has:
- **hex**: String, Required. A hex color code including the `#` (e.g., `#3A86FF`).
- **name**: String, Required. A creative, human-friendly name for the color (e.g., "Sapphire Sky").

### Example Payload

```json
{
"title": "Sunset Glow",
"colors": [
{ "hex": "#FF6B6B", "name": "Coral Flame" },
{ "hex": "#FFA07A", "name": "Peach Blush" },
{ "hex": "#FFD93D", "name": "Golden Hour" },
{ "hex": "#6BCB77", "name": "Twilight Moss" },
{ "hex": "#4D96FF", "name": "Evening Sky" }
]
}
```

### Guidelines

- Always pick colors with good contrast and visual harmony.
- Give each color a creative, evocative name — not just the hex code.
- If the user asks for a palette for a specific use case (e.g., "website", "bedroom", "logo"), tailor the palette accordingly.
- If the user provides an image, analyze the dominant colors and moods in the image and generate a matching palette.

### Invocation Triggers

You should invoke this skill when the user:
- Asks for a color palette, color scheme, or color suggestions.
- Describes a mood, theme, or aesthetic and wants matching colors.
- Uploads an image and asks for colors that match it.
- Asks for design inspiration related to colors.
124 changes: 124 additions & 0 deletions skills/featured/color-palette/scripts/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
<!--
Copyright 2026 Google LLC

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
==============================================================================
-->

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Color Palette Generator</title>
</head>
<body>
<canvas id="palette-canvas" style="display: none;"></canvas>

<script>
window['ai_edge_gallery_get_result'] = async function(data, secret) {
try {
const params = JSON.parse(data);
const title = params.title;
const colors = params.colors;

if (!title || !colors || colors.length !== 5) {
throw new Error("A title and exactly 5 colors are required.");
}

const canvas = document.getElementById('palette-canvas');
const ctx = canvas.getContext('2d');

const width = 600;
const height = 440;
const swatchWidth = width / 5;
const swatchHeight = 280;
const headerHeight = 60;
const labelHeight = height - headerHeight - swatchHeight;

canvas.width = width;
canvas.height = height;

// Background
ctx.fillStyle = '#FFFFFF';
ctx.fillRect(0, 0, width, height);

// Title bar
ctx.fillStyle = '#1A1A2E';
ctx.fillRect(0, 0, width, headerHeight);
ctx.fillStyle = '#FFFFFF';
ctx.font = 'bold 22px -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif';
ctx.textAlign = 'center';
ctx.textBaseline = 'middle';
ctx.fillText(title, width / 2, headerHeight / 2);

// Color swatches
for (var i = 0; i < 5; i++) {
var x = i * swatchWidth;

// Swatch
ctx.fillStyle = colors[i].hex;
ctx.fillRect(x, headerHeight, swatchWidth, swatchHeight);

// Label background
ctx.fillStyle = '#F8F8F8';
ctx.fillRect(x, headerHeight + swatchHeight, swatchWidth, labelHeight);

// Separator lines
if (i > 0) {
ctx.strokeStyle = '#E0E0E0';
ctx.lineWidth = 1;
ctx.beginPath();
ctx.moveTo(x, headerHeight + swatchHeight);
ctx.lineTo(x, height);
ctx.stroke();
}

// Hex code
ctx.fillStyle = '#1A1A2E';
ctx.font = 'bold 13px "SF Mono", "Fira Code", monospace, sans-serif';
ctx.textAlign = 'center';
ctx.fillText(colors[i].hex.toUpperCase(), x + swatchWidth / 2, headerHeight + swatchHeight + 32);

// Color name
ctx.fillStyle = '#666666';
ctx.font = '11px -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif';
ctx.fillText(colors[i].name, x + swatchWidth / 2, headerHeight + swatchHeight + 58);
}

// Bottom border
ctx.fillStyle = '#1A1A2E';
ctx.fillRect(0, height - 4, width, 4);

var base64 = canvas.toDataURL('image/png');

var resultData = {
title: title,
colors: colors.map(function(c) {
return c.name + ': ' + c.hex;
})
};

return JSON.stringify({
result: JSON.stringify(resultData),
image: { base64: base64 },
error: null
});

} catch (err) {
return JSON.stringify({ result: null, image: null, error: err.message });
}
};
</script>
</body>
</html>