Files
djaudiovisualizer/src/style.css
T
2026-06-19 15:46:54 +02:00

611 lines
15 KiB
CSS
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
* { box-sizing: border-box; }
html, body {
margin: 0;
padding: 0;
width: 100%;
height: 100%;
overflow: hidden;
background: #000;
color: #e8e8f0;
font-family: -apple-system, BlinkMacSystemFont, "SF Pro Text", Helvetica, Arial, sans-serif;
cursor: default;
}
body.hide-cursor { cursor: none; }
#gl {
position: fixed;
inset: 0;
width: 100vw;
height: 100vh;
display: block;
}
/* ============ CONTROL WINDOW LAYOUT ============ */
body.control {
display: flex;
flex-direction: column;
height: 100vh;
overflow-x: hidden; /* never a horizontal scrollbar */
overflow-y: auto;
background: #0e0e16;
cursor: default;
}
#topbar {
flex: 0 0 auto;
display: flex;
align-items: baseline;
justify-content: space-between;
padding: 12px 16px;
border-bottom: 1px solid rgba(255,255,255,0.08);
background: rgba(20,20,30,0.6);
}
#topbar strong { font-size: 15px; letter-spacing: 0.3px; }
#topbar #status { font-size: 11px; opacity: 0.6; font-variant-numeric: tabular-nums; }
/* Tab bar */
#tabs {
flex: 0 0 auto;
display: flex;
gap: 4px;
padding: 8px 10px 0;
border-bottom: 1px solid rgba(255,255,255,0.08);
background: rgba(20,20,30,0.45);
overflow-x: auto;
}
#tabs button {
flex: 0 0 auto;
background: transparent;
border: none;
border-bottom: 2px solid transparent;
border-radius: 8px 8px 0 0;
padding: 8px 12px;
opacity: 0.6;
font-size: 13px;
}
#tabs button:hover { background: rgba(255,255,255,0.06); opacity: 0.9; }
#tabs button.active {
opacity: 1;
background: rgba(110,150,255,0.14);
border-bottom-color: #7aa2ff;
}
#content { flex: 1 1 auto; overflow-y: auto; min-width: 0; }
.tab-panel { display: none; }
.tab-panel.active {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 12px;
padding: 14px;
align-content: start;
}
.tab-panel section {
min-width: 0; /* allow grid cells to shrink, no overflow */
background: rgba(255,255,255,0.04);
border: 1px solid rgba(255,255,255,0.07);
border-radius: 14px;
padding: 12px;
}
.tab-panel section.span2 { grid-column: 1 / -1; }
@media (max-width: 460px) {
.tab-panel.active { grid-template-columns: 1fr; }
}
body.control label {
display: block;
font-size: 11px;
text-transform: uppercase;
letter-spacing: 0.6px;
opacity: 0.6;
margin: 8px 0 6px;
}
body.control label:first-child { margin-top: 0; }
body.control label span { float: right; opacity: 0.9; text-transform: none; letter-spacing: 0; }
body.control .chk { text-transform: none; letter-spacing: 0; opacity: 0.85; margin: 0; }
#hints {
flex: 0 0 auto;
font-size: 10.5px;
opacity: 0.5;
line-height: 1.7;
padding: 10px 16px;
border-top: 1px solid rgba(255,255,255,0.08);
}
body.control select { width: 100%; max-width: 100%; }
/* Per-band equaliser labels + sliders */
.band { display: block; }
#bass-gain { accent-color: #5ad1ff; }
#mid-gain { accent-color: #7aa2ff; }
#treble-gain { accent-color: #ff7ad1; }
.band-bass span, .band-mid span, .band-treble span { color: #fff; }
/* ---- Effect library ---- */
.effect-list {
margin-top: 8px;
max-height: 220px;
overflow-y: auto;
border: 1px solid rgba(255,255,255,0.07);
border-radius: 10px;
padding: 4px;
}
.fx {
display: flex;
align-items: center;
gap: 6px;
padding: 5px 8px;
border-radius: 7px;
font-size: 12px;
cursor: pointer;
}
.fx:hover { background: rgba(255,255,255,0.07); }
.fx.active { background: rgba(110,150,255,0.25); }
.fx .fx-name { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.fx .fx-add {
flex: 0 0 auto;
padding: 2px 8px;
border-radius: 6px;
font-size: 12px;
}
#effect-family { flex: 0 0 45%; }
#effect-search { flex: 1; margin: 0; }
/* ---- Pad bank (5×5 launchpad) ---- */
.pad-grid {
display: grid;
grid-template-columns: repeat(5, 1fr);
gap: 6px;
margin-top: 8px;
}
.pad {
position: relative;
aspect-ratio: 1 / 1;
border: 1px solid rgba(255,255,255,0.1);
border-radius: 10px;
background: rgba(255,255,255,0.04);
display: flex;
align-items: center;
justify-content: center;
text-align: center;
cursor: pointer;
overflow: hidden;
padding: 4px;
transition: background 0.12s ease, box-shadow 0.12s ease;
}
.pad:hover { background: rgba(255,255,255,0.09); }
.pad.filled { background: rgba(90,120,200,0.18); border-color: rgba(120,150,255,0.4); }
.pad.active {
background: rgba(60,200,120,0.35);
border-color: #5ad18a;
box-shadow: 0 0 12px rgba(90,230,150,0.55);
}
.pad-num { position: absolute; top: 3px; left: 5px; font-size: 9px; opacity: 0.5; }
.pad-name {
font-size: 9.5px;
line-height: 1.15;
word-break: break-word;
max-height: 100%;
overflow: hidden;
opacity: 0.92;
}
.pad-plus { font-size: 22px; opacity: 0.3; }
.pad-x {
position: absolute;
top: 1px; right: 2px;
background: transparent;
border: none;
color: #ff8a8a;
font-size: 11px;
padding: 0 3px;
opacity: 0;
flex: none;
width: auto;
}
.pad:hover .pad-x { opacity: 0.9; }
.pad-key {
position: absolute;
bottom: 2px;
right: 3px;
background: rgba(255,255,255,0.12);
border: none;
color: #cdd6ff;
font-size: 9px;
font-weight: 700;
line-height: 1;
padding: 2px 4px;
border-radius: 4px;
min-width: 14px;
width: auto;
flex: none;
opacity: 0.85;
}
.pad-key:hover { background: rgba(120,150,255,0.45); }
.pad-time {
position: absolute;
bottom: 3px;
left: 4px;
font-size: 8.5px;
opacity: 0.7;
font-variant-numeric: tabular-nums;
}
.pad-prog {
position: absolute;
left: 0; bottom: 0;
height: 3px;
background: linear-gradient(90deg, #5ad18a, #aef0c0);
width: 0;
}
/* Larger ticker text area */
textarea.textarea-lg {
min-height: 78px;
resize: vertical;
font-size: 14px;
line-height: 1.4;
}
/* ---- Recording status ---- */
.rec-status {
display: flex;
align-items: center;
gap: 8px;
margin-bottom: 10px;
font-size: 13px;
}
#rec-dot { width: 12px; height: 12px; border-radius: 50%; flex: 0 0 auto; }
#rec-dot.off { background: #555; }
#rec-dot.on { background: #ff3b30; box-shadow: 0 0 10px #ff3b30; animation: recpulse 1s infinite; }
#rec-time { margin-left: auto; font-variant-numeric: tabular-nums; opacity: 0.85; }
@keyframes recpulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.35; } }
/* ---- SVG quick-pick chips ---- */
.svg-grid { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 8px; }
.svg-chip {
display: flex;
align-items: center;
gap: 6px;
flex: 0 0 auto;
padding: 4px 8px;
}
.svg-chip img {
width: 26px; height: 26px;
object-fit: contain;
background: #9aa3b2;
border-radius: 5px;
padding: 2px;
}
.svg-chip span {
font-size: 11px;
max-width: 120px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
/* ---- Playlist ---- */
.playlist { list-style: none; margin: 8px 0 0; padding: 0; }
.hint-mini { font-size: 10px; opacity: 0.45; margin-top: 6px; }
.track {
position: relative;
display: flex;
align-items: center;
gap: 6px;
padding: 6px 8px;
margin-bottom: 5px;
background: rgba(255,255,255,0.05);
border: 1px solid rgba(255,255,255,0.08);
border-radius: 9px;
font-size: 12px;
overflow: hidden;
}
.track .ttime {
flex: 0 0 auto;
font-size: 10px;
opacity: 0.65;
font-variant-numeric: tabular-nums;
min-width: 34px;
text-align: right;
}
.track .tprog {
position: absolute;
left: 0; bottom: 0;
height: 2px;
background: linear-gradient(90deg, #5ad1ff, #7aa2ff, #ff7ad1);
width: 0;
}
.track.playing {
background: rgba(110,150,255,0.22);
border-color: rgba(120,170,255,0.6);
}
.track.dragging { opacity: 0.4; }
.track .grip { cursor: grab; opacity: 0.4; font-size: 14px; }
.track .tname {
flex: 1;
min-width: 0;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
cursor: pointer;
}
.track .tname:hover { color: #cde0ff; }
.track button {
flex: 0 0 auto;
padding: 3px 8px;
border-radius: 7px;
font-size: 11px;
}
.track .key-btn {
min-width: 30px;
font-weight: 700;
background: rgba(255,255,255,0.1);
}
.track .play-btn { color: #8ef0b0; }
.track .del-btn { color: #ff8a8a; }
/* ============ OUTPUT WINDOW ============ */
body.output { cursor: none; background: #000; }
/* ---- Image overlay layer ---- */
#overlay-images {
position: fixed;
inset: 0;
z-index: 4;
pointer-events: none;
display: flex;
align-items: center;
justify-content: center;
--beat-scale: 1;
}
#overlay-images img {
position: absolute;
max-width: calc(var(--img-size, 70) * 1vw);
max-height: calc(var(--img-size, 70) * 1vh);
object-fit: contain;
mix-blend-mode: screen;
opacity: 0;
transform: scale(var(--beat-scale));
transition: opacity 0.8s ease;
filter: drop-shadow(0 0 30px rgba(0,0,0,0.6));
}
#overlay-images img.show { opacity: 1; }
/* ---- Independent logos ---- */
.logo {
position: fixed;
left: 50%;
top: 50%;
width: 20vw;
transform: translate(-50%, -50%);
z-index: 5;
pointer-events: none;
display: none;
filter: drop-shadow(0 0 18px rgba(0,0,0,0.45));
}
.logo.show { display: block; }
/* ---- Scrolling text ticker ---- */
#ticker {
position: fixed;
left: 0;
right: 0;
z-index: 6;
pointer-events: none;
overflow: hidden;
display: none;
padding: 14px 0;
background: linear-gradient(transparent, rgba(0,0,0,0.35), transparent);
}
#ticker.show { display: block; }
#ticker.pos-bottom { bottom: 4vh; }
#ticker.pos-top { top: 4vh; }
#ticker.pos-middle { top: 50%; transform: translateY(-50%); }
#ticker-track {
display: inline-flex;
white-space: nowrap;
will-change: transform;
font-size: 6vh;
font-weight: 800;
color: #fff;
text-transform: uppercase;
animation: ticker-scroll var(--ticker-dur, 18s) linear infinite;
}
.tick-copy { display: inline-flex; padding: 0 2vw; }
.tl {
display: inline-block;
white-space: pre;
letter-spacing: 2px;
text-shadow: 0 0 calc(8px + var(--ticker-glow, 0px)) rgba(140,180,255,0.9),
0 2px 30px rgba(0,0,0,0.8);
}
@keyframes ticker-scroll {
from { transform: translateX(0); }
to { transform: translateX(-50%); }
}
/* Text movement effects (applied per letter) */
.fx-updown .tl { animation: tl-updown 1.1s ease-in-out infinite; }
.fx-wave .tl { animation: tl-wave 1.2s ease-in-out infinite; animation-delay: calc(var(--i) * 0.05s); }
.fx-zoom .tl { animation: tl-zoom 0.9s ease-in-out infinite; animation-delay: calc(var(--i) * 0.04s); }
.fx-flash .tl { animation: tl-flash 0.6s steps(1, end) infinite; }
.fx-rotate .tl { animation: tl-rotate 2s ease-in-out infinite; animation-delay: calc(var(--i) * 0.03s); }
@keyframes tl-updown { 0%, 100% { transform: translateY(-0.18em); } 50% { transform: translateY(0.18em); } }
@keyframes tl-wave { 0%, 100% { transform: translateY(-0.24em); } 50% { transform: translateY(0.24em); } }
@keyframes tl-zoom { 0%, 100% { transform: scale(1); } 50% { transform: scale(1.35); } }
@keyframes tl-flash { 0%, 100% { opacity: 1; } 50% { opacity: 0.12; } }
@keyframes tl-rotate { 0%, 100% { transform: rotate(-12deg); } 50% { transform: rotate(12deg); } }
/* ---- Drop hint ---- */
#drop-hint {
position: fixed;
inset: 0;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
gap: 10px;
pointer-events: none;
text-shadow: 0 2px 20px rgba(0,0,0,0.8);
transition: opacity 0.4s ease;
}
#drop-hint .big { font-size: 34px; font-weight: 600; }
#drop-hint .small { font-size: 15px; opacity: 0.7; }
#drop-hint.hidden { opacity: 0; }
body.dragover #drop-hint { opacity: 1; }
body.dragover::after {
content: "";
position: fixed;
inset: 18px;
border: 3px dashed rgba(120,170,255,0.8);
border-radius: 18px;
pointer-events: none;
}
/* ---- Control panel ---- */
#panel {
position: fixed;
top: 16px;
left: 16px;
width: 320px;
max-height: calc(100vh - 32px);
overflow-y: auto;
background: rgba(14, 14, 22, 0.82);
backdrop-filter: blur(14px);
-webkit-backdrop-filter: blur(14px);
border: 1px solid rgba(255,255,255,0.08);
border-radius: 16px;
padding: 14px 16px;
font-size: 13px;
z-index: 10;
transition: opacity 0.25s ease, transform 0.25s ease;
box-shadow: 0 12px 40px rgba(0,0,0,0.5);
}
#panel.hidden { opacity: 0; transform: translateX(-12px); pointer-events: none; }
#panel header {
display: flex;
justify-content: space-between;
align-items: baseline;
margin-bottom: 10px;
}
#panel header strong { font-size: 15px; letter-spacing: 0.3px; }
#fps { font-size: 11px; opacity: 0.55; font-variant-numeric: tabular-nums; }
#panel section { margin-bottom: 14px; }
#panel label {
display: block;
font-size: 11px;
text-transform: uppercase;
letter-spacing: 0.6px;
opacity: 0.6;
margin-bottom: 6px;
}
#panel label span { float: right; opacity: 0.9; text-transform: none; letter-spacing: 0; }
.row { display: flex; gap: 6px; margin-bottom: 6px; }
.scene-grid {
display: grid;
grid-template-columns: repeat(2, 1fr);
gap: 6px;
}
.scene-grid button { font-size: 12px; padding: 7px 6px; text-align: left; }
button, select {
font: inherit;
color: #e8e8f0;
background: rgba(255,255,255,0.06);
border: 1px solid rgba(255,255,255,0.1);
border-radius: 9px;
padding: 7px 10px;
cursor: pointer;
flex: 1;
transition: background 0.15s ease, border-color 0.15s ease;
white-space: nowrap;
}
button:hover, select:hover { background: rgba(255,255,255,0.12); }
button:disabled { opacity: 0.4; cursor: default; }
button.active {
background: rgba(110,150,255,0.28);
border-color: rgba(120,170,255,0.7);
}
button.wide { width: 100%; }
select { appearance: none; }
.chk {
display: flex !important;
align-items: center;
gap: 6px;
flex: 1;
text-transform: none !important;
letter-spacing: 0 !important;
opacity: 0.85 !important;
font-size: 12px;
margin: 0 !important;
cursor: pointer;
}
.chk input { accent-color: #7aa2ff; cursor: pointer; }
.textfield {
width: 100%;
font: inherit;
color: #e8e8f0;
background: rgba(255,255,255,0.06);
border: 1px solid rgba(255,255,255,0.1);
border-radius: 9px;
padding: 8px 10px;
margin-bottom: 6px;
}
.textfield::placeholder { color: rgba(232,232,240,0.4); }
input[type=range] {
width: 100%;
accent-color: #7aa2ff;
}
/* ---- Meters ---- */
.meters { display: flex; flex-direction: column; gap: 6px; }
.meter { display: flex; align-items: center; gap: 8px; }
.meter span { width: 38px; font-size: 10px; opacity: 0.6; }
.meter .bar {
flex: 1;
height: 8px;
background: rgba(255,255,255,0.08);
border-radius: 6px;
overflow: hidden;
}
.meter .bar i {
display: block;
height: 100%;
width: 0%;
border-radius: 6px;
background: linear-gradient(90deg, #5ad1ff, #7aa2ff, #ff7ad1);
transition: width 0.05s linear;
}
#panel footer {
font-size: 10.5px;
opacity: 0.5;
line-height: 1.7;
border-top: 1px solid rgba(255,255,255,0.08);
padding-top: 10px;
}
kbd {
font-family: ui-monospace, Menlo, monospace;
font-size: 10px;
background: rgba(255,255,255,0.1);
border: 1px solid rgba(255,255,255,0.15);
border-radius: 4px;
padding: 1px 5px;
margin: 0 1px;
}