/** Per-group colors and identity, and the feature toggles that have gone back and * forth while this design was under review - flip one here rather than hunting * through the components that read it. Most toggles are about the browse screen's * shelf/row look, but some (`SHOW_GLASS_BLUR`, `SHOW_AMBIENCE`, * `SHOW_DECORATIVE_ANIMATIONS`) reach further: the play view, the player bar, the * room page and `App.tsx` all read this module too, wherever they share the same * "cut this on weak hardware" knob. * * `SHOW_ROW_TITLES` and `SHOW_ROW_ICONS` both `true` reproduces the original shelf * header - an icon badge plus label button above each row's tiles. */ import type { CSSProperties } from "react"; import type { Group } from "./search"; import type { UiState } from "./keyboard"; // ---------------------------------------------------------------- toggles -- /** Tint each shelf panel and its rows with the group's hue below. */ export const SHOW_ROW_TINT = false; /** Show each shelf's title text ("Musik", "Hörbücher", "Podcasts") above its tiles. */ export const SHOW_ROW_TITLES = true; /** Show the small icon badge (🎵/📖/🎙️) beside the title. Stands alone fine with * `SHOW_ROW_TITLES` off (an icon-only header), but the original look needs both. */ export const SHOW_ROW_ICONS = true; /** Vertical gap between shelves on the root browse screen, in px. */ export const ROW_SPACING = 25; /** Fade the album/category grid in (with a slight upward slide) when a group or * category is entered, and the album modal in when it opens. One animation per * container, not per card, so cost stays flat regardless of grid size. */ export const ANIMATE_VIEW_TRANSITIONS = true; /** Frost the glass panels/cards/rows with a real backdrop blur. `backdrop-filter` is * one of the most GPU-expensive CSS effects in the app - a live backdrop copy+blur * per element, repeated for every album card in the unvirtualized grid - so turn * this off on weak hardware (e.g. an old Raspberry Pi) to fall back to a plain * translucent background with no blur. */ export const SHOW_GLASS_BLUR = true; /** Render the play view's animated canvas background (gradient + bubbles, both * redrawn every frame at 60fps). Off falls back to `.stage`'s own static CSS * gradient, which is still underneath the canvas either way. */ export const SHOW_AMBIENCE = true; /** Run the purely decorative CSS animation loops: the room page's bubble field and * the dolphin mascot's bob/swim. Individually cheap (opacity/transform only) but * free to cut on weak hardware. */ export const SHOW_DECORATIVE_ANIMATIONS = true; // ------------------------------------------------------------------ colors -- /** Per-group hue (oklch degrees). The play view's ambient water uses the same * family (`ambienceBaseFor` in `lib/ambience.ts`), so a tinted shelf already hints * at the mood its albums play into - and so does the book/music card tint in * `lib/covers.ts`, which reads `GROUP_HUE.audiobooks`/`GROUP_HUE.music` too. */ export const GROUP_HUE: Record = { music: 210, // today's sea - Dolphin Beats' baseline hue audiobooks: 55, // warm amber - richer than the old shared hue (80)'s dull brown podcasts: 300, // the one otherwise-unused family }; export const GROUP_ICON: Record = { music: "🎵", audiobooks: "📖", podcasts: "🎙️", }; export const GROUP_LABEL: Record = { music: "Musik", audiobooks: "Hörbücher", podcasts: "Podcasts", }; /** How much horizontal space the tab rail's own glass bar claims on the right edge * (its `right` inset plus its rendered width) - scrollable content reserves this much * padding on that side so a full row/grid never renders underneath it. Keep in sync * with the geometry in `TabRail.tsx`. */ export const TAB_RAIL_CLEARANCE = 88; /** Icon/label for the vertical tab rail - one entry per `UiState["page"]`. The * smarthome tab only renders when Home Assistant is configured (see `App.tsx`); the * other two always show. */ export const PAGE_ICON: Record = { music: "🎵", room: "💡", typing: "⌨️", }; export const PAGE_LABEL: Record = { music: "Musik", room: "Mein Zimmer", typing: "Tippen", }; /** A shelf/row's frosted background and border, tinted with its group's hue - or, * with `SHOW_ROW_TINT` off, `{}` so `.glass-panel`'s own neutral CSS shows through. */ export function glassTint(hue: number): CSSProperties { if (!SHOW_ROW_TINT) return {}; return { background: `linear-gradient(160deg, oklch(55% 0.1 ${hue} / .32), oklch(30% 0.06 ${hue} / .14))`, borderColor: `oklch(75% 0.09 ${hue} / .4)`, }; } /** One list row's background, tinted with its group's hue and brighter/more opaque * while it's the currently-playing row - or, with `SHOW_ROW_TINT` off, the same * neutral highlight the row used before tinting existed. */ export function rowTint(hue: number, highlighted: boolean): CSSProperties { if (!SHOW_ROW_TINT) { return { background: `oklch(97% 0.01 210 / ${highlighted ? ".22" : ".10"})` }; } return { background: `oklch(${highlighted ? "62% 0.12" : "42% 0.08"} ${hue} / ${highlighted ? ".34" : ".2"})`, borderColor: `oklch(78% 0.09 ${hue} / ${highlighted ? ".5" : ".28"})`, }; }