/* ============================================================ Bri-Tunes — retrofuture / cyberpunk skin ============================================================ */ @font-face { font-family: 'Orbitron'; src: url('/static/vendor/fonts/Orbitron.woff2') format('woff2'); font-weight: 400 900; font-display: swap; } @font-face { font-family: 'Inter'; src: url('/static/vendor/fonts/Inter.woff2') format('woff2'); font-weight: 400 700; font-display: swap; } :root { --bg: #05060d; --bg-panel: #0c0e1a; --bg-inset: #141830; --grid: #1a1f3d; --fg: #e8ecff; --muted: #7a84b8; --neon-cyan: #00e5ff; --neon-magenta: #ff2bd6; --neon-violet: #8f5bff; --neon-amber: #ffb347; --danger: #ff4d6d; --border: rgba(143, 91, 255, 0.45); --border-strong: rgba(143, 91, 255, 0.85); --glow-cyan: 0 0 8px rgba(0, 229, 255, 0.75), 0 0 18px rgba(0, 229, 255, 0.35); --glow-magenta: 0 0 8px rgba(255, 43, 214, 0.75), 0 0 18px rgba(255, 43, 214, 0.35); --glow-violet: 0 0 6px rgba(143, 91, 255, 0.9), 0 0 16px rgba(143, 91, 255, 0.4); --radius: 4px; } * { box-sizing: border-box; } html, body { margin: 0; padding: 0; } body { font-family: 'Inter', system-ui, -apple-system, Segoe UI, Roboto, sans-serif; background: var(--bg); color: var(--fg); line-height: 1.55; padding-bottom: 140px; min-height: 100vh; position: relative; overflow-x: hidden; } /* ---------- Background canvas ---------- */ #bg-canvas { position: fixed; inset: 0; width: 100%; height: 100%; z-index: 0; pointer-events: none; } /* ---------- Scanlines + vignette overlays ---------- */ body::before { content: ""; position: fixed; inset: 0; z-index: 2; pointer-events: none; background: repeating-linear-gradient( to bottom, rgba(255, 255, 255, 0.035) 0px, rgba(255, 255, 255, 0.035) 1px, transparent 1px, transparent 3px ); mix-blend-mode: overlay; } body::after { content: ""; position: fixed; inset: 0; z-index: 3; pointer-events: none; background: radial-gradient(ellipse at center, rgba(0,0,0,0.35) 0%, rgba(0,0,0,0.55) 60%, rgba(0,0,0,0.8) 100%); } /* Everything interactive sits above the background canvas and below the overlays. */ .site-header, main.container, .player-bar, .flash { position: relative; z-index: 4; } /* ---------- Typography ---------- */ h1, h2, h3, .brand, .card-title, .tabs a, .data-table th, .btn-primary, .btn-small, .btn-play { font-family: 'Orbitron', 'Inter', sans-serif; letter-spacing: 0.08em; text-transform: uppercase; } h1 { font-size: 1.7rem; margin: 1.25rem 0 0.6rem; text-shadow: var(--glow-violet); } h2 { font-size: 1.15rem; margin: 1.5rem 0 0.75rem; color: var(--neon-cyan); text-shadow: var(--glow-cyan); } h3 { font-size: 1rem; color: var(--neon-magenta); text-shadow: var(--glow-magenta); } a { color: var(--neon-cyan); text-decoration: none; transition: color .15s, text-shadow .15s; } a:hover { color: #fff; text-shadow: var(--glow-cyan); text-decoration: none; } .muted { color: var(--muted); } .small { font-size: 0.82rem; letter-spacing: 0.02em; } /* ---------- Layout ---------- */ .container { max-width: 1040px; margin: 0 auto; padding: 1rem 1.25rem; } .site-header { background: linear-gradient(180deg, rgba(12,14,26,0.92), rgba(12,14,26,0.75)); border-bottom: 1px solid var(--border-strong); box-shadow: 0 1px 0 rgba(0, 229, 255, 0.25), 0 0 24px rgba(143, 91, 255, 0.2); backdrop-filter: blur(6px); -webkit-backdrop-filter: blur(6px); position: sticky; top: 0; z-index: 20; } .header-inner { display: flex; align-items: center; justify-content: space-between; padding: 0.75rem 1.25rem; max-width: 1040px; margin: 0 auto; } .brand { font-weight: 700; font-size: 1.15rem; color: var(--fg); text-shadow: var(--glow-magenta); } .brand:hover { color: #fff; text-shadow: var(--glow-cyan); } .nav { display: flex; gap: 1.1rem; align-items: center; } .nav a { color: var(--muted); font-family: 'Orbitron', sans-serif; text-transform: uppercase; font-size: 0.78rem; letter-spacing: 0.12em; padding: 0.4rem 0.1rem; border-bottom: 1px solid transparent; } .nav a.active, .nav a:hover { color: var(--neon-cyan); border-bottom-color: var(--neon-cyan); text-shadow: var(--glow-cyan); } /* ---------- Buttons ---------- */ .btn-primary, .btn-small { background: transparent; color: var(--neon-cyan); border: 1px solid var(--neon-cyan); padding: 0.55rem 1rem; border-radius: var(--radius); font-weight: 600; font-size: 0.82rem; cursor: pointer; box-shadow: var(--glow-cyan), inset 0 0 0 1px rgba(0,229,255,0.1); transition: transform .12s, background .15s, color .15s, box-shadow .15s; } .btn-primary:hover, .btn-small:hover { background: var(--neon-cyan); color: #05060d; transform: translateY(-1px); text-decoration: none; box-shadow: 0 0 18px rgba(0,229,255,0.85), 0 0 36px rgba(0,229,255,0.45); } .btn-small { padding: 0.35rem 0.75rem; font-size: 0.72rem; } .btn-link { color: var(--muted); margin-left: 0.75rem; font-size: 0.82rem; } .btn-link:hover { color: var(--neon-magenta); text-shadow: var(--glow-magenta); } /* Playlist action row — Play All + Shuffle All on left, Now Playing on right */ .playlist-btn-row { display: flex; align-items: center; justify-content: space-between; gap: 0.5rem; flex-wrap: wrap; margin: 0.25rem 0; } .playlist-btn-left { display: flex; align-items: center; gap: 0.5rem; flex-wrap: wrap; } /* "Now Playing" re-open button — filled cyan to signal active state */ .btn-nowplaying { background: var(--neon-cyan); color: #05060d; border: 1px solid var(--neon-cyan); padding: 0.55rem 1rem; border-radius: var(--radius); font-weight: 700; font-size: 0.82rem; cursor: pointer; box-shadow: 0 0 14px rgba(0,229,255,0.6), 0 0 28px rgba(0,229,255,0.25); transition: transform .12s, box-shadow .15s; animation: np-btn-pulse 2.5s ease-in-out infinite; } .btn-nowplaying:hover { transform: translateY(-1px); box-shadow: 0 0 22px rgba(0,229,255,0.9), 0 0 44px rgba(0,229,255,0.4); } @keyframes np-btn-pulse { 0%, 100% { box-shadow: 0 0 14px rgba(0,229,255,0.6), 0 0 28px rgba(0,229,255,0.25); } 50% { box-shadow: 0 0 20px rgba(0,229,255,0.85), 0 0 40px rgba(0,229,255,0.4); } } /* ---------- Share row ---------- */ .share-row { display: flex; align-items: center; gap: 0.5rem; margin-top: 0.9rem; flex-wrap: wrap; } .share-label { font-family: 'Orbitron', sans-serif; font-size: 0.62rem; text-transform: uppercase; letter-spacing: 0.12em; color: var(--muted); margin-right: 0.15rem; } .share-btn { display: inline-flex; align-items: center; gap: 0.35rem; background: rgba(255,179,71,0.07); border: 1px solid rgba(255,179,71,0.35); border-radius: var(--radius); color: var(--neon-amber); padding: 0.3rem 0.55rem; font-size: 0.72rem; font-family: 'Orbitron', sans-serif; text-decoration: none; cursor: pointer; transition: color .15s, border-color .15s, box-shadow .15s, background .15s; line-height: 1; } .share-btn svg { width: 14px; height: 14px; flex-shrink: 0; } .share-btn:hover { background: rgba(255,255,255,0.09); border-color: var(--neon-cyan); color: var(--neon-cyan); box-shadow: 0 0 8px rgba(0,229,255,0.25); text-decoration: none; } .share-btn--copied { border-color: var(--neon-cyan); color: var(--neon-cyan); } .share-btn--x:hover { border-color: #fff; color: #fff; box-shadow: 0 0 8px rgba(255,255,255,0.2); } .share-btn--facebook:hover { border-color: #1877f2; color: #1877f2; box-shadow: 0 0 8px rgba(24,119,242,0.3); } .share-btn--reddit:hover { border-color: #ff4500; color: #ff4500; box-shadow: 0 0 8px rgba(255,69,0,0.3); } .share-btn--whatsapp:hover { border-color: #25d366; color: #25d366; box-shadow: 0 0 8px rgba(37,211,102,0.3); } .share-btn--mastodon:hover { border-color: #6364ff; color: #6364ff; box-shadow: 0 0 8px rgba(99,100,255,0.35); } button.linklike { background: none; border: none; color: var(--neon-cyan); padding: 0; cursor: pointer; font: inherit; } button.linklike:hover { color: #fff; text-shadow: var(--glow-cyan); } button.linklike.danger { color: var(--danger); } button.linklike.danger:hover { color: #fff; text-shadow: 0 0 6px var(--danger); } .inline-form { display: inline; margin-left: 0.5rem; } .inline-row { display: flex; gap: 0.5rem; align-items: center; margin-top: 0.5rem; } /* ---------- Focus ring ---------- */ :focus-visible { outline: 2px dashed var(--neon-magenta); outline-offset: 3px; } /* ---------- Hero ---------- */ .hero { padding: 2rem 0 1rem; } .hero h1 { margin: 0 0 0.25rem 0; font-size: 2.1rem; background: linear-gradient(90deg, var(--neon-cyan), var(--neon-magenta), var(--neon-violet)); background-clip: text; -webkit-background-clip: text; color: transparent; text-shadow: none; } /* ---------- Cards / grid ---------- */ .grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(180px, 1fr)); gap: 1rem; } .card { background: var(--bg-panel); border: 1px solid var(--border); border-radius: var(--radius); overflow: hidden; display: flex; flex-direction: column; color: var(--fg); position: relative; transition: transform .15s, border-color .15s, box-shadow .15s; } .card::before, .card::after { content: ""; position: absolute; width: 12px; height: 12px; border: 1px solid var(--neon-cyan); pointer-events: none; } .card::before { top: 4px; left: 4px; border-right: none; border-bottom: none; } .card::after { bottom: 4px; right: 4px; border-left: none; border-top: none; } .card:hover { transform: translateY(-2px); border-color: var(--neon-magenta); box-shadow: 0 0 0 1px var(--neon-magenta), 0 0 24px rgba(255,43,214,0.35); text-decoration: none; } .card.playlist-active { border-color: var(--neon-cyan); box-shadow: 0 0 0 1px var(--neon-cyan), 0 0 20px rgba(0,229,255,0.3); } .card.playlist-active:hover { border-color: var(--neon-cyan); box-shadow: 0 0 0 1px var(--neon-cyan), 0 0 32px rgba(0,229,255,0.5); } .card img { width: 100%; aspect-ratio: 1 / 1; object-fit: cover; display: block; } .cover-fallback { aspect-ratio: 1 / 1; display: flex; align-items: center; justify-content: center; background: linear-gradient(135deg, #1a1f3d, #0c0e1a); font-size: 2.5rem; color: var(--neon-violet); text-shadow: var(--glow-violet); } .card-body { padding: 0.65rem 0.85rem; display: flex; flex-direction: column; flex: 1; } .card-title { font-size: 0.85rem; color: var(--fg); } .card-creator { font-size: 0.75rem; font-style: italic; color: var(--muted); margin-bottom: 0.35rem; opacity: 0.75; } .card-footer { margin-top: auto; padding-top: 0.5rem; } /* ---------- Visibility badges ---------- */ .badge { font-family: 'Orbitron', sans-serif; font-size: 0.58rem; font-weight: 700; letter-spacing: 0.1em; text-transform: uppercase; padding: 0.12rem 0.42rem; border-radius: 3px; vertical-align: middle; line-height: 1; white-space: nowrap; } .badge-public { color: var(--neon-cyan); border: 1px solid var(--neon-cyan); box-shadow: 0 0 5px rgba(0,229,255,0.35); } .badge-logged-in { color: var(--neon-amber); border: 1px solid var(--neon-amber); box-shadow: 0 0 5px rgba(255,179,71,0.4); } .badge-private { color: var(--neon-magenta); border: 1px solid var(--neon-magenta); box-shadow: 0 0 5px rgba(255,43,214,0.4); } /* ---------- Visibility radio fieldset ---------- */ .visibility-field { border: 1px solid var(--border); border-radius: var(--radius); padding: 0.75rem 1rem; display: flex; flex-direction: column; gap: 0.5rem; } .visibility-field legend { font-family: 'Orbitron', sans-serif; font-size: 0.72rem; text-transform: uppercase; letter-spacing: 0.12em; color: var(--muted); padding: 0 0.4rem; } /* ---------- Song list ---------- */ .song-list { list-style: none; margin: 0; padding: 0; } .song-row { display: flex; align-items: center; gap: 0.75rem; padding: 0.55rem 0.6rem; border-bottom: 1px solid rgba(143, 91, 255, 0.18); transition: background .15s; } .song-row:hover { background: rgba(143, 91, 255, 0.08); } .song-cover { width: 44px; height: 44px; border-radius: 4px; object-fit: cover; border: 1px solid var(--border); } .song-cover.cover-fallback { font-size: 1.25rem; } .song-main { flex: 1; min-width: 0; } .song-title { display: block; color: var(--fg); font-weight: 600; } .song-row:hover .song-title { color: var(--neon-cyan); text-shadow: var(--glow-cyan); } .song-meta { width: 60px; text-align: right; font-family: 'Orbitron', monospace; font-size: 0.75rem; color: var(--muted); } /* ── Now-playing highlight ── */ @keyframes now-playing-pulse { 0%, 100% { background: rgba(0,255,255,0.05); box-shadow: inset 3px 0 0 var(--neon-cyan), inset 4px 0 12px rgba(0,255,255,0.15); } 50% { background: rgba(0,255,255,0.10); box-shadow: inset 3px 0 0 var(--neon-cyan), inset 4px 0 22px rgba(0,255,255,0.28); } } @keyframes eq-bar { 0%, 100% { height: 3px; } 50% { height: 14px; } } .song-row.now-playing { animation: now-playing-pulse 2s ease-in-out infinite; } .song-row.now-playing .song-title { color: var(--neon-cyan); text-shadow: var(--glow-cyan); } .eq-bars { display: none; align-items: flex-end; gap: 2px; height: 16px; flex-shrink: 0; } .song-row.now-playing .eq-bars { display: flex; } .eq-bars span { display: block; width: 3px; border-radius: 1px; background: var(--neon-cyan); box-shadow: 0 0 4px var(--neon-cyan); animation: eq-bar 0.7s ease-in-out infinite alternate; } .eq-bars span:nth-child(1) { animation-duration: 0.6s; animation-delay: 0s; } .eq-bars span:nth-child(2) { animation-duration: 0.8s; animation-delay: 0.15s; } .eq-bars span:nth-child(3) { animation-duration: 0.5s; animation-delay: 0.3s; } .btn-play { background: transparent; color: var(--neon-magenta); border: 1px solid var(--neon-magenta); padding: 0.35rem 0.75rem; border-radius: var(--radius); cursor: pointer; font-size: 0.72rem; box-shadow: 0 0 6px rgba(255,43,214,0.35); transition: all .15s; } .btn-play:hover { background: var(--neon-magenta); color: #05060d; box-shadow: var(--glow-magenta); } /* ---------- Song detail ---------- */ .song-detail { display: flex; gap: 1.5rem; align-items: flex-start; padding: 1rem 0 2rem; } .song-detail-cover { width: 220px; height: 220px; border-radius: var(--radius); object-fit: cover; border: 1px solid var(--neon-violet); box-shadow: var(--glow-violet); flex-shrink: 0; } .song-detail-info { display: flex; justify-content: space-between; align-items: flex-start; gap: 1.5rem; flex: 1; min-width: 0; } .song-detail-meta { flex: 1; min-width: 0; } /* Creator card on detail pages */ .detail-creator-card { display: flex; flex-direction: column; align-items: center; gap: 0.35rem; flex-shrink: 0; text-align: center; min-width: 80px; text-decoration: none; border-radius: 8px; padding: 0.5rem; transition: background 0.15s ease, box-shadow 0.15s ease; } a.detail-creator-card:hover { background: var(--bg-panel); box-shadow: 0 0 0 1px var(--neon-cyan), 0 0 10px rgba(0, 255, 255, 0.2); } .detail-creator-avatar { width: 72px; height: 72px; border-radius: 50%; object-fit: cover; border: 2px solid var(--border); background: var(--bg-inset); } .detail-creator-placeholder { display: flex; align-items: center; justify-content: center; font-size: 1.75rem; font-weight: bold; color: var(--muted); } .detail-creator-label { font-size: 0.7rem; color: var(--muted); margin: 0; text-transform: uppercase; letter-spacing: 0.05em; } .detail-creator-name { font-size: 0.82rem; color: var(--fg); margin: 0; font-weight: 600; } /* ---------- Forms ---------- */ .form-card { background: var(--bg-panel); border: 1px solid var(--border); border-radius: var(--radius); padding: 1.5rem 1.75rem; margin: 1.25rem 0; max-width: 580px; position: relative; box-shadow: 0 0 0 1px rgba(143, 91, 255, 0.15), 0 0 28px rgba(143, 91, 255, 0.1); } .form-card::before, .form-card::after { content: ""; position: absolute; width: 14px; height: 14px; border: 1px solid var(--neon-cyan); pointer-events: none; } .form-card::before { top: 6px; left: 6px; border-right: none; border-bottom: none; } .form-card::after { bottom: 6px; right: 6px; border-left: none; border-top: none; } .stacked { display: flex; flex-direction: column; gap: 1rem; } .current-cover-wrap { margin: 0.25rem 0; } .current-cover-thumb { width: 80px; height: 80px; object-fit: cover; border-radius: var(--radius); border: 1px solid var(--border); } .stacked label { display: flex; flex-direction: column; gap: 0.35rem; font-size: 0.72rem; color: var(--muted); font-family: 'Orbitron', sans-serif; text-transform: uppercase; letter-spacing: 0.12em; } .stacked input[type=text], .stacked input[type=email], .stacked input[type=password], .stacked input[type=number], .stacked textarea, .stacked select, .stacked input[type=search] { background: var(--bg-inset); color: var(--fg); border: 1px solid var(--border); border-radius: var(--radius); padding: 0.6rem 0.8rem; font: inherit; font-family: 'Inter', sans-serif; text-transform: none; letter-spacing: 0; transition: border-color .15s, box-shadow .15s; } .stacked input:focus, .stacked textarea:focus, .stacked select:focus { outline: none; border-color: var(--neon-cyan); box-shadow: var(--glow-cyan); } .stacked input[type=file] { color: var(--muted); font-family: 'Inter', sans-serif; } .stacked .row { flex-direction: row; gap: 0.75rem; align-items: center; } .stacked .checkbox { flex-direction: row; align-items: center; gap: 0.5rem; } .err { color: var(--danger); font-size: 0.75rem; text-shadow: 0 0 4px rgba(255, 77, 109, 0.6); } /* ---------- Search ---------- */ .search-form { display: flex; gap: 0.5rem; align-items: center; margin: 1rem 0; } .search-form input[type=search] { flex: 1; background: var(--bg-inset); color: var(--fg); border: 1px solid var(--border); padding: 0.6rem 0.9rem; border-radius: var(--radius); font: inherit; } .search-form input[type=search]:focus { outline: none; border-color: var(--neon-cyan); box-shadow: var(--glow-cyan); } .search-form button { background: transparent; color: var(--neon-cyan); border: 1px solid var(--neon-cyan); padding: 0.6rem 1.1rem; border-radius: var(--radius); cursor: pointer; font-family: 'Orbitron', sans-serif; font-size: 0.78rem; letter-spacing: 0.1em; } .search-form button:hover { background: var(--neon-cyan); color: #05060d; } .pagination { display: flex; gap: 1rem; align-items: center; padding: 1rem 0; } /* ---------- Flash ---------- */ .flash { margin: 0.75rem auto; max-width: 1040px; padding: 0.7rem 1rem; border-radius: var(--radius); font-family: 'Orbitron', sans-serif; font-size: 0.78rem; text-transform: uppercase; letter-spacing: 0.08em; animation: glitch-in .4s ease-out; } .flash-success { background: rgba(0, 229, 255, 0.06); color: var(--neon-cyan); border: 1px solid var(--neon-cyan); box-shadow: var(--glow-cyan); } .flash-error { background: rgba(255, 77, 109, 0.06); color: var(--danger); border: 1px solid var(--danger); box-shadow: 0 0 10px rgba(255, 77, 109, 0.5); } .flash-warning { background: rgba(255, 179, 71, 0.08); color: var(--neon-amber); border: 1px solid rgba(255, 179, 71, 0.4); box-shadow: 0 0 8px rgba(255, 179, 71, 0.3); } @keyframes glitch-in { 0% { transform: translate(0); opacity: 0; } 20% { transform: translate(-4px, 2px); opacity: 1; } 40% { transform: translate(4px, -1px); } 60% { transform: translate(-2px, 1px); } 100% { transform: translate(0); } } /* ---------- Admin tabs + tables ---------- */ .row-between { display: flex; justify-content: space-between; align-items: center; } .tabs { display: flex; gap: 1rem; border-bottom: 1px solid var(--border); margin: 1rem 0; } .tabs a { padding: 0.55rem 0.5rem; color: var(--muted); font-size: 0.78rem; border-bottom: 2px solid transparent; transition: color .15s, border-color .15s, text-shadow .15s; } .tabs a.active { color: var(--neon-cyan); border-bottom-color: var(--neon-cyan); text-shadow: var(--glow-cyan); } .tabs a:hover { color: var(--neon-cyan); text-decoration: none; } .data-table { width: 100%; border-collapse: collapse; } .data-table th, .data-table td { text-align: left; padding: 0.65rem 0.7rem; border-bottom: 1px solid rgba(143, 91, 255, 0.2); } .data-table th { color: var(--neon-violet); font-weight: 600; font-size: 0.72rem; letter-spacing: 0.12em; } .data-table tr:hover td { background: rgba(0, 229, 255, 0.04); } .data-table .actions { white-space: nowrap; font-size: 0.85rem; } .data-table tr.row-disabled td { opacity: 0.45; } /* ---------- Social buttons ---------- */ .btn-social { background: none; border: none; cursor: pointer; color: var(--muted); font-size: 0.8rem; padding: 2px 5px; border-radius: 4px; display: inline-flex; align-items: center; gap: 3px; transition: color 0.15s, background 0.15s; line-height: 1; } .btn-social:hover { color: var(--fg); background: rgba(255,255,255,0.06); } .btn-social[data-social-action="like"].active { color: var(--neon-cyan); text-shadow: var(--glow-cyan); } .btn-social[data-social-action="favorite"].active { color: var(--neon-amber); text-shadow: 0 0 8px rgba(255,179,71,0.7); } .btn-social:disabled { opacity: 0.5; cursor: wait; } .song-social { display: flex; align-items: center; gap: 2px; } .social-row { display: flex; gap: 4px; margin: 0.4rem 0 0.6rem; } .card-social { display: flex; gap: 4px; padding-top: 0.4rem; border-top: 1px solid rgba(255,255,255,0.06); } /* ---------- Lightbox ---------- */ .lb-trigger { cursor: zoom-in; transition: transform 0.18s ease, box-shadow 0.18s ease; } .lb-trigger:hover { transform: scale(1.04); box-shadow: 0 0 0 3px var(--neon-cyan), var(--glow-cyan); } /* Flanking 3D canvas objects — always above all overlays */ .oo-canvas { z-index: 3100; } #lb-overlay { display: none; position: fixed; inset: 0; background: transparent; z-index: 3000; align-items: center; justify-content: center; cursor: zoom-out; overflow: hidden; } #lb-overlay.lb-open { display: flex; animation: lb-fade-in-synthwave 0.22s ease forwards; } #lb-overlay.lb-closing { animation: lb-fade-out-synthwave 0.2s ease forwards; } /* Dark fade for overlay open/close — color comes from the animated ::before */ @keyframes lb-fade-in-synthwave { from { background: rgba(0, 0, 0, 0); } to { background: rgba(5, 6, 13, 0.82); } } @keyframes lb-fade-out-synthwave { from { background: rgba(5, 6, 13, 0.82); } to { background: rgba(0, 0, 0, 0); } } /* Animated synthwave plasma — spins on both overlays */ #lb-overlay::before, #np-overlay::before { content: ''; position: absolute; top: 50%; left: 50%; width: 220vmax; height: 220vmax; transform: translate(-50%, -50%) rotate(0deg) scale(1); background: conic-gradient( from 0deg at 50% 50%, rgba(102, 15, 87, 0.90) 0deg, rgba(255, 43, 214, 0.78) 60deg, rgba(143, 91, 255, 0.68) 110deg, rgba( 8, 10, 45, 0.88) 155deg, rgba( 8, 10, 45, 0.88) 185deg, rgba(150, 72, 12, 0.84) 225deg, rgba(230, 105, 18, 0.75) 275deg, rgba(255, 43, 214, 0.60) 320deg, rgba(102, 15, 87, 0.90) 360deg ); filter: blur(42px); opacity: 0; pointer-events: none; z-index: -1; } #lb-overlay.lb-open::before, #np-overlay.np-open::before { animation: overlay-plasma-in 0.4s ease forwards, overlay-plasma-spin 60s linear infinite; } #lb-overlay.lb-closing::before, #np-overlay.np-closing::before { animation: overlay-plasma-out 0.22s ease forwards; } @keyframes overlay-plasma-in { from { opacity: 0; } to { opacity: 1; } } @keyframes overlay-plasma-out { from { opacity: 1; } to { opacity: 0; } } @keyframes overlay-plasma-spin { 0% { transform: translate(-50%, -50%) rotate( 0deg) scale(1.00); } 25% { transform: translate(-50%, -50%) rotate( 90deg) scale(1.06); } 50% { transform: translate(-50%, -50%) rotate(180deg) scale(0.97); } 75% { transform: translate(-50%, -50%) rotate(270deg) scale(1.04); } 100% { transform: translate(-50%, -50%) rotate(360deg) scale(1.00); } } @keyframes lb-fade-in { from { background: rgba(0,0,0,0); } to { background: rgba(0,0,0,0.88); } } @keyframes lb-fade-out { from { background: rgba(0,0,0,0.88); } to { background: rgba(0,0,0,0); } } .lb-container { position: relative; z-index: 1; cursor: default; border-radius: var(--radius); overflow: hidden; max-width: min(90vw, 90vh); max-height: 90vh; box-shadow: 0 0 0 2px var(--neon-violet), 0 0 40px rgba(143,91,255,0.5); } #lb-overlay.lb-open .lb-container { animation: lb-zoom-in 0.28s cubic-bezier(0.34, 1.45, 0.64, 1) forwards; } #lb-overlay.lb-closing .lb-container { animation: lb-zoom-out 0.2s ease forwards; } @keyframes lb-zoom-in { from { transform: scale(0.15); opacity: 0; } to { transform: scale(1); opacity: 1; } } @keyframes lb-zoom-out { from { transform: scale(1); opacity: 1; } to { transform: scale(0.15); opacity: 0; } } .lb-img { display: block; max-width: min(90vw, 90vh); max-height: 90vh; width: auto; height: auto; object-fit: contain; } .lb-close { position: absolute; top: 10px; right: 10px; width: 30px; height: 30px; background: rgba(0,0,0,0.65); border: 1px solid rgba(255,255,255,0.3); border-radius: 4px; color: #fff; font-size: 1.1rem; line-height: 1; cursor: pointer; display: flex; align-items: center; justify-content: center; z-index: 1; transition: background 0.15s, border-color 0.15s; } .lb-close:hover { background: rgba(255,255,255,0.15); border-color: var(--neon-cyan); } /* ---------- Now Playing overlay ---------- */ #np-overlay { display: none; position: fixed; inset: 0; background: rgba(0,0,0,0); z-index: 2600; align-items: center; justify-content: center; overflow: hidden; } #np-overlay.np-open { display: flex; animation: lb-fade-in-synthwave 0.25s ease forwards; } #np-overlay.np-closing { animation: lb-fade-out-synthwave 0.2s ease forwards; } #np-modal { position: relative; z-index: 1; display: flex; background: var(--bg-panel); border: 1px solid var(--neon-violet); border-radius: var(--radius); box-shadow: 0 0 0 1px var(--border), 0 0 40px rgba(143,91,255,0.45); width: min(940px, 92vw); height: min(640px, 85vh); overflow: visible; } #np-overlay.np-open #np-modal { animation: lb-zoom-in 0.3s cubic-bezier(0.34, 1.4, 0.64, 1) forwards; } #np-overlay.np-closing #np-modal { animation: lb-zoom-out 0.2s ease forwards; } #np-close { position: absolute; top: 10px; right: 10px; z-index: 10; width: 30px; height: 30px; background: rgba(0,0,0,0.65); border: 1px solid rgba(255,255,255,0.3); border-radius: 4px; color: #fff; font-size: 1.1rem; cursor: pointer; display: flex; align-items: center; justify-content: center; transition: background 0.15s, border-color 0.15s; } #np-close:hover { background: rgba(255,255,255,0.15); border-color: var(--neon-cyan); } /* ── Left panel ──────────────────────────────────────────────────── */ #np-left { width: 38%; flex-shrink: 0; display: flex; flex-direction: column; background: #000; overflow: visible; border-right: 1px solid var(--border); position: relative; z-index: 1; } /* Sleeve scene — handles tilt, hover scale, and record pull-out */ #np-sleeve-scene { position: relative; width: 115%; margin: -1.5rem 0 0 -30%; transform: rotate(-10deg); transform-origin: 42% 50%; transition: transform 0.35s cubic-bezier(0.34, 1.3, 0.64, 1); } #np-sleeve-scene:hover { transform: rotate(-10deg) scale(1.05); cursor: pointer; } /* 1:1 cover using padding-bottom trick */ #np-cover-wrap { width: 100%; position: relative; flex-shrink: 0; overflow: visible; } #np-cover-wrap::before { content: ''; display: block; padding-bottom: 100%; } /* Vinyl record — peeks out behind the sleeve */ #np-record { position: absolute; width: 100%; height: 100%; top: 0; left: 18%; z-index: 0; object-fit: contain; border-radius: 50%; transition: left 0.35s cubic-bezier(0.34, 1.3, 0.64, 1); pointer-events: none; } #np-sleeve-scene:hover #np-record { left: 44%; } #np-cover { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; transition: opacity 0.3s ease; z-index: 1; } #np-cover-wrap::after { content: ''; position: absolute; inset: 0; z-index: 2; border: 8px solid rgba(128, 128, 128, 0.8); pointer-events: none; } #np-cover[data-lightbox] { cursor: pointer; } /* Creator info below the square cover */ #np-creator-info { flex: 1; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 0.4rem; padding: 0.9rem 1rem; background: var(--bg-inset); overflow: hidden; text-align: center; transition: background 0.15s ease, box-shadow 0.15s ease; } #np-creator-info[style*="cursor: pointer"]:hover { background: var(--bg-panel); box-shadow: inset 0 0 0 1px var(--neon-cyan), inset 0 0 12px rgba(0, 255, 255, 0.1); } .np-creator-avatar { width: 58px; height: 58px; border-radius: 50%; object-fit: cover; border: 2px solid var(--border); background: var(--bg-panel); flex-shrink: 0; } .np-creator-placeholder { display: flex; align-items: center; justify-content: center; font-size: 1.5rem; font-weight: bold; color: var(--muted); } .np-creator-label { font-size: 0.62rem; color: var(--muted); text-transform: uppercase; letter-spacing: 0.07em; margin: 0; } .np-creator-name { font-size: 0.82rem; color: var(--fg); font-weight: 600; margin: 0; } /* ── Right panel ─────────────────────────────────────────────────── */ #np-right { flex: 1; display: flex; flex-direction: column; min-width: 0; position: relative; z-index: 0; } #np-playlist-view { flex: 1; display: flex; flex-direction: column; min-height: 0; } #np-header { padding: 0.9rem 1.25rem 0.8rem; border-bottom: 1px solid var(--border); background: var(--bg-inset); flex-shrink: 0; } #np-pl-title { font-family: 'Orbitron', monospace; font-size: 0.88rem; font-weight: 700; color: var(--fg); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } #np-pl-meta { font-size: 0.7rem; color: var(--muted); margin-top: 0.2rem; } /* Track list */ #np-tracks { list-style: none; padding: 0; margin: 0; overflow-y: auto; flex: 1; scrollbar-width: thin; scrollbar-color: var(--border) transparent; } #np-tracks::-webkit-scrollbar { width: 5px; } #np-tracks::-webkit-scrollbar-track { background: transparent; } #np-tracks::-webkit-scrollbar-thumb { background: var(--border); border-radius: 3px; } .np-track { display: flex; align-items: center; gap: 0.55rem; padding: 0.5rem 1rem; border-bottom: 1px solid rgba(255,255,255,0.04); transition: background 0.1s; cursor: pointer; } .np-track:hover { background: rgba(255,255,255,0.08); } .np-track.np-active { background: rgba(0,229,255,0.07); } /* Equalizer bars */ .np-eq { display: none; align-items: flex-end; gap: 2px; height: 14px; flex-shrink: 0; } .np-track.np-active .np-eq { display: inline-flex; } .np-eq span { width: 3px; background: var(--neon-cyan); border-radius: 1px; transform-origin: bottom; } .np-eq span:nth-child(1) { height: 14px; animation: np-eq 0.55s ease-in-out infinite alternate; } .np-eq span:nth-child(2) { height: 10px; animation: np-eq 0.40s ease-in-out infinite alternate; animation-delay: -0.15s; } .np-eq span:nth-child(3) { height: 12px; animation: np-eq 0.65s ease-in-out infinite alternate; animation-delay: -0.35s; } @keyframes np-eq { from { transform: scaleY(0.15); opacity: 0.5; } to { transform: scaleY(1); opacity: 1; } } .np-track-num { font-size: 0.7rem; color: var(--muted); width: 1.5rem; text-align: right; flex-shrink: 0; font-family: 'Orbitron', monospace; } .np-track.np-active .np-track-num { color: var(--neon-cyan); } .np-track-info { flex: 1; min-width: 0; } .np-track-title { font-size: 0.84rem; color: var(--fg); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } .np-track-artist { font-size: 0.7rem; color: var(--muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } .np-track.np-active .np-track-title { color: var(--neon-cyan); } .np-track.np-active .np-track-artist { color: rgba(0,229,255,0.6); } /* Bottom bar */ #np-bar { flex-shrink: 0; border-top: 1px solid var(--border); background: var(--bg-inset); } #np-progress-wrap { height: 4px; background: rgba(255,255,255,0.08); cursor: pointer; transition: height 0.15s; } #np-progress-wrap:hover { height: 6px; } #np-progress-fill { height: 100%; width: 0%; background: var(--neon-cyan); box-shadow: var(--glow-cyan); transition: width 0.25s linear; } #np-controls { display: flex; align-items: center; gap: 0.2rem; padding: 0.45rem 0.75rem; } #np-btn-playpause, #np-btn-next, #np-btn-repeat { background: none; border: none; color: var(--muted); cursor: pointer; font-size: 1rem; padding: 3px 6px; border-radius: 4px; transition: color 0.15s, background 0.15s; line-height: 1; } #np-btn-playpause { font-size: 1.1rem; color: var(--fg); padding: 3px 8px; } #np-btn-playpause:hover { color: var(--neon-cyan); background: rgba(0,229,255,0.08); } #np-btn-next:hover, #np-btn-repeat:hover { color: var(--fg); background: rgba(255,255,255,0.06); } #np-btn-repeat.active { color: var(--neon-cyan); text-shadow: var(--glow-cyan); } @media (max-width: 600px) { #np-left { display: none; } #np-modal { width: 96vw; height: 90vh; } } /* ---------- Avatar ---------- */ .avatar-section { display: flex; align-items: center; gap: 1rem; } .avatar-preview { width: 80px; height: 80px; border-radius: 50%; object-fit: cover; background: var(--bg-inset); border: 2px solid var(--border); flex-shrink: 0; } .avatar-placeholder { display: flex; align-items: center; justify-content: center; font-size: 2rem; font-weight: bold; color: var(--muted); } /* ---------- Crop modal ---------- */ .crop-modal { position: fixed; inset: 0; background: rgba(0,0,0,0.85); z-index: 1000; display: flex; align-items: center; justify-content: center; } .crop-modal-inner { background: var(--bg-panel); border: 1px solid var(--border); border-radius: 8px; padding: 1.5rem; max-width: 500px; width: 90vw; } .crop-container { width: 100%; height: 380px; } .crop-actions { display: flex; gap: 0.75rem; margin-top: 1rem; align-items: center; } .track-list { padding-left: 0; list-style: none; } .track-list li { margin: 0; display: flex; align-items: center; justify-content: space-between; gap: 0.75rem; padding: 0.35rem 0.5rem; border-radius: 4px; border-top: 2px solid transparent; border-bottom: 2px solid transparent; transition: background 0.15s; } .track-list li:hover { background: rgba(255,255,255,0.04); } .track-list li.dragging { opacity: 0.35; } .track-list li.drop-above { border-top-color: var(--neon-cyan); } .track-list li.drop-below { border-bottom-color: var(--neon-cyan); } .track-label { flex: 1; min-width: 0; } .drag-handle { flex-shrink: 0; color: var(--muted); cursor: grab; padding: 0 2px; line-height: 0; user-select: none; } .drag-handle:active { cursor: grabbing; } /* ---------- Player bar ---------- */ .player-bar { position: fixed; left: 0; right: 0; bottom: 0; background: linear-gradient(180deg, rgba(12,14,26,0.9), rgba(5,6,13,0.96)); border-top: 1px solid var(--neon-magenta); box-shadow: 0 -1px 0 rgba(255,43,214,0.6), 0 -8px 28px rgba(255,43,214,0.2); backdrop-filter: blur(8px); -webkit-backdrop-filter: blur(8px); padding: 0.75rem 1rem; display: flex; align-items: center; gap: 1rem; z-index: 5; } .player-now { display: flex; align-items: center; gap: 0.6rem; width: 320px; flex-shrink: 0; } #player-cover { width: 44px; height: 44px; border-radius: 4px; object-fit: cover; background: var(--bg-inset); border: 1px solid var(--border); flex-shrink: 0; } #player-viz { width: 72px; height: 44px; flex-shrink: 0; pointer-events: none; } .player-meta { min-width: 0; } .player-meta #player-title { font-family: 'Orbitron', sans-serif; font-weight: 600; font-size: 0.82rem; letter-spacing: 0.08em; text-transform: uppercase; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; color: var(--neon-cyan); text-shadow: var(--glow-cyan); } #player-audio { flex: 1; min-width: 160px; filter: hue-rotate(200deg) saturate(1.2); } .player-queue { display: flex; align-items: center; gap: 0.6rem; } #player-queue-info { font-family: 'Orbitron', monospace; font-size: 0.72rem; } #player-next, #player-repeat { background: transparent; color: var(--neon-cyan); border: 1px solid var(--neon-cyan); padding: 0.45rem 0.7rem; border-radius: 4px; cursor: pointer; box-shadow: var(--glow-cyan); transition: all .15s; } #player-next:hover, #player-repeat:hover { background: var(--neon-cyan); color: #05060d; } #player-repeat.active { background: var(--neon-cyan); color: #05060d; box-shadow: 0 0 12px var(--neon-cyan), 0 0 24px rgba(0,229,255,0.4); } /* ---------- Boot sequence overlay ---------- */ #boot-overlay { position: fixed; inset: 0; z-index: 999; background: #05060d; display: flex; align-items: center; justify-content: center; font-family: 'Orbitron', 'Courier New', monospace; color: var(--neon-cyan); text-shadow: var(--glow-cyan); transition: opacity .3s ease-out; } #boot-overlay.hidden { opacity: 0; pointer-events: none; } #boot-overlay.gone { display: none; } #boot-overlay .boot-inner { max-width: 560px; padding: 2rem; white-space: pre; font-size: 0.95rem; line-height: 1.7; } #boot-overlay .boot-cursor { display: inline-block; width: 0.6em; background: var(--neon-cyan); margin-left: 2px; animation: boot-blink 0.7s steps(1) infinite; } @keyframes boot-blink { 50% { opacity: 0; } } /* ---------- Profiles ---------- */ .profiles-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(140px, 1fr)); gap: 1.25rem; margin-top: 1rem; } .profile-card { display: flex; flex-direction: column; align-items: center; gap: 0.5rem; padding: 1.25rem 0.75rem; background: var(--bg-panel); border: 1px solid var(--border); border-radius: 8px; text-decoration: none; color: var(--fg); text-align: center; transition: transform 0.15s ease, border-color 0.15s ease, box-shadow 0.15s ease; } .profile-card:hover { transform: scale(1.04); border-color: var(--neon-cyan); box-shadow: 0 0 10px var(--neon-cyan-dim, rgba(0,255,255,0.25)); } .profile-card-avatar-wrap { width: 72px; height: 72px; flex-shrink: 0; } .profile-card-avatar { width: 72px; height: 72px; border-radius: 50%; object-fit: cover; border: 2px solid var(--border); } .profile-card-placeholder { display: flex; align-items: center; justify-content: center; background: var(--bg-inset); font-size: 1.6rem; font-weight: bold; color: var(--muted); } .profile-card-name { font-weight: 600; font-size: 0.9rem; } .profile-card-meta { font-size: 0.75rem; } /* Profile detail header */ .profile-header { display: flex; align-items: center; gap: 1.5rem; padding: 1.5rem 0 1.5rem; border-bottom: 1px solid var(--border); margin-bottom: 1.5rem; } .profile-header-avatar-wrap { flex-shrink: 0; } .profile-header-avatar { width: 96px; height: 96px; border-radius: 50%; object-fit: cover; border: 2px solid var(--border); background: var(--bg-panel); } .profile-header-placeholder { display: flex; align-items: center; justify-content: center; font-size: 2.5rem; font-weight: bold; color: var(--muted); background: var(--bg-inset); } .profile-header-info h1 { margin: 0; } /* Spacing and dividers between sections on profile page */ .profile-header ~ section { margin-top: 3.5rem; padding-top: 3rem; position: relative; } .profile-header ~ section::before { content: ''; position: absolute; top: 0; left: 0; right: 0; height: 1px; background: linear-gradient(to right, transparent, var(--neon-cyan), transparent); box-shadow: 0 0 8px var(--neon-cyan), 0 0 20px rgba(0, 255, 255, 0.2); } /* No line/extra space before the first section */ .profile-header + section { margin-top: 1rem; padding-top: 0; } .profile-header + section::before { display: none; } /* 4-wide grid for songs on profile page */ .grid.grid-4 { grid-template-columns: repeat(auto-fill, minmax(160px, 1fr)); } /* Section header with inline action button */ .section-header-row { display: flex; align-items: center; justify-content: space-between; gap: 1rem; margin-bottom: 0.75rem; } .section-header-row h2 { margin: 0; } /* ---------- Big-room single-song overlay ---------- */ #np-bigroom-view { display: none; flex-direction: column; align-items: center; justify-content: center; flex: 1; gap: 0.25rem; padding: 1.25rem 1.5rem 0; text-align: center; overflow: hidden; min-height: 0; } .np-single #np-playlist-view { display: none; } .np-single #np-bigroom-view { display: flex; } .np-single #np-btn-next { visibility: hidden; } #np-bigroom-title { font-family: 'Orbitron', sans-serif; font-size: 1.2rem; font-weight: 700; color: var(--fg); text-shadow: var(--glow-cyan); line-height: 1.3; margin: 0; } #np-bigroom-artist { font-size: 0.9rem; color: var(--muted); margin: 0; } #np-bigroom-meta { font-size: 0.7rem; color: var(--muted); margin: 0 0 0.5rem; } #np-viz-big { width: 270px; height: 270px; flex-shrink: 0; } /* ---------- Notifications ---------- */ .notif-nav-btn { display: inline-flex; align-items: center; gap: 0.6rem; padding: 0.65rem 1.25rem; margin-bottom: 1.5rem; background: rgba(255, 179, 71, 0.08); border: 1px solid rgba(255, 179, 71, 0.4); border-radius: var(--radius); color: var(--neon-amber); font-size: 1rem; font-weight: 600; text-decoration: none; transition: background 0.2s, box-shadow 0.2s; } .notif-nav-btn:hover { background: rgba(255, 179, 71, 0.15); box-shadow: 0 0 12px rgba(255, 179, 71, 0.25); text-decoration: none; } .notif-nav-icon { font-size: 1.15rem; } .notif-nav-label { letter-spacing: 0.02em; } .notif-badge { display: inline-flex; align-items: center; justify-content: center; background: var(--neon-amber); color: #05060d; font-family: 'Orbitron', sans-serif; font-size: 0.58rem; font-weight: 700; min-width: 1.25em; height: 1.25em; border-radius: 99px; padding: 0 0.3em; margin-left: 0.3em; box-shadow: 0 0 6px rgba(255, 179, 71, 0.7); vertical-align: middle; } .notif-list { list-style: none; padding: 0; display: flex; flex-direction: column; gap: 0.5rem; max-width: 680px; } .notif-item { background: var(--bg-panel); border: 1px solid var(--border); border-radius: var(--radius); padding: 0.75rem 1rem; display: flex; gap: 0.75rem; align-items: flex-start; } .notif-item.unread { border-left: 3px solid var(--neon-amber); box-shadow: 0 0 8px rgba(255, 179, 71, 0.15); } .notif-icon { font-size: 1.1rem; line-height: 1; margin-top: 0.1rem; flex-shrink: 0; } .notif-text { font-size: 0.85rem; line-height: 1.5; } .notif-text a { color: var(--neon-cyan); } .notif-text a:hover { text-decoration: underline; } .notif-time { font-size: 0.72rem; color: var(--muted); margin-top: 0.2rem; } /* ---------- Mobile ---------- */ @media (max-width: 720px) { .player-bar { flex-wrap: wrap; } .player-now { width: auto; flex: 1; } #player-viz { width: 56px; } #player-audio { width: 100%; order: 3; } .song-detail { flex-direction: column; align-items: flex-start; } .song-detail-cover { width: 100%; height: auto; max-width: 300px; aspect-ratio: 1 / 1; object-fit: cover; } .song-detail-info { flex-wrap: wrap; } .detail-creator-card { flex-direction: row; align-items: center; gap: 0.6rem; text-align: left; width: 100%; } .detail-creator-avatar { width: 48px; height: 48px; } .hero h1 { font-size: 1.6rem; } } /* ---------- Reduced motion ---------- */ @media (prefers-reduced-motion: reduce) { .flash { animation: none; } .card, .btn-primary, .btn-small, .btn-play, #player-next { transition: none; } #boot-overlay { display: none; } }