Files
jellybloom/src/lib/discover-icons.ts
T

96 lines
2.4 KiB
TypeScript

import type { ComponentType } from 'react'
import {
Sword,
MasksTheater,
MoodHappy,
Rocket,
Spy,
Ghost,
Palette,
HomeHeart,
Wand,
Binoculars,
Backpack,
Leaf,
News,
Trophy,
Microphone,
Gavel,
Globe,
Tv,
Film as FilmIcon,
} from './icons'
type IconCmp = ComponentType<{ size?: number; stroke?: number; className?: string }>
/**
* Visual mapping for the Browse-by tiles. Each label gets a glyph + a
* solid tonal hue so the grid reads as a mosaic of distinct sections
* instead of a uniform wall of cards.
*
* Hue values are HSL tuples we feed to the tile background; the same
* hue at higher saturation drives the icon tint. Keeping everything on
* a single chromatic axis (warm-to-cool sweep) preserves the app's
* tonal-dark palette - no random rainbow.
*/
export interface TileVisual {
icon: IconCmp
/** HSL hue value 0-360. Tile uses this at low saturation + high luminance. */
hue: number
}
export const GENRE_VISUALS: Record<string, TileVisual> = {
Action: { icon: Sword, hue: 14 },
Drama: { icon: MasksTheater, hue: 280 },
Comedy: { icon: MoodHappy, hue: 48 },
'Science Fiction': { icon: Rocket, hue: 200 },
Thriller: { icon: Spy, hue: 0 },
Horror: { icon: Ghost, hue: 320 },
Animation: { icon: Palette, hue: 170 },
Romance: { icon: HomeHeart, hue: 340 },
Fantasy: { icon: Wand, hue: 260 },
Mystery: { icon: Binoculars, hue: 220 },
Adventure: { icon: Backpack, hue: 35 },
Documentary: { icon: Leaf, hue: 130 },
Crime: { icon: Gavel, hue: 10 },
Family: { icon: HomeHeart, hue: 40 },
News: { icon: News, hue: 210 },
Music: { icon: Microphone, hue: 290 },
History: { icon: Trophy, hue: 30 },
}
const GENRE_FALLBACK: TileVisual = { icon: FilmIcon, hue: 200 }
export function genreVisual(label: string): TileVisual {
return GENRE_VISUALS[label] || GENRE_FALLBACK
}
const LANG_HUE: Record<string, number> = {
ja: 0,
ko: 220,
fr: 245,
es: 25,
de: 50,
it: 130,
zh: 12,
hi: 30,
}
export function languageVisual(code: string): TileVisual {
return { icon: Globe, hue: LANG_HUE[code] ?? 200 }
}
export function studioVisual(): TileVisual {
return { icon: FilmIcon, hue: 40 }
}
export function networkVisual(): TileVisual {
return { icon: Tv, hue: 220 }
}
/** Build the gradient background CSS for a tile from a hue value. */
export function tileBackground(hue: number): string {
return `linear-gradient(135deg, hsla(${hue}, 50%, 38%, 0.32) 0%, hsla(${hue}, 30%, 18%, 0.55) 100%)`
}