Найдено треков:
- {preview.tracks.length}
+ {preview.tracks.length}
{preview.tracks.map((t, i) => (
@@ -673,7 +673,7 @@ export default function PlaylistsPage() {
className="flex items-center gap-1.5 text-[12px] font-display font-bold px-3.5 py-2 rounded-xl transition-all duration-150 cursor-pointer"
style={showForm
? { background: 'rgba(255,255,255,0.06)', border: '1px solid rgba(255,255,255,0.1)', color: 'var(--color-muted)' }
- : { background: '#c8ff00', color: '#0a0a0f' }
+ : { background: 'var(--accent)', color: '#0a0a0f' }
}
>
{showForm ? (
diff --git a/apps/web/src/app/remote/[id]/page.tsx b/apps/web/src/app/remote/[id]/page.tsx
index c06ec9f..87c5283 100644
--- a/apps/web/src/app/remote/[id]/page.tsx
+++ b/apps/web/src/app/remote/[id]/page.tsx
@@ -1,4 +1,4 @@
-'use client'
+'use client'
import { use, useEffect, useRef, useState } from 'react'
@@ -145,14 +145,14 @@ export default function RemotePage({ params }: { params: Promise<{ id: string }>
))}
diff --git a/apps/web/src/components/Header.tsx b/apps/web/src/components/Header.tsx
index f75e718..e2ee817 100644
--- a/apps/web/src/components/Header.tsx
+++ b/apps/web/src/components/Header.tsx
@@ -21,7 +21,7 @@ export default function Header() {
href={href}
className="flex items-center gap-1.5 text-[12px] font-display font-semibold px-3 py-1.5 rounded-xl border transition-all duration-150 hidden sm:flex"
style={active
- ? { background: 'rgba(200,255,0,0.12)', borderColor: 'rgba(200,255,0,0.3)', color: '#c8ff00' }
+ ? { background: 'rgba(var(--accent-rgb),0.12)', borderColor: 'rgba(var(--accent-rgb),0.3)', color: 'var(--accent)' }
: { background: 'rgba(255,255,255,0.04)', borderColor: 'rgba(255,255,255,0.07)', color: 'var(--color-muted)' }
}
>
diff --git a/apps/web/src/components/Player/PlayerCard.tsx b/apps/web/src/components/Player/PlayerCard.tsx
index 17f328f..80b3a07 100644
--- a/apps/web/src/components/Player/PlayerCard.tsx
+++ b/apps/web/src/components/Player/PlayerCard.tsx
@@ -273,11 +273,11 @@ export default function PlayerCard({ onTrackEnd }: PlayerCardProps) {
title={saved ? 'Забыть версию' : 'Запомнить эту версию'}
className="w-[26px] h-[26px] rounded-full border flex items-center justify-center shrink-0 transition-all duration-150 cursor-pointer hover:border-accent/40"
style={{
- borderColor: saved ? 'rgba(200,255,0,0.4)' : 'rgba(255,255,255,0.07)',
- background: saved ? 'rgba(200,255,0,0.08)' : 'transparent',
+ borderColor: saved ? 'rgba(var(--accent-rgb),0.4)' : 'rgba(255,255,255,0.07)',
+ background: saved ? 'rgba(var(--accent-rgb),0.08)' : 'transparent',
}}
>
-
+
@@ -316,11 +316,11 @@ export default function PlayerCard({ onTrackEnd }: PlayerCardProps) {
title="Добавить в плейлист"
className="w-9 h-9 rounded-[9px] border flex items-center justify-center shrink-0 transition-all duration-150 cursor-pointer sm:w-8 sm:h-8"
style={{
- borderColor: playlistOpen ? 'rgba(200,255,0,0.35)' : 'rgba(255,255,255,0.07)',
- background: playlistOpen ? 'rgba(200,255,0,0.06)' : 'transparent',
+ borderColor: playlistOpen ? 'rgba(var(--accent-rgb),0.35)' : 'rgba(255,255,255,0.07)',
+ background: playlistOpen ? 'rgba(var(--accent-rgb),0.06)' : 'transparent',
}}
>
-
+
@@ -338,11 +338,11 @@ export default function PlayerCard({ onTrackEnd }: PlayerCardProps) {
title={favorited ? 'Убрать из избранного' : 'В избранное'}
className="w-9 h-9 rounded-[9px] border flex items-center justify-center shrink-0 transition-all duration-150 cursor-pointer sm:w-8 sm:h-8"
style={{
- borderColor: favorited ? 'rgba(200,255,0,0.4)' : 'rgba(255,255,255,0.07)',
- background: favorited ? 'rgba(200,255,0,0.08)' : 'transparent',
+ borderColor: favorited ? 'rgba(var(--accent-rgb),0.4)' : 'rgba(255,255,255,0.07)',
+ background: favorited ? 'rgba(var(--accent-rgb),0.08)' : 'transparent',
}}
>
-
+
diff --git a/apps/web/src/components/Queue/QueueCard.tsx b/apps/web/src/components/Queue/QueueCard.tsx
index 8e178c6..790605b 100644
--- a/apps/web/src/components/Queue/QueueCard.tsx
+++ b/apps/web/src/components/Queue/QueueCard.tsx
@@ -75,7 +75,7 @@ export default function QueueCard() {
data-idx={i}
draggable
className="q-item flex items-center gap-2 px-4 py-2 border-b border-white/[0.07] last:border-b-0 cursor-pointer hover:bg-surface2 transition-colors duration-100 select-none relative sm:px-3"
- style={{ background: active ? 'rgba(200,255,0,0.04)' : undefined }}
+ style={{ background: active ? 'rgba(var(--accent-rgb),0.04)' : undefined }}
onClick={(e) => handleQueueClick(e, i)}
onDragStart={(e) => onDragStart(i, e.currentTarget)}
onDragEnd={(e) => onDragEnd(e.currentTarget)}
diff --git a/apps/web/src/components/SoloTab/SoloTab.tsx b/apps/web/src/components/SoloTab/SoloTab.tsx
index 7b53b73..570ff4d 100644
--- a/apps/web/src/components/SoloTab/SoloTab.tsx
+++ b/apps/web/src/components/SoloTab/SoloTab.tsx
@@ -34,8 +34,8 @@ function TopChartsCard({ tracks }: { tracks: string[] }) {
onClick={handlePlay}
className="text-[12px] font-display font-bold px-3 py-1.5 rounded-[9px] transition-all duration-200 cursor-pointer whitespace-nowrap shrink-0 mt-1"
style={{
- background: launched ? '#c8ff00' : 'rgba(200,255,0,0.15)',
- color: launched ? '#0a0a0f' : '#c8ff00',
+ background: launched ? 'var(--accent)' : 'rgba(var(--accent-rgb),0.15)',
+ color: launched ? '#0a0a0f' : 'var(--accent)',
}}
>
{launched ? '▶ Играет' : '▶ Слушать'}
diff --git a/apps/web/src/components/ThemeApplier.tsx b/apps/web/src/components/ThemeApplier.tsx
new file mode 100644
index 0000000..be58d1d
--- /dev/null
+++ b/apps/web/src/components/ThemeApplier.tsx
@@ -0,0 +1,16 @@
+'use client'
+
+import { useEffect } from 'react'
+import { useThemeStore, ACCENT_PRESETS } from '@/store/themeStore'
+
+export default function ThemeApplier() {
+ const { accentIdx } = useThemeStore()
+
+ useEffect(() => {
+ const preset = ACCENT_PRESETS[accentIdx] ?? ACCENT_PRESETS[0]
+ document.documentElement.style.setProperty('--accent', preset.accent)
+ document.documentElement.style.setProperty('--accent-rgb', preset.rgb)
+ }, [accentIdx])
+
+ return null
+}
diff --git a/apps/web/src/lib/colors.ts b/apps/web/src/lib/colors.ts
index e8d8179..54d9708 100644
--- a/apps/web/src/lib/colors.ts
+++ b/apps/web/src/lib/colors.ts
@@ -1,7 +1,7 @@
import type { Color } from '@/types'
export const COLORS: Color[] = [
- { bg: 'rgba(200,255,0,0.1)', text: '#c8ff00' },
+ { bg: 'rgba(var(--accent-rgb),0.1)', text: 'var(--accent)' },
{ bg: 'rgba(255,60,172,0.1)', text: '#ff3cac' },
{ bg: 'rgba(0,212,255,0.1)', text: '#00d4ff' },
{ bg: 'rgba(255,165,0,0.1)', text: '#ffa500' },
@@ -29,5 +29,5 @@ export function hexToRgba(color: string, alpha: number): string {
const b = parseInt(color.slice(5, 7), 16)
return `rgba(${r},${g},${b},${alpha})`
}
- return `rgba(200,255,0,${alpha})`
+ return `rgba(var(--accent-rgb),${alpha})`
}
diff --git a/apps/web/src/store/themeStore.ts b/apps/web/src/store/themeStore.ts
new file mode 100644
index 0000000..82bd776
--- /dev/null
+++ b/apps/web/src/store/themeStore.ts
@@ -0,0 +1,38 @@
+'use client'
+
+import { create } from 'zustand'
+
+export interface AccentPreset {
+ name: string
+ accent: string
+ rgb: string
+}
+
+export const ACCENT_PRESETS: AccentPreset[] = [
+ { name: 'Лайм', accent: '#c8ff00', rgb: '200,255,0' },
+ { name: 'Синий', accent: '#00D4FF', rgb: '0,212,255' },
+ { name: 'Розовый', accent: '#FF2D78', rgb: '255,45,120' },
+ { name: 'Фиолет', accent: '#A855F7', rgb: '168,85,247' },
+ { name: 'Оранж', accent: '#FF6B35', rgb: '255,107,53' },
+ { name: 'Минт', accent: '#00FFB2', rgb: '0,255,178' },
+]
+
+const STORAGE_KEY = 'pm_accent'
+
+interface ThemeStore {
+ accentIdx: number
+ setAccent: (idx: number) => void
+}
+
+export const useThemeStore = create((set) => ({
+ accentIdx: (() => {
+ if (typeof window === 'undefined') return 0
+ const saved = localStorage.getItem(STORAGE_KEY)
+ const idx = saved !== null ? parseInt(saved, 10) : 0
+ return idx >= 0 && idx < ACCENT_PRESETS.length ? idx : 0
+ })(),
+ setAccent: (idx) => {
+ if (typeof window !== 'undefined') localStorage.setItem(STORAGE_KEY, String(idx))
+ set({ accentIdx: idx })
+ },
+}))
diff --git a/apps/web/tailwind.config.ts b/apps/web/tailwind.config.ts
index 4c1124e..35bed50 100644
--- a/apps/web/tailwind.config.ts
+++ b/apps/web/tailwind.config.ts
@@ -8,7 +8,9 @@ const config: Config = {
bg: '#0a0a0f',
surface: '#12121a',
surface2: '#1a1a26',
- accent: '#c8ff00',
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
+ accent: (({ opacityValue }: { opacityValue?: string }) =>
+ opacityValue !== undefined ? `rgba(var(--accent-rgb),${opacityValue})` : 'var(--accent)') as any,
muted: '#555555',
'app-text': '#f0f0f0',
},