/* NISPS Immersive — Design A */ /* Full-viewport canvas with floating translucent overlays */ * { margin: 0; padding: 0; box-sizing: border-box; -webkit-tap-highlight-color: transparent; } :root { --glass-bg: rgba(13, 13, 13, 0.65); --glass-border: rgba(255, 255, 255, 0.08); --glass-blur: 16px; --accent: #ff6a00; --accent-dim: rgba(255, 106, 0, 0.25); --danger: #ff4466; --text: #e0e0e0; --text-dim: #888; --radius: 12px; --radius-sm: 8px; --safe-bottom: env(safe-area-inset-bottom, 0px); } html, body { width: 100%; height: 100%; overflow: hidden; background: #0d0d0d; color: var(--text); font-family: 'JetBrains Mono', 'SF Mono', 'Fira Code', 'Cascadia Code', monospace; font-size: 13px; touch-action: none; user-select: none; -webkit-user-select: none; } /* ---- Back button ---- */ .back-btn { position: fixed; top: 45px; left: 8px; z-index: 30; width: 36px; height: 36px; display: flex; align-items: center; justify-content: center; padding: 0; border-radius: 6px; background: rgba(13, 13, 13, 0.65); backdrop-filter: blur(16px); -webkit-backdrop-filter: blur(16px); border: 1px solid rgba(255, 255, 255, 0.08); color: var(--text); text-decoration: none; line-height: 1; transition: all 0.15s; } .back-btn:hover, .back-btn:active { border-color: var(--accent); color: var(--accent); } /* ---- Output mode toggle (floating) ---- */ .pill-toggle-sm { border-radius: 4px; overflow: hidden; border: 1px solid rgba(255, 255, 255, 0.08); } .pill-toggle-sm .pill-opt { padding: 3px 10px; font-size: 11px; } /* ---- Fullscreen canvas ---- */ #vis-canvas, #synth-vis-canvas { position: fixed; inset: 0; width: 100%; height: 100%; display: block; z-index: 0; } #synth-vis-canvas { display: none; } #synth-vis-canvas.active { display: block; } #vis-canvas.hidden-canvas { display: none; } /* ---- ShapeSeq container (synth mode) ---- */ .shapeseq-container { position: fixed; inset: 0; z-index: 1; display: flex; flex-direction: column; background: #0d0d0d; overflow: hidden; } .shapeseq-container.hidden { display: none; } #shapeseq-viz { width: 100%; flex: 0 0 45%; min-height: 0; } .shapeseq-chain-wrap { flex: 1 1 auto; overflow-y: auto; overflow-x: hidden; -webkit-overflow-scrolling: touch; padding-bottom: calc(120px + var(--safe-bottom, 0px)); } /* ---- Glass mixin ---- */ .glass { background: var(--glass-bg); backdrop-filter: blur(var(--glass-blur)); -webkit-backdrop-filter: blur(var(--glass-blur)); border: 1px solid var(--glass-border); } /* ---- Heatmap strip (top) ---- */ .heatmap-strip { position: fixed; top: 0; left: 0; right: 0; height: 22px; z-index: 20; background: rgba(13, 13, 13, 0.5); backdrop-filter: blur(8px); -webkit-backdrop-filter: blur(8px); display: flex; align-items: flex-end; padding: 2px 4px; } .heatmap-cells { display: flex; flex-direction: row; flex: 1; height: 16px; gap: 1px; border-radius: 3px; overflow: hidden; align-items: stretch; } .heatmap-cell { flex: 1; min-width: 0; position: relative; cursor: pointer; height: 16px; background: rgba(255, 255, 255, 0.04); overflow: hidden; } .heatmap-cell-bar { height: 100%; border-radius: 0 1px 1px 0; transition: width 0.15s; } .heatmap-cell:hover .heatmap-cell-bar { filter: brightness(1.3); } .heatmap-tooltip { position: fixed; top: 32px; padding: 4px 10px; background: rgba(0, 0, 0, 0.85); border: 1px solid var(--glass-border); border-radius: 6px; font-size: 12px; color: var(--text); pointer-events: none; opacity: 0; transition: opacity 0.15s; z-index: 25; white-space: nowrap; } .heatmap-tooltip.visible { opacity: 1; } /* ---- Floating joystick with integrated map ---- */ .joystick-container { position: fixed; bottom: 136px; left: 24px; width: 160px; height: 160px; z-index: 30; touch-action: none; border-radius: 50%; } #joy-map { position: absolute; inset: 0; width: 100%; height: 100%; border-radius: 50%; cursor: grab; touch-action: none; } #joy-map:active { cursor: grabbing; } .joystick-glow { position: absolute; inset: -8px; border-radius: 50%; pointer-events: none; background: radial-gradient(circle, rgba(255,106,0,0.06) 0%, transparent 70%); z-index: -1; } /* Noise ring (RL exploration indicator) */ .noise-ring { position: absolute; inset: -4px; border-radius: 50%; border: 0px solid rgba(255, 100, 50, 0.0); pointer-events: none; transition: border-width 0.3s, border-color 0.3s; } .noise-ring.active { border-width: 3px; border-color: rgba(255, 100, 50, 0.5); } .noise-ring.high { border-width: 6px; border-color: rgba(255, 60, 40, 0.6); } /* Follow badge near joystick */ .follow-badge { position: absolute; top: -24px; left: 50%; transform: translateX(-50%); padding: 2px 10px; border-radius: 10px; background: rgba(255, 106, 0, 0.15); border: 1px solid rgba(255, 106, 0, 0.4); color: var(--accent); font-size: 10px; font-weight: 700; letter-spacing: 1px; pointer-events: none; white-space: nowrap; } .follow-badge.hidden { display: none; } /* Joystick follow-mode pulsing border on canvas */ .joystick-container.follow-active #joy-map { box-shadow: 0 0 0 2px rgba(255, 106, 0, 0.5); animation: follow-pulse 1.5s ease-in-out infinite; } @keyframes follow-pulse { 0%, 100% { box-shadow: 0 0 0 2px rgba(255, 106, 0, 0.3); } 50% { box-shadow: 0 0 12px 3px rgba(255, 106, 0, 0.5); } } /* ---- Hand tracking PIP ---- */ .hand-pip { position: fixed; bottom: 136px; left: 24px; width: 180px; height: 135px; z-index: 30; border-radius: var(--radius); overflow: hidden; background: var(--glass-bg); backdrop-filter: blur(var(--glass-blur)); -webkit-backdrop-filter: blur(var(--glass-blur)); border: 1px solid var(--glass-border); } .hand-pip.hidden { display: none; } .hand-pip video { /* Hidden — only used as MediaPipe source, not displayed */ position: absolute; width: 1px; height: 1px; opacity: 0; pointer-events: none; } .hand-pip canvas { position: absolute; inset: 0; width: 100%; height: 100%; transform: scaleX(-1); pointer-events: none; } .hand-status { position: absolute; bottom: 4px; left: 0; right: 0; text-align: center; font-size: 9px; color: var(--text-dim); pointer-events: none; text-shadow: 0 1px 3px rgba(0,0,0,0.8); } .hand-status.tracking { color: var(--accent); } .gesture-indicator { position: absolute; top: 6px; right: 6px; width: 36px; height: 36px; pointer-events: none; opacity: 0; transition: opacity 0.15s; } .gesture-indicator.active { opacity: 1; } .gesture-ring { width: 100%; height: 100%; transform: rotate(-90deg); } .gesture-ring-bg { fill: none; stroke: rgba(255,255,255,0.1); stroke-width: 3; } .gesture-ring-progress { fill: none; stroke: var(--accent); stroke-width: 3; stroke-dasharray: 100.53; stroke-dashoffset: 100.53; stroke-linecap: round; transition: stroke-dashoffset 0.05s linear; } .gesture-label { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center; font-size: 14px; color: white; text-shadow: 0 1px 3px rgba(0,0,0,0.8); } /* ---- Dev panel (hand tracking tuning) ---- */ .dev-panel { position: fixed; top: 60px; right: 16px; width: 220px; z-index: 90; background: rgba(10, 10, 10, 0.92); backdrop-filter: blur(12px); -webkit-backdrop-filter: blur(12px); border: 1px solid rgba(255, 255, 255, 0.1); border-radius: 8px; font-size: 10px; color: var(--text-dim); user-select: none; box-shadow: 0 4px 20px rgba(0,0,0,0.5); } .dev-panel.collapsed { width: auto; } .dev-panel-header { display: flex; align-items: center; justify-content: space-between; padding: 6px 10px; cursor: grab; border-bottom: 1px solid rgba(255,255,255,0.06); } .dev-panel-header:active { cursor: grabbing; } .dev-panel-title { font-size: 10px; font-weight: 500; color: var(--accent); letter-spacing: 0.03em; } .dev-panel-collapse { background: none; border: 1px solid rgba(255,255,255,0.15); color: var(--text-dim); width: 18px; height: 18px; border-radius: 3px; cursor: pointer; font-size: 10px; line-height: 1; display: flex; align-items: center; justify-content: center; } .dev-panel-body { padding: 6px 10px 10px; } .dev-row { margin-bottom: 6px; } .dev-label { display: flex; align-items: center; justify-content: space-between; font-size: 9px; color: rgba(255,255,255,0.5); margin-bottom: 2px; cursor: help; } .dev-slider-row { display: flex; align-items: center; gap: 6px; } .dev-slider { flex: 1; height: 3px; -webkit-appearance: none; appearance: none; background: rgba(255,255,255,0.1); border-radius: 2px; outline: none; } .dev-slider::-webkit-slider-thumb { -webkit-appearance: none; width: 10px; height: 10px; border-radius: 50%; background: var(--accent); cursor: pointer; } .dev-slider::-moz-range-thumb { width: 10px; height: 10px; border-radius: 50%; background: var(--accent); border: none; cursor: pointer; } .dev-value { font-family: 'JetBrains Mono', monospace; font-size: 9px; color: rgba(255,255,255,0.6); min-width: 28px; text-align: right; } .dev-toggle { accent-color: var(--accent); cursor: pointer; } .dev-row-actions { margin-top: 8px; padding-top: 6px; border-top: 1px solid rgba(255,255,255,0.06); } .dev-reset-btn { background: rgba(255,255,255,0.06); border: 1px solid rgba(255,255,255,0.1); color: var(--text-dim); font-size: 9px; padding: 3px 8px; border-radius: 4px; cursor: pointer; width: 100%; } .dev-reset-btn:hover { background: rgba(255,255,255,0.1); color: white; } .dev-feature-bars { width: 100%; height: 56px; border-radius: 4px; background: rgba(0,0,0,0.3); display: block; } /* ---- RL floating buttons ---- */ .rl-buttons { position: fixed; bottom: 92px; /* just above 88px collapsed sheet */ left: 50%; transform: translateX(-50%); display: flex; gap: 32px; z-index: 45; transition: opacity 0.3s; } .rl-buttons.hidden { opacity: 0; pointer-events: none; } .rl-btn { width: 64px; height: 64px; border-radius: 50%; border: 2px solid var(--glass-border); background: var(--glass-bg); backdrop-filter: blur(var(--glass-blur)); -webkit-backdrop-filter: blur(var(--glass-blur)); color: var(--text); cursor: pointer; transition: all 0.15s; display: flex; flex-direction: column; align-items: center; justify-content: center; padding-top: 2px; gap: 0; } .rl-icon { font-size: 28px; font-weight: 700; line-height: 1; } .key-num { font-size: 12px; color: rgba(255, 255, 255, 0.5); font-family: inherit; line-height: 1; margin-top: -1px; } .rl-btn:active { transform: scale(0.9); } .rl-up { border-color: rgba(0, 200, 160, 0.4); color: #00c8a0; background: rgba(0, 200, 160, 0.08); } .rl-up:active { background: rgba(0, 200, 160, 0.2); box-shadow: 0 0 20px rgba(0, 200, 160, 0.3); } .rl-down { border-color: rgba(220, 60, 20, 0.4); color: #dc3c14; background: rgba(220, 60, 20, 0.08); } .rl-down:active { background: rgba(220, 60, 20, 0.2); box-shadow: 0 0 20px rgba(220, 60, 20, 0.3); } .rl-btn.flash { animation: rl-flash 0.25s ease-out; } @keyframes rl-flash { 0% { transform: scale(1.15); } 100% { transform: scale(1); } } /* ---- Floating mode bar (sticky inside sheet) ---- */ .floating-bar { position: sticky; top: 0; z-index: 45; display: flex; align-items: center; justify-content: center; gap: 10px; padding: 6px 12px; background: rgba(13, 13, 13, 0.85); backdrop-filter: blur(20px); -webkit-backdrop-filter: blur(20px); border-bottom: 1px solid var(--glass-border); } /* Float button (randomize in floating bar) */ .float-btn { padding: 4px 12px; border-radius: 6px; border: 1px solid rgba(255, 255, 255, 0.08); background: rgba(255, 255, 255, 0.04); color: var(--text-dim); font-size: 12px; cursor: pointer; transition: all 0.15s; } .float-btn:active { background: rgba(255, 106, 0, 0.15); color: var(--accent); } .float-btn.accent { border-color: rgba(255, 106, 0, 0.3); color: var(--accent); } .follow-pill { padding: 4px 12px; border-radius: 6px; border: 1px solid rgba(255, 255, 255, 0.08); background: rgba(255, 255, 255, 0.04); color: var(--text-dim); font-size: 12px; cursor: pointer; transition: all 0.15s; } .follow-pill.active { background: rgba(255, 106, 0, 0.15); border-color: rgba(255, 106, 0, 0.4); color: var(--accent); } .chevron-btn { width: 32px; height: 32px; border-radius: 50%; border: 1px solid var(--glass-border); background: rgba(255, 255, 255, 0.06); color: var(--text-dim); font-size: 14px; cursor: pointer; display: flex; align-items: center; justify-content: center; transition: all 0.2s; } .chevron-btn:active { background: rgba(255, 255, 255, 0.12); } .chevron-btn.open { transform: rotate(180deg); } /* ---- Bottom sheet ---- */ .bottom-sheet { position: fixed; bottom: 0; left: 0; right: 0; z-index: 40; background: rgba(13, 13, 13, 0.75); backdrop-filter: blur(20px); -webkit-backdrop-filter: blur(20px); border-top: 1px solid var(--glass-border); border-radius: 0; transition: height 0.35s cubic-bezier(0.22, 1, 0.36, 1); height: 88px; overflow: hidden; padding-bottom: var(--safe-bottom); will-change: height; } .bottom-sheet.expanded { height: 55vh; overflow-y: auto; -webkit-overflow-scrolling: touch; } /* Sheet status line */ .sheet-status { padding: 8px 16px; font-size: 12px; color: var(--text-dim); text-align: center; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; height: 44px; display: flex; align-items: center; justify-content: center; } /* Sheet content */ .sheet-content { padding: 0 16px 16px; } /* Mode row */ .mode-row { display: flex; justify-content: center; margin-bottom: 12px; } /* Pill toggle */ .pill-toggle { display: inline-flex; border-radius: 6px; overflow: hidden; border: 1px solid var(--glass-border); background: rgba(255, 255, 255, 0.04); } .pill-opt { padding: 6px 18px; background: none; border: none; color: var(--text-dim); font-size: 13px; cursor: pointer; transition: all 0.2s; } .pill-opt.active { background: var(--accent-dim); color: var(--accent); font-weight: 600; } /* Action buttons row */ .action-row { display: flex; gap: 8px; flex-wrap: wrap; justify-content: center; margin-bottom: 12px; } .action-btn { padding: 8px 16px; border-radius: 6px; border: 1px solid var(--glass-border); background: rgba(255, 255, 255, 0.06); color: var(--text); font-size: 13px; cursor: pointer; transition: all 0.15s; touch-action: manipulation; } .action-btn:active { transform: scale(0.95); } .action-btn.accent { border-color: rgba(255, 106, 0, 0.3); color: var(--accent); background: rgba(255, 106, 0, 0.08); } .action-btn.accent:active { background: rgba(255, 106, 0, 0.2); } .action-btn.dim { color: var(--text-dim); border-color: rgba(255, 255, 255, 0.05); } .action-btn.flash { animation: btn-flash 0.2s ease-out; } @keyframes btn-flash { 0% { background: rgba(255, 106, 0, 0.3); } 100% { background: rgba(255, 255, 255, 0.06); } } /* Preset row */ .preset-row { display: flex; gap: 6px; align-items: center; flex-wrap: wrap; justify-content: center; margin-bottom: 12px; } .preset-label { font-size: 11px; color: var(--text-dim); text-transform: uppercase; letter-spacing: 0.5px; margin-right: 4px; } .preset-chip { padding: 4px 12px; border-radius: 6px; border: 1px solid rgba(255, 255, 255, 0.08); background: rgba(255, 255, 255, 0.04); color: var(--text-dim); font-size: 12px; cursor: pointer; transition: all 0.15s; touch-action: manipulation; } .preset-chip:active { background: rgba(255, 106, 0, 0.15); color: var(--accent); } /* Synth panel */ .synth-panel { margin-bottom: 16px; } .synth-panel.hidden { display: none; } .synth-row { display: flex; align-items: center; gap: 10px; margin-bottom: 10px; } .synth-row label { font-size: 12px; color: var(--text-dim); min-width: 80px; } .synth-row input[type="range"] { flex: 1; accent-color: var(--accent); height: 4px; } .synth-row select { flex: 1; background: rgba(255, 255, 255, 0.06); border: 1px solid var(--glass-border); border-radius: 6px; color: var(--text); padding: 4px 8px; font-size: 12px; } .synth-status { font-size: 11px; color: var(--text-dim); } /* Loss section */ .loss-section { margin-bottom: 12px; } .loss-section label { font-size: 11px; color: var(--text-dim); text-transform: uppercase; letter-spacing: 0.5px; display: block; margin-bottom: 4px; } #loss-canvas { width: 100%; height: 80px; border-radius: var(--radius-sm); background: rgba(0, 0, 0, 0.3); border: 1px solid var(--glass-border); } /* Advanced section */ .advanced-section { margin-top: 8px; } .advanced-section summary { font-size: 12px; color: var(--text-dim); cursor: pointer; padding: 6px 0; } .raw-params { display: grid; grid-template-columns: 1fr; gap: 4px; max-height: 300px; overflow-y: auto; padding: 8px 0; } .raw-param { display: flex; align-items: center; gap: 8px; font-size: 11px; } .raw-param-label { width: 70px; color: var(--text-dim); text-align: right; flex-shrink: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } .raw-param input[type="range"] { flex: 1; accent-color: var(--accent); height: 3px; } .raw-param-val { width: 36px; color: var(--text-dim); text-align: left; flex-shrink: 0; font-variant-numeric: tabular-nums; } /* Tooltip for raw param sliders */ .raw-param { position: relative; } .raw-param[data-tooltip]:hover::after { content: attr(data-tooltip); position: absolute; bottom: calc(100% + 6px); left: 50%; transform: translateX(-50%); padding: 4px 10px; background: rgba(0, 0, 0, 0.9); border: 1px solid var(--glass-border); border-radius: 6px; font-size: 12px; color: var(--text); white-space: nowrap; pointer-events: none; z-index: 50; } /* ---- Synth quick controls (play button next to back) ---- */ .synth-quick-controls { position: fixed; top: 45px; left: 52px; z-index: 30; display: flex; flex-direction: row; align-items: center; gap: 0; } .play-btn { width: 36px; height: 36px; border-radius: 18px; border: 1px solid rgba(255, 255, 255, 0.08); background: rgba(13, 13, 13, 0.65); backdrop-filter: blur(16px); -webkit-backdrop-filter: blur(16px); color: var(--text); cursor: pointer; display: flex; align-items: center; justify-content: center; transition: background 0.15s, border-color 0.15s; padding: 0; flex-shrink: 0; align-self: flex-start; } .play-btn:active { background: rgba(255, 255, 255, 0.12); } .play-btn.playing { border-color: rgba(255, 106, 0, 0.4); color: var(--accent); background: rgba(255, 106, 0, 0.12); } .play-btn.audio-needs-init { animation: audioInitPulse 2s ease-in-out infinite; } @keyframes audioInitPulse { 0%, 100% { border-color: rgba(255, 106, 0, 0.3); box-shadow: 0 0 6px rgba(255, 106, 0, 0.15); color: var(--accent); } 50% { border-color: rgba(255, 106, 0, 0.6); box-shadow: 0 0 14px rgba(255, 106, 0, 0.3); color: #ffaa55; } } .play-drawer { display: none; flex-direction: column; gap: 6px; padding: 8px 12px; border-radius: 18px; background: rgba(13, 13, 13, 0.65); backdrop-filter: blur(16px); -webkit-backdrop-filter: blur(16px); border: 1px solid rgba(255, 255, 255, 0.08); margin-left: 6px; height: auto; white-space: nowrap; } .play-drawer label { font-size: 11px; color: var(--text-dim); display: flex; align-items: center; gap: 6px; } .play-drawer input[type="range"] { width: 80px; accent-color: var(--accent); height: 3px; } .play-drawer span { font-size: 10px; font-variant-numeric: tabular-nums; min-width: 24px; color: var(--text-dim); } .play-btn:hover ~ .play-drawer, .play-drawer:hover, .play-drawer.show { display: flex; } /* Synth preset dropdown */ .preset-select { margin-left: 8px; height: 36px; padding: 0 10px; border-radius: 18px; border: 1px solid rgba(255, 255, 255, 0.08); background: rgba(13, 13, 13, 0.65); backdrop-filter: blur(16px); -webkit-backdrop-filter: blur(16px); color: var(--text); font-family: inherit; font-size: 11px; cursor: pointer; transition: background 0.15s, border-color 0.15s; appearance: none; -webkit-appearance: none; background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6'%3E%3Cpath d='M0 0l5 6 5-6z' fill='%23888'/%3E%3C/svg%3E"); background-repeat: no-repeat; background-position: right 8px center; padding-right: 24px; min-width: 0; max-width: 160px; text-overflow: ellipsis; align-self: flex-start; } .preset-select:hover, .preset-select:focus { border-color: rgba(255, 255, 255, 0.15); background-color: rgba(255, 255, 255, 0.06); outline: none; } .preset-select option, .preset-select optgroup { background: #1a1a1a; color: var(--text); } /* ---- Utility ---- */ .hidden { display: none !important; } /* ---- Group Override Drawer ---- */ .group-drawer { position: fixed; z-index: 50; width: 320px; max-height: 60vh; overflow-y: auto; background: rgba(13, 13, 13, 0.92); backdrop-filter: blur(20px); -webkit-backdrop-filter: blur(20px); border: 1px solid rgba(255, 255, 255, 0.1); border-radius: var(--radius-sm); padding: 0; opacity: 0; pointer-events: none; transform: translateY(-4px); transition: opacity 0.15s, transform 0.15s; } .group-drawer.visible { opacity: 1; pointer-events: auto; transform: translateY(0); } .group-drawer-header { padding: 6px 10px; font-size: 12px; font-weight: 700; letter-spacing: 0.5px; border-bottom: 1px solid rgba(255, 255, 255, 0.06); } .group-drawer-body { padding: 6px 8px 8px; } /* Group curve row */ .gd-curve-row { display: flex; align-items: center; gap: 6px; margin-bottom: 8px; padding-bottom: 6px; border-bottom: 1px solid rgba(255, 255, 255, 0.04); } .gd-label { font-size: 10px; color: var(--text-dim); text-transform: uppercase; letter-spacing: 0.5px; min-width: 34px; flex-shrink: 0; } .gd-curve-canvas { width: 48px; height: 48px; border-radius: 4px; border: 1px solid rgba(255, 255, 255, 0.06); flex-shrink: 0; } .gd-val { font-size: 10px; color: var(--text-dim); min-width: 30px; text-align: right; font-variant-numeric: tabular-nums; flex-shrink: 0; } /* Per-param row */ .gd-param-row { display: flex; align-items: center; gap: 4px; margin-bottom: 2px; min-height: 28px; } .gd-param-name { font-size: 9px; color: var(--text-dim); min-width: 52px; max-width: 52px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; flex-shrink: 0; } /* Per-param curve mini-canvas */ .gd-param-curve-canvas { width: 28px; height: 28px; border-radius: 3px; border: 1px solid rgba(255, 255, 255, 0.06); flex-shrink: 0; } /* Dual-range slider wrapper */ .gd-range-wrap { position: relative; flex: 1; height: 16px; min-width: 0; } .gd-range-fill { position: absolute; top: 50%; height: 3px; transform: translateY(-50%); background: var(--accent); border-radius: 2px; pointer-events: none; opacity: 0.6; } .gd-range-input { position: absolute; width: 100%; top: 0; left: 0; height: 16px; margin: 0; padding: 0; -webkit-appearance: none; appearance: none; background: transparent; pointer-events: none; } .gd-range-input::-webkit-slider-runnable-track { height: 3px; background: transparent; border-radius: 2px; } .gd-range-input::-webkit-slider-thumb { -webkit-appearance: none; appearance: none; pointer-events: auto; width: 10px; height: 10px; border-radius: 50%; border: 1px solid rgba(255, 255, 255, 0.3); cursor: pointer; margin-top: -3.5px; } .gd-range-min::-webkit-slider-thumb { background: #4488ff; } .gd-range-max::-webkit-slider-thumb { background: #ff6a00; } /* Firefox dual-range */ .gd-range-input::-moz-range-track { height: 3px; background: transparent; border: none; } .gd-range-input::-moz-range-thumb { pointer-events: auto; width: 10px; height: 10px; border-radius: 50%; border: 1px solid rgba(255, 255, 255, 0.3); cursor: pointer; } .gd-range-min::-moz-range-thumb { background: #4488ff; } .gd-range-max::-moz-range-thumb { background: #ff6a00; } /* Value slider (shown when muted) */ .gd-val-slider { flex: 1; min-width: 0; accent-color: #888; height: 3px; display: none; } /* Mute button */ .gd-mute-btn { width: 20px; height: 20px; border-radius: 3px; border: 1px solid rgba(255, 255, 255, 0.1); background: transparent; color: rgba(255, 255, 255, 0.25); font-size: 9px; font-weight: 700; cursor: pointer; flex-shrink: 0; padding: 0; line-height: 18px; text-align: center; transition: all 0.1s; } .gd-mute-btn:hover { border-color: rgba(255, 255, 255, 0.3); color: rgba(255, 255, 255, 0.5); } .gd-mute-btn.muted { background: rgba(255, 60, 60, 0.2); border-color: rgba(255, 60, 60, 0.4); color: #ff5555; } /* Muted param row: hide curve + range, show value slider */ .gd-param-row.gd-muted .gd-param-curve-canvas, .gd-param-row.gd-muted .gd-range-wrap { display: none; } .gd-param-row.gd-muted .gd-val-slider { display: block; } .gd-param-row.gd-muted .gd-param-name { color: rgba(255, 255, 255, 0.2); text-decoration: line-through; } /* Drawer scrollbar */ .group-drawer::-webkit-scrollbar { width: 3px; } .group-drawer::-webkit-scrollbar-track { background: transparent; } .group-drawer::-webkit-scrollbar-thumb { background: rgba(255, 255, 255, 0.1); border-radius: 2px; } /* ---- Scrollbar styling ---- */ .bottom-sheet::-webkit-scrollbar { width: 4px; } .bottom-sheet::-webkit-scrollbar-track { background: transparent; } .bottom-sheet::-webkit-scrollbar-thumb { background: rgba(255, 255, 255, 0.1); border-radius: 2px; } /* ---- Help button ---- */ .help-btn { position: fixed; bottom: 96px; right: 12px; z-index: 45; width: 32px; height: 32px; border-radius: 50%; border: 1px solid var(--glass-border); background: var(--glass-bg); backdrop-filter: blur(var(--glass-blur)); -webkit-backdrop-filter: blur(var(--glass-blur)); color: var(--text-dim); font-size: 16px; font-weight: 700; cursor: pointer; display: flex; align-items: center; justify-content: center; transition: all 0.15s; padding: 0; line-height: 1; } .help-btn:hover, .help-btn:active { border-color: var(--accent); color: var(--accent); } /* ---- Help modal ---- */ .help-overlay { position: fixed; inset: 0; z-index: 100; background: rgba(0, 0, 0, 0.7); backdrop-filter: blur(6px); -webkit-backdrop-filter: blur(6px); display: flex; align-items: center; justify-content: center; padding: 16px; animation: helpFadeIn 0.2s ease-out; } .help-overlay.hidden { display: none; } @keyframes helpFadeIn { from { opacity: 0; } to { opacity: 1; } } .help-modal { position: relative; max-width: 520px; width: 100%; max-height: 85vh; overflow-y: auto; background: rgba(18, 18, 18, 0.95); backdrop-filter: blur(20px); -webkit-backdrop-filter: blur(20px); border: 1px solid rgba(255, 255, 255, 0.1); border-radius: var(--radius); padding: 28px 24px 20px; color: var(--text); } .help-modal h2 { font-size: 18px; font-weight: 700; margin: 0 0 2px; color: #fff; } .help-subtitle { font-size: 11px; color: var(--text-dim); margin: 0 0 16px; letter-spacing: 0.5px; } .help-close { position: absolute; top: 12px; right: 12px; width: 28px; height: 28px; border-radius: 50%; border: 1px solid var(--glass-border); background: rgba(255, 255, 255, 0.06); color: var(--text-dim); font-size: 18px; cursor: pointer; display: flex; align-items: center; justify-content: center; padding: 0; line-height: 1; transition: all 0.15s; } .help-close:hover { border-color: var(--accent); color: var(--accent); } .help-section { margin-bottom: 16px; } .help-section h3 { font-size: 13px; font-weight: 700; color: var(--accent); margin: 0 0 6px; text-transform: uppercase; letter-spacing: 0.5px; } .help-section p { font-size: 12px; line-height: 1.5; margin: 0 0 6px; color: var(--text); } .help-section ul { margin: 0; padding-left: 18px; font-size: 12px; line-height: 1.6; color: var(--text); } .help-section li { margin-bottom: 2px; } .help-keys { width: 100%; border-collapse: collapse; font-size: 12px; } .help-keys th { text-align: left; padding: 8px 0 4px; color: var(--text-dim); font-size: 11px; text-transform: uppercase; letter-spacing: 0.5px; border-bottom: 1px solid rgba(255, 255, 255, 0.06); } .help-keys td { padding: 3px 0; color: var(--text); } .help-keys td:first-child { color: #fff; font-weight: 500; width: 45%; } .help-keys kbd { display: inline-block; padding: 1px 6px; border-radius: 3px; border: 1px solid rgba(255, 255, 255, 0.15); background: rgba(255, 255, 255, 0.06); font-family: inherit; font-size: 11px; } .help-got-it { display: block; width: 100%; padding: 10px; margin-top: 8px; border-radius: 6px; border: 1px solid rgba(255, 106, 0, 0.3); background: rgba(255, 106, 0, 0.1); color: var(--accent); font-size: 14px; font-weight: 600; cursor: pointer; transition: all 0.15s; } .help-got-it:active { background: rgba(255, 106, 0, 0.25); } /* Help modal scrollbar */ .help-modal::-webkit-scrollbar { width: 4px; } .help-modal::-webkit-scrollbar-track { background: transparent; } .help-modal::-webkit-scrollbar-thumb { background: rgba(255, 255, 255, 0.1); border-radius: 2px; } /* ---- Media queries ---- */ @media (min-width: 768px) { .joystick-container { width: 180px; height: 180px; bottom: 156px; left: 32px; } #joy-map { width: 180px; height: 180px; } .hand-pip { width: 200px; height: 150px; bottom: 156px; left: 32px; } .rl-buttons { bottom: 92px; gap: 32px; } .rl-btn { width: 72px; height: 72px; font-size: 32px; } } @media (min-width: 1024px) { .bottom-sheet { max-width: 600px; left: 50%; transform: translateX(-50%); } }