96 lines
2.4 KiB
TypeScript
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%)`
|
|
}
|