:root { --time-signature-numerator: 4; --max-number-of-bars: 32; --track-grid-bar-width: 40px; --region-piano-key-width: 60px; --region-piano-key-height: 20px; --region-grid-beat-width: 40px; --region-grid-bar-width: calc(var(--region-grid-beat-width) * var(--time-signature-numerator)); --chat-box-width: 350px; --instrument-selection-width: 300px; } /* Reset default styles */ * { margin: 0; padding: 0; box-sizing: border-box; } #root { width: 100%; height: 100vh; margin: 0; padding: 0; text-align: left; display: flex; flex-direction: column; } body { font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; background-color: #1e1e1e; color: #e0e0e0; } /* Main container */ .daw-container { display: flex; flex-direction: column; height: 100vh; width: 100%; overflow: hidden; } /* Main Display Area */ .main-display-area { display: flex; flex-direction: row; flex: 1; overflow: hidden; } /* Toolbar */ .toolbar { display: flex; justify-content: space-between; align-items: center; background-color: #2d2d2d; height: 50px; padding: 0 10px; border-bottom: 1px solid #3a3a3a; } .toolbar-left, .toolbar-center, .toolbar-right { display: flex; align-items: center; } .toolbar-left { display: flex; align-items: center; } .logo-container { margin-right: 10px; display: flex; align-items: center; } .logo { height: 30px; width: auto; } .project-name { font-size: 14px; color: #e0e0e0; margin-right: 20px; display: flex; align-items: center; pointer-events: auto; } .toolbar button { background: transparent; border: none; color: #e0e0e0; margin: 0 5px; padding: 5px; cursor: pointer; display: flex; align-items: center; justify-content: center; border-radius: 3px; font-size: 14px; pointer-events: auto; } .toolbar button:hover { background-color: #3a3a3a; } .toolbar button:disabled { color: #666; cursor: not-allowed; } .record-btn { color: #ff4444; } .toolbar-separator { width: 1px; height: 20px; background-color: #555; margin: 0 10px; } .transport-control { display: flex; align-items: center; margin: 0 10px; pointer-events: auto; } .transport-item { margin: 0 5px; padding: 2px 2px; background-color: #3a3a3a; border-radius: 3px; font-size: 12px; } /* Fixed-width font for time display to prevent layout shifts */ .current-time { font-family: 'Courier New', 'Monaco', 'Menlo', 'Ubuntu Mono', monospace; font-weight: normal; letter-spacing: 0.5px; padding: 2px 4px; } /* Clickable BPM styling */ .current-bpm { font-family: 'Courier New', 'Monaco', 'Menlo', 'Ubuntu Mono', monospace; font-weight: normal; letter-spacing: 0.5px; cursor: pointer; transition: background-color 0.2s ease; padding: 2px 4px; border-radius: 2px; } .current-bpm:hover { background-color: #4a4a4a; color: #fff; } /* Clickable time signature styling */ .current-time-signature { font-family: 'Courier New', 'Monaco', 'Menlo', 'Ubuntu Mono', monospace; font-weight: normal; letter-spacing: 0.5px; cursor: pointer; transition: background-color 0.2s ease; padding: 2px 4px; border-radius: 2px; } .current-time-signature:hover { background-color: #4a4a4a; color: #fff; } .current-key-signature { font-family: 'Courier New', 'Monaco', 'Menlo', 'Ubuntu Mono', monospace; font-weight: normal; letter-spacing: 0.5px; cursor: pointer; transition: background-color 0.2s ease; padding: 2px 4px; border-radius: 2px; } .current-key-signature:hover { background-color: #4a4a4a; color: #fff; } .export-dropdown .quant-dropdown { width: 250px; left: 0; } /* Main content */ .main-content { display: flex; flex-direction: column; flex: 1; overflow: auto; /* Main scrollable container */ position: relative; } .main-content-wrapper { display: flex; flex-direction: column; min-width: calc(200px + var(--max-number-of-bars) * var(--track-grid-bar-width)); /* info width + grid width */ min-height: fit-content; position: relative; } .top-left-spacer { position: fixed; top: 50px; left: 0; width: 200px; height: 20px; background-color: #2d2d2d; border-bottom: 1px solid #3a3a3a; border-right: 1px solid #3a3a3a; z-index: 1002; /* Higher than other elements to ensure it's always visible */ } /* Offset spacer when instrument selection panel is visible on the left */ .main-content.has-left-instrument .top-left-spacer { left: 300px; } .bar-numbers { position: sticky; top: 0; height: 20px; display: flex; border-bottom: 1px solid #3a3a3a; background-color: #2d2d2d; z-index: 20; margin-left: 200px; /* Offset for info-container */ width: calc(var(--max-number-of-bars) * var(--track-grid-bar-width)); /* Exact width for 32 bars */ cursor: pointer; /* Show pointer cursor on hover to indicate interactivity */ } .bar-numbers:hover { cursor: url("data:image/svg+xml,%3csvg width='16' height='16' xmlns='http://www.w3.org/2000/svg'%3e%3cpath d='M4 6h8l-4 4-4-4z' fill='%23e0e0e0'/%3e%3c/svg%3e") 8 8, pointer; } .bar-number-cell { min-width: var(--track-grid-bar-width); width: var(--track-grid-bar-width); flex-shrink: 0; flex-grow: 0; height: 20px; text-align: center; font-size: 12px; border-right: 1px solid #3a3a3a; color: #999; display: flex; align-items: center; justify-content: center; box-sizing: border-box; } .main-content-body { display: flex; min-height: fit-content; } .info-container { position: sticky; left: 0; width: 200px; z-index: 1002; background-color: #2d2d2d; align-self: flex-start; } /* Shift the bar numbers and info panel when instrument selection is present */ /* No need to shift bar numbers or info container; they live inside main content. Only shift the fixed spacer when the left panel is present. */ .track-top-spacer { height: 20px; border-bottom: 1px solid #3a3a3a; background-color: #2d2d2d; position: sticky; top: 0; z-index: 15; } .grid-container { margin-left: 0; /* No need for margin since we're using flex */ min-width: calc(var(--max-number-of-bars) * var(--track-grid-bar-width)); /* Ensure minimum width */ min-height: fit-content; position: relative; /* Required for absolute positioned playhead */ } .track-grid { display: block; height: 120px; min-width: calc(var(--max-number-of-bars) * var(--track-grid-bar-width)); /* 32 bars * --track-grid-bar-width */ background-size: var(--track-grid-bar-width) 120px; background-image: /* Vertical lines for bars */ linear-gradient(to right, transparent calc(var(--track-grid-bar-width) - 1px), #3a3a3a calc(var(--track-grid-bar-width) - 1px), #3a3a3a var(--track-grid-bar-width) ); position: relative; border-bottom: 1px solid #3a3a3a; } .track-grid.pencil-cursor { cursor: crosshair; } .track-control { padding: 5px; background-color: #2d2d2d; border-top: 1px solid #3a3a3a; } .track-control button { background: transparent; border: none; color: #999; cursor: pointer; padding: 5px; width: 100%; text-align: left; font-size: 12px; } .track-control button:hover { color: #e0e0e0; } .track { display: flex; height: 120px; position: relative; border-bottom: none; } .track-info { width: 200px; height: 120px; padding: 15px; background-color: #2d2d2d; display: flex; flex-direction: column; border-right: 1px solid #3a3a3a; border-bottom: 1px solid #3a3a3a; flex-shrink: 0; box-sizing: border-box; cursor: grab; position: relative; } .track-info:active { cursor: grabbing; } .track-info.selected { background-color: #363636; } /* Drag and drop styles */ .track-info.drag-over { border-top: 2px solid #7b68ee; } .track-grid.drag-over { border-top: 2px solid #7b68ee; } /* Dragging state */ .track-info.dragging { opacity: 0.5; background-color: #444; } .track-grid.dragging { opacity: 0.5; background-color: #333; } /* Remove drag indicator since hover cursor is sufficient */ .track-name { font-size: 12px; cursor: pointer; position: relative; } .track-name:hover { color: #7b68ee; } .track-name:hover::before { content: "✎"; position: absolute; right: 0px; font-size: 16px; opacity: 1; } .track-controls { display: flex; flex-direction: column; width: 100%; height: 100%; } .track-name-and-volume { display: flex; flex-direction: row; flex: 1; align-items: flex-start; gap: 8px; } .instrument-image { flex-shrink: 0; margin-top: -10px; margin-left: -10px; } .instrument-image img { display: block; border-radius: 4px; } .track-name-and-controls { display: flex; flex-direction: column; flex: 1; min-width: 0; } .volume-slider { margin-bottom: 15px; width: 100%; display: flex; align-items: center; gap: 6px; } .volume-slider input[type="range"] { flex: 1; min-width: 0; height: 6px; } .volume-slider .reset-volume { flex-shrink: 0; width: 16px; height: 16px; border-radius: 8px; background: #3a3a3a; color: #e0e0e0; /* border: 1px solid #444; */ display: inline-flex; align-items: center; justify-content: center; cursor: pointer; font-size: 10px; } .volume-slider .reset-volume:hover { background: #4a4a4a; } .pan-controls { display: flex; } .pan-controls button { background: #3a3a3a; border: none; color: #e0e0e0; margin-right: 5px; width: 24px; height: 24px; font-size: 12px; border-radius: 2px; cursor: pointer; display: flex; align-items: center; justify-content: center; } .pan-controls button.solo.active { background: #c8a400; /* yellow */ color: #101010; } .pan-controls button.mute.active { background: #d32f2f; /* red */ color: #ffffff; } /* Status bar */ .status-bar { display: flex; justify-content: space-between; align-items: center; background-color: #2d2d2d; padding: 5px 10px; font-size: 12px; color: #999; border-top: 1px solid #3a3a3a; height: 30px; } .status-right span { margin-left: 15px; } /* For the piano roll (to be implemented later) */ .piano-roll { background-color: #7b68ee; height: 100%; } /* Piano Roll Panel */ .piano-roll-panel { position: fixed; background-color: #2d2d2d; border: 1px solid #3a3a3a; box-shadow: 0 0 20px rgba(0, 0, 0, 0.5); display: flex; flex-direction: column; overflow: hidden; } /* Piano notes */ .piano-note { position: absolute; background-color: #ff5555; /* Red color */ border: 1px solid #999; border-radius: 2px; z-index: 10; cursor: pointer; user-select: none; box-sizing: border-box; } .piano-note:hover { filter: brightness(1.1); box-shadow: 0 0 5px rgba(255, 85, 85, 0.5); } .piano-note.dragging { opacity: 0.8; box-shadow: 0 0 10px rgba(0, 0, 0, 0.5); z-index: 100; cursor: grabbing; } .piano-note.resizing { opacity: 0.8; box-shadow: 0 0 10px rgba(255, 85, 85, 0.7); z-index: 100; } .piano-note.selected { border: 2px solid white; z-index: 50; } .piano-roll-header { height: 30px; background-color: #1e1e1e; border-bottom: 1px solid #3a3a3a; display: flex; align-items: center; padding: 0 10px; cursor: move; user-select: none; } /* Piano roll toolbar */ .piano-roll-toolbar { height: 30px; background-color: #252525; border-bottom: 1px solid #3a3a3a; display: flex; align-items: center; justify-content: space-between; padding: 0 10px; user-select: none; position: relative; } /* Override pointer-events for piano roll toolbar sections */ .piano-roll-toolbar .toolbar-left, .piano-roll-toolbar .toolbar-right { pointer-events: auto; } .piano-roll-toolbar .quant-button { font-size: 10px; } /* Generic button blink effect */ .quant-button.button-blink { animation: buttonBlink 0.2s ease-in-out; } @keyframes buttonBlink { 0% { background-color: #333; } 50% { background-color: #555; } 100% { background-color: #333; } } .toolbar-left, .toolbar-right { display: flex; align-items: center; z-index: 1; pointer-events: none; } .toolbar-left { width: 20%; justify-content: flex-start; } .toolbar-right { width: 33%; justify-content: flex-end; z-index: 1500; } .toolbar-center { position: absolute; left: 50%; transform: translateX(-50%); display: flex; align-items: center; justify-content: center; z-index: 1005; margin-left: -50px; } .tool-button { width: 30px; height: 30px; background-color: transparent; border: none; border-radius: 3px; color: #999; font-size: 14px; display: flex; align-items: center; justify-content: center; cursor: pointer; margin: 0 2px; } .tool-button:hover { background-color: #3a3a3a; color: #e0e0e0; } .tool-button.active { background-color: #4a4a4a; color: #e0e0e0; } .chatbox-export-dropdown .quant-dropdown { width: 250px; left: -200px; } .key-signature-dropdown .quant-dropdown { width: 100px; left: 0; } .quant-button { background-color: #333; border: 1px solid #444; border-radius: 3px; color: #e0e0e0; font-size: 12px; padding: 3px 8px; margin-left: 5px; cursor: pointer; display: flex; align-items: center; gap: 5px; } .quant-button:hover { background-color: #444; } .quant-dropdown-container { position: relative; display: inline-block; z-index: 1500; } .quant-dropdown { position: absolute; top: 100%; right: 0; background-color: #2d2d2d; border: 1px solid #444; border-radius: 3px; width: 100px; z-index: 1500; box-shadow: 0 2px 8px rgba(0, 0, 0, 0.3); margin-top: 2px; max-height: 200px; overflow-y: auto; } .quant-option { padding: 6px 10px; font-size: 12px; color: #e0e0e0; cursor: pointer; transition: background-color 0.2s; } .quant-option:hover { background-color: #444; } .quant-option.active { background-color: #4a6b8a; } .piano-roll-title { flex: 1; text-align: center; font-size: 14px; color: #e0e0e0; text-transform: uppercase; cursor: pointer; padding: 5px; border-radius: 3px; } .close-button { background: transparent; border: none; color: #e0e0e0; cursor: pointer; font-size: 14px; padding: 5px; } .close-button:hover { color: #ff4444; } .piano-roll-content { display: flex; flex-direction: column; flex: 1; overflow: auto; } .piano-grid-header { display: grid; grid-template-columns: repeat(var(--max-number-of-bars), var(--region-grid-bar-width)); width: calc(var(--max-number-of-bars) * var(--region-grid-bar-width) + var(--region-piano-key-width) - 1px); min-width: 100%; height: 20px; border-bottom: 1px solid #3a3a3a; background-color: #1e1e1e; padding-left: calc(var(--region-piano-key-width) - 1px); box-sizing: border-box; position: sticky; top: 0; z-index: 20; cursor: pointer; /* Show pointer cursor on hover to indicate interactivity */ } .piano-grid-header:hover { cursor: url("data:image/svg+xml,%3csvg width='16' height='16' xmlns='http://www.w3.org/2000/svg'%3e%3cpath d='M4 6h8l-4 4-4-4z' fill='%23e0e0e0'/%3e%3c/svg%3e") 8 8, pointer; } .piano-bar-number { border-left: 1px solid #3a3a3a; padding-left: 10px; font-size: 10px; } .piano-roll-body { display: flex; min-height: calc(8 * 12 * var(--region-piano-key-height)); /* 8 octaves * 12 notes * piano key height */ width: calc(var(--max-number-of-bars) * var(--region-grid-bar-width) + var(--region-piano-key-width)); /* 32 bars * 160px width + piano keys width */ } .piano-keys-container { width: var(--region-piano-key-width); flex-shrink: 0; overflow: hidden; border-right: 1px solid #3a3a3a; background-color: #252525; position: sticky; left: 0; z-index: 10; } .piano-grid-container { flex: 1; min-width: calc(var(--max-number-of-bars) * var(--region-grid-bar-width)); min-height: calc(8 * 12 * var(--region-piano-key-height)); z-index: 5; } .piano-octave { display: flex; flex-direction: column; } .piano-key { width: var(--region-piano-key-width); height: var(--region-piano-key-height); box-sizing: border-box; display: flex; align-items: center; border-bottom: 1px solid #3a3a3a; } .piano-key.natural { background-color: #e0e0e0; color: #222; } .piano-key.sharp { background-color: #222; color: #e0e0e0; } .key-label { font-size: 10px; padding-left: 5px; } .piano-grid { width: 100%; height: 100%; position: relative; background-size: var(--region-grid-beat-width) var(--region-piano-key-height), var(--region-grid-bar-width) var(--region-piano-key-height); background-image: /* Vertical lines for beats */ linear-gradient(to right, transparent calc(var(--region-grid-beat-width) - 1px), #444 calc(var(--region-grid-beat-width) - 1px), #444 var(--region-grid-beat-width), transparent calc(var(--region-grid-beat-width)), transparent calc(var(--region-grid-beat-width) * 2 - 1px), #444 calc(var(--region-grid-beat-width) * 2 - 1px), #444 calc(var(--region-grid-beat-width) * 2), transparent calc(var(--region-grid-beat-width) * 2), transparent calc(var(--region-grid-beat-width) * 3 - 1px), #444 calc(var(--region-grid-beat-width) * 3 - 1px), #444 calc(var(--region-grid-beat-width) * 3), transparent calc(var(--region-grid-beat-width) * 3), transparent calc(var(--region-grid-beat-width) * 4 - 1px), #3a3a3a calc(var(--region-grid-beat-width) * 4 - 1px), #3a3a3a calc(var(--region-grid-beat-width) * 4) ), /* Horizontal lines for notes */ linear-gradient(to bottom, transparent calc(var(--region-piano-key-height) - 1px), #3a3a3a calc(var(--region-piano-key-height) - 1px), #3a3a3a var(--region-piano-key-height) ); } .piano-grid.pencil-cursor { cursor: crosshair; } /* Piano Grid Cursor Highlights */ .piano-grid-pitch-highlight { position: absolute; left: 0; right: 0; background-color: rgba(123, 104, 238, 0.15); border-top: 1px solid rgba(123, 104, 238, 0.3); border-bottom: 1px solid rgba(123, 104, 238, 0.3); pointer-events: none; z-index: 1; transition: opacity 0.1s ease; } .piano-grid-beat-highlight { position: absolute; top: 0; bottom: 0; background-color: rgba(123, 104, 238, 0.1); border-left: 1px solid rgba(123, 104, 238, 0.25); border-right: 1px solid rgba(123, 104, 238, 0.25); pointer-events: none; z-index: 1; transition: opacity 0.1s ease; } .resize-handle { position: absolute; right: 5px; bottom: 5px; width: 20px; height: 20px; cursor: nwse-resize; color: #999; display: flex; align-items: center; justify-content: center; z-index: 100; } /* Track Region Styles */ .track-region { position: absolute; background-color: #4a6b8a; border: 2px solid #5a7b9a; border-radius: 3px; height: calc(100%); margin: 0px; overflow: hidden; display: flex; flex-direction: column; cursor: pointer; user-select: none; transition: box-shadow 0.1s ease; will-change: transform; } .track-region:hover { box-shadow: 0 0 0 1px #7a9bba; } .track-region.selected { /* box-shadow: 0 0 0 2px #ffffff, 0 0 8px rgba(255, 255, 255, 0.3); */ /* let's only apply a border */ border-color: #ffffff; } .track-region.dragging { opacity: 0.8; box-shadow: 0 0 10px rgba(0, 0, 0, 0.5); z-index: 100; pointer-events: none; transform-origin: center center; animation: pulse 1.5s infinite; cursor: grabbing; transition: none; /* Remove transition during drag for immediate response */ } @keyframes pulse { 0% { box-shadow: 0 0 0 0 rgba(122, 155, 186, 0.7); } 70% { box-shadow: 0 0 0 5px rgba(122, 155, 186, 0); } 100% { box-shadow: 0 0 0 0 rgba(122, 155, 186, 0); } } .region-header { background-color: #5a7b9a; color: #fff; padding: 2px 6px; font-size: 11px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; cursor: move; height: 18px; user-select: none; } .track-region:hover .region-header { background-color: #6a8baa; } .region-content { height: calc(100% - 18px); background-color: #87CEFA; /* Light blue */ width: 100%; position: relative; /* Allow overlayed controls */ } /* Region pencil trigger inside content */ .region-pencil-btn { position: absolute; top: 4px; left: 4px; background: rgba(0, 0, 0, 0.25); color: #fff; border: 1px solid rgba(255, 255, 255, 0.2); border-radius: 3px; padding: 2px; margin: 0; cursor: pointer; z-index: 2; display: inline-flex; align-items: center; justify-content: center; } .region-pencil-btn:hover { background: rgba(0, 0, 0, 0.35); } /* Instrument dropdown specific styles */ .instrument-dropdown .quant-dropdown { min-width: 80px; width: auto; right: auto; left: 0; } /* Settings dropdown specific styles */ .settings-dropdown .quant-dropdown { min-width: 100px; width: auto; right: auto; left: 0; } /* Update structure in JSX to match this pattern: