/* ============================================================ 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); } 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 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: center; 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); } /* ---------- 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; } .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); } .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; } } /* ---------- 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; } .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; } }