'use client' import { create } from 'zustand' const KEY_ENABLED = 'pm_overlay_enabled' const KEY_DESIGN = 'pm_overlay_design' const KEY_STYLE = 'pm_overlay_style' const KEY_ACCENT = 'pm_overlay_accent' const KEY_POSITION = 'pm_overlay_position' const KEY_FONT = 'pm_overlay_font' const KEY_TEXTCOLOR = 'pm_overlay_textcolor' const KEY_SHOWCVR = 'pm_overlay_showcvr' const KEY_SHOWEQ = 'pm_overlay_showeq' const KEY_PALETTE = 'pm_overlay_palette' const KEY_CUSTPALETTES = 'pm_overlay_custpalettes' const KEY_MARGIN = 'pm_overlay_margin' const KEY_SCALE = 'pm_overlay_scale' const KEY_OPACITY = 'pm_overlay_opacity' export type OverlayDesign = 'minimal' | 'card' | 'bar' export type OverlayStyle = | 'classic' | 'aero' | 'retro' | 'neon' | 'clean' | 'y2k' | 'lofi' | 'glam' | 'matrix' export type OverlayPosition = 'bl' | 'br' | 'tl' | 'tr' export interface StyleConfig { bg: string blur: string border: string shadow: string radius: string text: string text2: string eqColor: string fontStyle: 'normal' | 'italic' fontWeight: number letterSpacing: string } export const OVERLAY_STYLES: Record = { classic: { name: 'Классика', desc: 'Тёмное стекло, нейтральный', cfg: { bg: 'rgba(10,10,15,0.82)', blur: '20px', border: '1px solid rgba(255,255,255,0.08)', shadow: '0 8px 32px rgba(0,0,0,0.5)', radius: '16px', text: '#ffffff', text2: 'rgba(255,255,255,0.45)', eqColor: 'var(--accent)', fontStyle: 'normal', fontWeight: 600, letterSpacing: '0', }, }, aero: { name: 'Фрутигер Аеро', desc: 'Глянцевый XP-стиль', cfg: { bg: 'linear-gradient(145deg,rgba(200,235,255,0.55) 0%,rgba(140,195,255,0.4) 100%)', blur: '24px', border: '1.5px solid rgba(255,255,255,0.75)', shadow: '0 4px 20px rgba(80,160,255,0.35),inset 0 1px 0 rgba(255,255,255,0.6)', radius: '22px', text: '#003a6e', text2: 'rgba(0,60,120,0.6)', eqColor: '#0077cc', fontStyle: 'normal', fontWeight: 700, letterSpacing: '-0.02em', }, }, retro: { name: 'Ретро', desc: 'VHS / кассетная эстетика', cfg: { bg: 'rgba(18,8,2,0.93)', blur: '0px', border: '2px solid #b06828', shadow: '0 0 24px rgba(180,100,20,0.45),4px 4px 0 rgba(0,0,0,0.5)', radius: '4px', text: '#f8d090', text2: '#9a6020', eqColor: '#e08030', fontStyle: 'normal', fontWeight: 700, letterSpacing: '0.05em', }, }, neon: { name: 'Неон', desc: 'Киберпанк, светящиеся линии', cfg: { bg: 'rgba(0,0,10,0.9)', blur: '8px', border: '1px solid rgba(var(--accent-rgb),0.55)', shadow: '0 0 24px rgba(var(--accent-rgb),0.35),inset 0 0 16px rgba(var(--accent-rgb),0.06)', radius: '8px', text: 'var(--accent)', text2: 'rgba(var(--accent-rgb),0.55)', eqColor: 'var(--accent)', fontStyle: 'normal', fontWeight: 800, letterSpacing: '0.04em', }, }, clean: { name: 'Минимализм', desc: 'Только текст, без фона', cfg: { bg: 'transparent', blur: '0px', border: 'none', shadow: 'none', radius: '0', text: '#ffffff', text2: 'rgba(255,255,255,0.5)', eqColor: 'var(--accent)', fontStyle: 'normal', fontWeight: 600, letterSpacing: '0', }, }, y2k: { name: 'Y2K', desc: 'Хром, ранние 2000-е', cfg: { bg: 'linear-gradient(160deg,#d8d8e8 0%,#b0b8d0 50%,#c8cce0 100%)', blur: '4px', border: '2px solid rgba(255,255,255,0.9)', shadow: '3px 3px 0 rgba(0,0,80,0.25),inset 0 1px 0 rgba(255,255,255,0.8)', radius: '6px', text: '#000060', text2: '#444488', eqColor: '#0044cc', fontStyle: 'normal', fontWeight: 700, letterSpacing: '-0.01em', }, }, lofi: { name: 'Ло-фай', desc: 'Тёплые тона, уютная атмосфера', cfg: { bg: 'rgba(38,24,12,0.9)', blur: '14px', border: '1px solid rgba(240,180,100,0.18)', shadow: '0 6px 28px rgba(0,0,0,0.45)', radius: '14px', text: '#fde8c0', text2: 'rgba(240,180,100,0.55)', eqColor: '#e8a060', fontStyle: 'italic', fontWeight: 500, letterSpacing: '0.01em', }, }, glam: { name: 'Гламур', desc: 'Золото, роскошь', cfg: { bg: 'linear-gradient(145deg,rgba(28,18,4,0.93) 0%,rgba(18,12,2,0.93) 100%)', blur: '16px', border: '1px solid rgba(212,175,55,0.45)', shadow: '0 8px 32px rgba(0,0,0,0.65),0 0 0 1px rgba(212,175,55,0.2)', radius: '14px', text: '#f0c840', text2: 'rgba(200,150,30,0.65)', eqColor: '#d4af37', fontStyle: 'normal', fontWeight: 700, letterSpacing: '0.02em', }, }, matrix: { name: 'Матрица', desc: 'Зелёный терминал, хакер', cfg: { bg: 'rgba(0,8,0,0.92)', blur: '4px', border: '1px solid rgba(0,255,50,0.3)', shadow: '0 0 20px rgba(0,255,50,0.18)', radius: '4px', text: '#00ff32', text2: 'rgba(0,200,30,0.55)', eqColor: '#00ff32', fontStyle: 'normal', fontWeight: 700, letterSpacing: '0.08em', }, }, } interface OverlayStore { enabled: boolean design: OverlayDesign style: OverlayStyle accentColor: string position: OverlayPosition font: string textColor: string showCover: boolean showEq: boolean palette: string customPalettes: Record> margin: number scale: number opacity: number setEnabled: (v: boolean) => void setDesign: (d: OverlayDesign) => void setStyle: (s: OverlayStyle) => void setAccentColor: (c: string) => void setPosition: (p: OverlayPosition) => void setFont: (f: string) => void setTextColor: (c: string) => void setShowCover: (v: boolean) => void setShowEq: (v: boolean) => void setPalette: (p: string) => void setCustomPaletteField: (style: string, field: string, value: string) => void setMargin: (v: number) => void setScale: (v: number) => void setOpacity: (v: number) => void } const ls = (key: string) => (typeof window !== 'undefined' ? localStorage.getItem(key) : null) const lsSet = (key: string, v: string) => { if (typeof window !== 'undefined') localStorage.setItem(key, v) } export const useOverlayStore = create((set) => ({ enabled: ls(KEY_ENABLED) !== 'false', design: (ls(KEY_DESIGN) ?? 'minimal') as OverlayDesign, style: (ls(KEY_STYLE) ?? 'classic') as OverlayStyle, accentColor: ls(KEY_ACCENT) ?? '#de9cfe', position: (ls(KEY_POSITION) ?? 'bl') as OverlayPosition, font: ls(KEY_FONT) ?? '', textColor: ls(KEY_TEXTCOLOR) ?? '', showCover: ls(KEY_SHOWCVR) !== 'false', showEq: ls(KEY_SHOWEQ) !== 'false', palette: ls(KEY_PALETTE) ?? 'default', customPalettes: (() => { try { return JSON.parse(ls(KEY_CUSTPALETTES) ?? '{}') } catch { return {} } })(), margin: Number(ls(KEY_MARGIN) ?? 24), scale: Number(ls(KEY_SCALE) ?? 1), opacity: Number(ls(KEY_OPACITY) ?? 1), setEnabled: (v) => { lsSet(KEY_ENABLED, String(v)); set({ enabled: v }) }, setDesign: (d) => { lsSet(KEY_DESIGN, d); set({ design: d }) }, setStyle: (s) => { lsSet(KEY_STYLE, s); set({ style: s }) }, setAccentColor: (c) => { lsSet(KEY_ACCENT, c); set({ accentColor: c }) }, setPosition: (p) => { lsSet(KEY_POSITION, p); set({ position: p }) }, setFont: (f) => { lsSet(KEY_FONT, f); set({ font: f }) }, setTextColor: (c) => { lsSet(KEY_TEXTCOLOR, c); set({ textColor: c }) }, setShowCover: (v) => { lsSet(KEY_SHOWCVR, String(v)); set({ showCover: v }) }, setShowEq: (v) => { lsSet(KEY_SHOWEQ, String(v)); set({ showEq: v }) }, setPalette: (p) => { lsSet(KEY_PALETTE, p); set({ palette: p }) }, setCustomPaletteField: (style, field, value) => { set((state) => { const next = { ...state.customPalettes, [style]: { ...(state.customPalettes[style] ?? {}), [field]: value }, } lsSet(KEY_CUSTPALETTES, JSON.stringify(next)) return { customPalettes: next } }) }, setMargin: (v) => { lsSet(KEY_MARGIN, String(v)); set({ margin: v }) }, setScale: (v) => { lsSet(KEY_SCALE, String(v)); set({ scale: v }) }, setOpacity: (v) => { lsSet(KEY_OPACITY, String(v)); set({ opacity: v }) }, }))