CodeGenie Logo Gradient Effect
Visual design and rendering specification for the CodeGenie logo in terminal/TUI applications.
Overview
The logo features a horizontal purple-to-pink gradient applied to ASCII art characters. The left side displays a "Three G" design using Unicode block characters with varying opacity levels, creating depth and a modern aesthetic. The right side provides contextual text with hierarchical styling.
Visual Layout
Left Column Right Column
░░░░░░░░░ CODE GENIE
░░░ ░░░
░░░ ▒▒▒▒▒▒▒▒▒ Collaborate with CodeGenie
░░░ ▒▒▒ ▒▒▒ AI copilot for HarmonyOS...
░░░ ▒▒▒░░░█████████ Powered by BITFUN & OpenCode
░░░▒▒▒ ░███ ███
░░▒▒▒░███▒▒▒▒▒ ⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯
▒▒▒███ ▒▒▒
▒▒███▒▒▒▒█████
███ ███
█████████
Gradient System
Color Range
| Position | RGB | Hex | Description |
|---|---|---|---|
| Start (left) | (77, 43, 251) | #4D2BFB | Purple |
| End (right) | (220, 73, 170) | #DC49AA | Pink |
Calculation Formula
function getGradientColor(x: number, totalWidth: number): RGB {
const ratio = Math.max(0, Math.min(1, x / totalWidth))
return {
r: Math.round(77 + (220 - 77) * ratio),
g: Math.round(43 + (73 - 43) * ratio),
b: Math.round(251 + (170 - 251) * ratio)
}
}
Character System
Block Characters
The design uses three Unicode shade characters mapped to a single rendering character with different opacity:
| Source | Unicode | Renders As | Unicode | Opacity | Visual Effect |
|---|---|---|---|---|---|
| ░ | U+2591 | ▮ | U+25AE | 0.15 | Ghostly/faint |
| ▒ | U+2592 | ▮ | U+25AE | 0.40 | Semi-visible |
| █ | U+2588 | ▮ | U+25AE | 1.00 | Solid |
Opacity Blending
Characters are blended toward a dark background color:
const DARK_BG = { r: 12, g: 12, b: 24 }
function blendOpacity(color: RGB, opacity: number): RGB {
return {
r: Math.round(color.r * opacity + DARK_BG.r * (1 - opacity)),
g: Math.round(color.g * opacity + DARK_BG.g * (1 - opacity)),
b: Math.round(color.b * opacity + DARK_BG.b * (1 - opacity))
}
}
Data Model
Logo Shape Interface
interface LogoShape {
left: string[]
right: string[]
charMap?: Record<string, string>
charOpacity?: Record<string, number>
}
Logo Definition
const CG_LEFT = [
" ░░░░░░░░░ ",
" ░░░ ░░░ ",
"░░░ ▒▒▒▒▒▒▒▒▒ ",
"░░░ ▒▒▒ ▒▒▒ ",
"░░░ ▒▒▒░░░█████████ ",
" ░░░▒▒▒ ░███ ███ ",
" ░░▒▒▒░███▒▒▒▒▒ ",
" ▒▒▒███ ▒▒▒ ",
" ▒▒███▒▒▒▒█████ ",
" ███ ███ ",
" █████████ ",
]
const CG_RIGHT = [
" CODE GENIE",
" ",
"",
"",
" {muted}Collaborate with {/muted}{link}CodeGenie{/link}",
" AI copilot for HarmonyOS application development",
" Powered by BITFUN & OpenCode",
"",
" ⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯",
"",
"",
]
export const logo: LogoShape = {
left: CG_LEFT,
right: CG_RIGHT,
charMap: { "\u2591": "\u25AE", "\u2592": "\u25AE", "\u2588": "\u25AE" },
charOpacity: { "\u2591": 0.15, "\u2592": 0.40, "\u2588": 1.0 },
}
Rendering
TUI Component (SolidJS)
function Logo(props: { shape?: LogoShape; column?: "left" | "right" }) {
const activeShape = props.shape ?? logo
const totalWidth = Math.max(...activeShape.left.map(line => line.length))
const renderLine = (line: string): JSX.Element[] => {
return line.split("").map((char, x) => {
const srcChar = char
// Apply character mapping
if (activeShape.charMap?.[char]) {
char = activeShape.charMap[char]
}
if (char === " ") return <text> </text>
// Calculate gradient
let color = getGradientColor(x, totalWidth)
// Apply opacity
const opacity = activeShape.charOpacity?.[srcChar]
if (opacity !== undefined) {
color = blendOpacity(color, opacity)
}
return <text fg={color}>{char}</text>
})
}
// Render based on column prop...
}
ANSI Terminal
function drawLogo(): string {
const totalWidth = Math.max(...logo.left.map(l => l.length))
const reset = "\x1b[0m"
const ansiFg = (rgb: RGB) => `\x1b[38;2;${rgb.r};${rgb.g};${rgb.b}m`
return logo.left.map(line =>
line.split("").map((char, x) => {
const src = char
if (logo.charMap?.[char]) char = logo.charMap[char]
if (char === " ") return " "
let rgb = getGradientColor(x, totalWidth)
const opacity = logo.charOpacity?.[src]
if (opacity !== undefined) rgb = blendOpacity(rgb, opacity)
return ansiFg(rgb) + char + reset
}).join("")
).join("\n")
}
Right Side Styling
Text Tags
The right side supports inline styling tags:
| Tag | Effect |
|---|---|
{muted}text{/muted} |
Muted gray color (theme.textMuted) |
{link}text{/link} |
Accent color with bold (theme.info) |
Example:
" {muted}Collaborate with {/muted}{link}CodeGenie{/link}"
// Renders: "Collaborate with" in muted gray, "CodeGenie" in accent color
Line-by-Line Rules
| Line | Content | Style |
|---|---|---|
| 0 | CODE GENIE | Bold white |
| 4 | Collaborate with CodeGenie | Use {muted} and {link} tags |
| 5 | Subtitle | Muted gray |
| 6 | Powered by... | White |
| 8 | Separator dots | 50% dimmed |
Tag Parsing Implementation
type TextSegment = { text: string; muted: boolean; link: boolean }
function parseSegments(line: string): TextSegment[] {
const segments: TextSegment[] = []
let s = line
while (s.length > 0) {
if (s.startsWith("{muted}")) {
s = s.slice(7)
const end = s.indexOf("{/muted}")
if (end === -1) break
segments.push({ text: s.slice(0, end), muted: true, link: false })
s = s.slice(end + 8)
continue
}
if (s.startsWith("{link}")) {
s = s.slice(6)
const end = s.indexOf("{/link}")
if (end === -1) break
segments.push({ text: s.slice(0, end), muted: false, link: true })
s = s.slice(end + 7)
continue
}
// Handle plain text between tags...
const nextTag = Math.min(
...[s.indexOf("{muted}"), s.indexOf("{link}")].filter(x => x >= 0)
)
const plainEnd = nextTag >= 0 ? nextTag : s.length
if (plainEnd > 0) {
segments.push({ text: s.slice(0, plainEnd), muted: false, link: false })
}
s = s.slice(plainEnd)
}
return segments
}
## Component Modes
```tsx
// Full logo (both columns)
<Logo />
// Left column only
<Logo column="left" />
// Right column only
<Logo column="right" />
// Custom shape
<Logo shape={customLogo} />
Implementation Checklist
- Define ASCII art arrays (left/right)
- Create charMap (░▒█ → ▮)
- Create charOpacity (0.15, 0.40, 1.0)
- Implement gradient calculation (purple → pink)
- Implement opacity blending toward dark
- Implement
{muted}and{link}tag parsing for right side - Apply right-side line styling rules
- Support column-based rendering
- Use
\x1b[38;2;R;G;Bmfor ANSI 24-bit color - Use RGBA objects for TUI components
File References
src/cli/logo.ts- Logo data definitionsrc/cli/cmd/tui/component/logo.tsx- TUI componentsrc/cli/ui.ts- ANSI terminal rendering