docs: add app icon design spec
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
171
docs/superpowers/specs/2026-09-22-app-icon-design.md
Normal file
171
docs/superpowers/specs/2026-09-22-app-icon-design.md
Normal file
@@ -0,0 +1,171 @@
|
||||
# Video Clipper App Icon — Design Spec
|
||||
|
||||
**Date:** 2026-09-22
|
||||
**Status:** Draft
|
||||
|
||||
## Overview
|
||||
|
||||
Design an SVG app icon for Video Clipper following Android adaptive icon guidelines. The icon depicts open scissors cutting diagonally across a horizontal film strip. The visual style is a hybrid of Material Design and modern gradient aesthetics in a shadcn-inspired palette (muted, dark, refined). Five color accent variants are produced; the user selects their preferred variant.
|
||||
|
||||
## Android Adaptive Icon Compliance
|
||||
|
||||
Per [Google Play icon design specifications](https://developer.android.com/distribute/google-play/resources/icon-design-specifications):
|
||||
|
||||
- **Canvas:** 512x512px, 32-bit PNG (or SVG source at that viewBox)
|
||||
- **Shape:** Full square — Google Play dynamically masks with 30% corner radius
|
||||
- **No drop shadows** in the asset — Google Play adds them dynamically
|
||||
- **No rounded corners** in the asset — Google Play adds them dynamically
|
||||
- **Foreground/background separation:** Two layers for adaptive icon parallax on Android
|
||||
- **Safe zone:** Inner 66% (338x338px centered area, 87px inset). All critical artwork fits within this zone. Decorative elements (film strip edges) may extend beyond and clip gracefully.
|
||||
|
||||
## Visual Style
|
||||
|
||||
- **Aesthetic:** Material Design geometry (clean, geometric shapes) + modern gradient treatment (subtle blade gradients for depth), in a shadcn-inspired dark palette
|
||||
- **Background:** Solid zinc-900 (`#18181b`) — no transparency, no gradient
|
||||
- **Foreground elements:** Film strip in zinc-700, scissors with accent-colored gradient blades, zinc-400 finger rings
|
||||
|
||||
## Foreground Artwork — Composition
|
||||
|
||||
### Film Strip
|
||||
|
||||
- Horizontal rectangle centered in the canvas, ~70% of safe zone width (~236px wide), ~80px tall
|
||||
- Two rows of sprocket holes: 3 small rounded rectangles (12x16px, 4px border-radius) evenly spaced along the top edge and 3 along the bottom edge
|
||||
- **Split into two halves** by a diagonal gap (~8px wide) matching the scissors' blade angle (~30 degrees from vertical)
|
||||
- Left half offset slightly downward, right half offset slightly upward along the cut line — creates a "separation" effect
|
||||
- Film strip body: zinc-700 (`#3f3f46`)
|
||||
- Sprocket holes: zinc-800 (`#27272a`) — punched out of the strip
|
||||
- Cut edge: thin accent-colored line along the gap
|
||||
|
||||
### Scissors
|
||||
|
||||
- Pivot point roughly at canvas center (256, 256)
|
||||
- Two blades at ~60 degree opening angle, each ~140px long
|
||||
- Blades are elongated tapered shapes (narrow at tip, wider at pivot)
|
||||
- Blades pass through the film strip gap — upper blade toward upper-right, lower blade toward lower-left
|
||||
- Two finger rings at handle ends (~30px diameter), rendered as oval strokes (4px stroke width)
|
||||
- Pivot: small circle (10px diameter) at blade intersection
|
||||
- Blades: filled with accent gradient; rings: stroked zinc-400 (`#a1a1aa`); pivot: solid zinc-400
|
||||
|
||||
### Composition
|
||||
|
||||
- Film strip provides horizontal anchor
|
||||
- Scissors cross diagonally, creating visual tension
|
||||
- Centered within the 338x338px safe zone
|
||||
- Film strip edges may extend slightly beyond safe zone (clip gracefully on round masks)
|
||||
|
||||
## Color Palettes — Five Variants
|
||||
|
||||
All variants share the same structural colors:
|
||||
- Background: `#18181b` (zinc-900)
|
||||
- Film strip body: `#3f3f46` (zinc-700)
|
||||
- Sprocket holes: `#27272a` (zinc-800)
|
||||
- Finger rings & pivot: `#a1a1aa` (zinc-400)
|
||||
|
||||
The accent color differentiates each variant, applied to blade gradients and cut-edge accent line:
|
||||
|
||||
| Variant | Blade Tip (lighter) | Blade Pivot (darker) | Cut Edge Accent |
|
||||
|---------|---------------------|----------------------|-----------------|
|
||||
| Blue | `#60a5fa` | `#2563eb` | `#3b82f6` |
|
||||
| Purple | `#c084fc` | `#7c3aed` | `#a855f7` |
|
||||
| Green | `#34d399` | `#059669` | `#10b981` |
|
||||
| Orange | `#fb923c` | `#ea580c` | `#f97316` |
|
||||
| Mono | `#d4d4d8` (zinc-300)| `#71717a` (zinc-500) | `#a1a1aa` |
|
||||
|
||||
The blade gradient runs along the length of each blade — lighter/brighter at the sharp tip (draws the eye to the cutting action), darker toward the pivot. This adds depth without breaking the flat aesthetic.
|
||||
|
||||
## SVG Structure
|
||||
|
||||
Each variant is a single SVG file:
|
||||
|
||||
```xml
|
||||
<svg viewBox="0 0 512 512" xmlns="http://www.w3.org/2000/svg">
|
||||
<defs>
|
||||
<linearGradient id="blade-gradient" ...>
|
||||
<stop offset="0%" stop-color="{blade-tip-color}"/>
|
||||
<stop offset="100%" stop-color="{blade-pivot-color}"/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
|
||||
<!-- Background layer -->
|
||||
<rect width="512" height="512" fill="#18181b"/>
|
||||
|
||||
<!-- Film strip (two halves split by diagonal cut) -->
|
||||
<g id="film-strip">
|
||||
<g id="film-left" transform="...">
|
||||
<rect .../> <!-- left half body -->
|
||||
<rect .../> <!-- sprocket holes (x3 top, x3 bottom) -->
|
||||
</g>
|
||||
<g id="film-right" transform="...">
|
||||
<rect .../> <!-- right half body -->
|
||||
<rect .../> <!-- sprocket holes (x3 top, x3 bottom) -->
|
||||
</g>
|
||||
<line id="cut-accent" stroke="{cut-accent-color}" stroke-width="2" .../>
|
||||
</g>
|
||||
|
||||
<!-- Scissors -->
|
||||
<g id="scissors" transform="rotate(-30, 256, 256)">
|
||||
<path id="blade-upper" fill="url(#blade-gradient)" .../>
|
||||
<path id="blade-lower" fill="url(#blade-gradient)" .../>
|
||||
<circle id="pivot" cx="256" cy="256" r="5" fill="#a1a1aa"/>
|
||||
<ellipse id="ring-upper" stroke="#a1a1aa" stroke-width="4" fill="none" .../>
|
||||
<ellipse id="ring-lower" stroke="#a1a1aa" stroke-width="4" fill="none" .../>
|
||||
</g>
|
||||
</svg>
|
||||
```
|
||||
|
||||
## Output Files
|
||||
|
||||
### Primary (from chosen variant)
|
||||
|
||||
| File | Size | Purpose |
|
||||
|------|------|---------|
|
||||
| `src-tauri/icons/icon.svg` | 512x512 viewBox | Source / scalable icon |
|
||||
| `src-tauri/icons/32x32.png` | 32x32 | Tauri bundle |
|
||||
| `src-tauri/icons/128x128.png` | 128x128 | Tauri bundle |
|
||||
| `src-tauri/icons/128x128@2x.png` | 256x256 | Tauri bundle (Retina) |
|
||||
| `src-tauri/icons/icon.icns` | multi-resolution | macOS app icon |
|
||||
| `src-tauri/icons/icon.ico` | 16, 32, 48, 256 | Windows app icon |
|
||||
| `static/favicon.svg` | 512x512 viewBox | Web favicon (replaces default `tauri.svg`) |
|
||||
| `static/favicon-32.png` | 32x32 | Fallback favicon |
|
||||
|
||||
### Color Variant Selection Files
|
||||
|
||||
All five variants are created as separate SVGs for comparison:
|
||||
|
||||
| File | Variant |
|
||||
|------|---------|
|
||||
| `src-tauri/icons/variants/icon-blue.svg` | Blue accent |
|
||||
| `src-tauri/icons/variants/icon-purple.svg` | Purple accent |
|
||||
| `src-tauri/icons/variants/icon-green.svg` | Green accent |
|
||||
| `src-tauri/icons/variants/icon-orange.svg` | Orange accent |
|
||||
| `src-tauri/icons/variants/icon-mono.svg` | Monochrome |
|
||||
|
||||
After user selects their preferred variant, it is copied to the primary locations and rasterized.
|
||||
|
||||
### Android Adaptive Icon (if packaging for Android)
|
||||
|
||||
| File | Purpose |
|
||||
|------|---------|
|
||||
| `ic_launcher_foreground.svg` | Scissors + film strip only (transparent background) |
|
||||
| `ic_launcher_background.svg` | Solid `#18181b` fill |
|
||||
|
||||
Separated so Android can apply parallax motion between layers.
|
||||
|
||||
## Rasterization Pipeline
|
||||
|
||||
1. Create all 5 SVG variants by hand-crafting the paths
|
||||
2. User previews all variants and selects their preferred one
|
||||
3. Copy the chosen variant to `src-tauri/icons/icon.svg` and `static/favicon.svg`
|
||||
4. Rasterize to PNGs at required sizes using a tool (e.g., `resvg`, `rsvg-convert`, or ImageMagick with SVG support)
|
||||
5. Pack PNGs into `.icns` (macOS) and `.ico` (Windows) using `iconutil` / `png2ico` or equivalent
|
||||
6. Generate the separated foreground-only SVG for Android adaptive icon use
|
||||
|
||||
## Size Considerations
|
||||
|
||||
At small sizes (16-32px), fine details like sprocket holes and finger ring strokes may not be visible. The icon remains recognizable at small sizes because:
|
||||
|
||||
- The diagonal scissors silhouette is distinctive even as a blob
|
||||
- The film strip horizontal band provides contrast against the dark background
|
||||
- The accent color blade gradient maintains visibility
|
||||
|
||||
No separate simplified small-size variant is planned — the geometry is simple enough to scale down. If testing reveals readability issues at 16px, a simplified version (scissors silhouette only, no sprocket holes) can be added as `static/favicon-16.png`.
|
||||
Reference in New Issue
Block a user