:root { --bg: #08111f; --panel: rgba(7, 20, 36, 0.72); --panel-strong: rgba(12, 29, 50, 0.92); --panel-border: rgba(152, 214, 255, 0.16); --text: #eef7ff; --muted: #9cb2c5; --accent: #65f2d1; --accent-2: #ffb36a; --accent-3: #87a7ff; --danger: #ff7c74; --shadow: 0 24px 80px rgba(0, 0, 0, 0.38); } * { box-sizing: border-box; } html, body { margin: 0; min-height: 100%; } body { position: relative; overflow-x: hidden; background: radial-gradient(circle at top, rgba(95, 151, 255, 0.18), transparent 30%), linear-gradient(180deg, #091320 0%, #050a12 100%); color: var(--text); font-family: "Space Grotesk", sans-serif; } button, select { font: inherit; } code { padding: 0.14rem 0.35rem; border-radius: 0.45rem; background: rgba(255, 255, 255, 0.08); font-family: "IBM Plex Mono", monospace; font-size: 0.92em; } .backdrop { position: fixed; inset: 0; overflow: hidden; pointer-events: none; } .backdrop__orb { position: absolute; border-radius: 999px; filter: blur(36px); opacity: 0.55; } .backdrop__orb--left { top: 10%; left: -8%; width: 22rem; height: 22rem; background: rgba(101, 242, 209, 0.2); animation: drift 16s ease-in-out infinite; } .backdrop__orb--right { right: -5%; bottom: 8%; width: 26rem; height: 26rem; background: rgba(255, 179, 106, 0.16); animation: drift 20s ease-in-out infinite reverse; } .backdrop__grid { position: absolute; inset: 0; background-image: linear-gradient(rgba(135, 167, 255, 0.06) 1px, transparent 1px), linear-gradient(90deg, rgba(135, 167, 255, 0.06) 1px, transparent 1px); background-size: 3rem 3rem; mask-image: linear-gradient(180deg, rgba(0, 0, 0, 0.6), transparent 85%); } .app { position: relative; z-index: 1; width: min(1100px, calc(100% - 2rem)); margin: 0 auto; padding: 2rem 0 3rem; } .hero { padding: 1rem 0 2rem; animation: rise 700ms ease-out both; } .eyebrow { margin: 0 0 0.75rem; color: var(--accent); font-family: "IBM Plex Mono", monospace; font-size: 0.9rem; letter-spacing: 0.16em; text-transform: uppercase; } .hero h1 { margin: 0; max-width: 12ch; font-size: clamp(2.7rem, 7vw, 5.8rem); line-height: 0.92; letter-spacing: -0.05em; } .hero__copy { max-width: 42rem; margin: 1.1rem 0 0; color: var(--muted); font-size: clamp(1rem, 2.2vw, 1.18rem); line-height: 1.6; } .controls, .legend { display: grid; gap: 1rem; } .controls { grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); align-items: stretch; margin-bottom: 1.4rem; animation: rise 850ms ease-out both; } .power, .control-card, .key { border: 1px solid var(--panel-border); box-shadow: var(--shadow); backdrop-filter: blur(18px); } .power, .control-card { min-height: 5.4rem; border-radius: 1.25rem; background: var(--panel); } .power { padding: 1rem 1.25rem; color: var(--text); font-weight: 700; cursor: pointer; text-transform: uppercase; letter-spacing: 0.08em; transition: transform 180ms ease, border-color 180ms ease, background 180ms ease; } .power:hover, .power:focus-visible { transform: translateY(-2px); border-color: rgba(101, 242, 209, 0.5); background: rgba(11, 35, 58, 0.96); } .power--armed { border-color: rgba(101, 242, 209, 0.7); color: #021117; background: linear-gradient(135deg, var(--accent), #c2fff0); } .control-card { display: flex; flex-direction: column; justify-content: center; gap: 0.45rem; padding: 0.95rem 1.15rem; } .control-card__label { color: var(--muted); font-family: "IBM Plex Mono", monospace; font-size: 0.85rem; letter-spacing: 0.08em; text-transform: uppercase; } select { width: 100%; padding: 0.7rem 0.85rem; border: 1px solid rgba(152, 214, 255, 0.18); border-radius: 0.85rem; background: rgba(5, 12, 22, 0.55); color: var(--text); } .mapping-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 0.7rem; } .mini-field { display: grid; gap: 0.35rem; } .mini-field span { color: var(--muted); font-family: "IBM Plex Mono", monospace; font-size: 0.76rem; letter-spacing: 0.06em; text-transform: uppercase; } .octave-controls { display: flex; align-items: center; gap: 0.75rem; } .octave-controls button, .octave-controls output { display: grid; place-items: center; height: 2.5rem; min-width: 2.5rem; border-radius: 999px; } .octave-controls button { border: 1px solid rgba(152, 214, 255, 0.18); background: rgba(5, 12, 22, 0.55); color: var(--text); cursor: pointer; } .octave-controls output { padding: 0 0.8rem; background: rgba(255, 255, 255, 0.06); font-weight: 700; } .note-display { margin: 0; font-size: 1.05rem; } .metronome-controls { display: flex; align-items: center; justify-content: space-between; gap: 0.8rem; } .metronome-toggle { padding: 0.55rem 0.9rem; border: 1px solid rgba(152, 214, 255, 0.18); border-radius: 999px; background: rgba(5, 12, 22, 0.55); color: var(--text); cursor: pointer; } .metronome-toggle.is-running { border-color: rgba(255, 179, 106, 0.7); background: rgba(77, 44, 15, 0.8); } .metronome-status { display: flex; align-items: center; gap: 0.55rem; color: var(--text); font-family: "IBM Plex Mono", monospace; font-size: 0.9rem; } .metronome-light { width: 0.8rem; height: 0.8rem; border-radius: 999px; background: rgba(255, 255, 255, 0.16); box-shadow: inset 0 0 0 1px rgba(152, 214, 255, 0.14); transition: background 100ms ease, box-shadow 100ms ease, transform 100ms ease; } .metronome-light.is-pulsing { background: var(--accent-2); box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.1), 0 0 18px rgba(255, 179, 106, 0.5); transform: scale(1.15); } .metronome-light.is-accent { background: var(--accent); box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.1), 0 0 20px rgba(101, 242, 209, 0.55); } .tempo-control { display: grid; gap: 0.45rem; margin-top: 0.35rem; color: var(--muted); font-family: "IBM Plex Mono", monospace; font-size: 0.82rem; } .tempo-control input { width: 100%; accent-color: var(--accent-2); } .board { display: grid; gap: 0.9rem; padding: 1.3rem; border: 1px solid rgba(152, 214, 255, 0.14); border-radius: 1.8rem; background: linear-gradient(180deg, rgba(9, 22, 38, 0.78), rgba(7, 15, 28, 0.92)); box-shadow: var(--shadow); animation: rise 1s ease-out both; } .sequencer { margin-top: 1.1rem; padding: 1.35rem; border: 1px solid rgba(152, 214, 255, 0.14); border-radius: 1.8rem; background: linear-gradient(180deg, rgba(10, 22, 38, 0.84), rgba(8, 16, 28, 0.94)); box-shadow: var(--shadow); animation: rise 1.08s ease-out both; } .sequencer__header { display: flex; align-items: end; justify-content: space-between; gap: 1rem; margin-bottom: 1rem; } .sequencer__header h2 { margin: 0; font-size: clamp(1.5rem, 4vw, 2.4rem); line-height: 1; letter-spacing: -0.04em; } .sequencer__copy { max-width: 36rem; margin: 0.5rem 0 0; color: var(--muted); line-height: 1.55; } .sequencer__transport { display: flex; flex-wrap: wrap; justify-content: end; gap: 0.65rem; } .sequencer-button { padding: 0.72rem 1rem; border: 1px solid rgba(101, 242, 209, 0.28); border-radius: 999px; background: rgba(14, 42, 56, 0.9); color: var(--text); cursor: pointer; transition: transform 140ms ease, border-color 140ms ease, background 140ms ease; } .sequencer-button:hover, .sequencer-button:focus-visible { transform: translateY(-2px); border-color: rgba(101, 242, 209, 0.55); } .sequencer-button.is-running { border-color: rgba(255, 179, 106, 0.78); background: rgba(78, 46, 17, 0.88); } .sequencer-button--ghost { border-color: rgba(152, 214, 255, 0.18); background: rgba(5, 12, 22, 0.55); } .sequencer-grid { overflow-x: auto; } .sequencer-grid__inner { display: grid; grid-template-columns: 8rem repeat(16, minmax(2.4rem, 1fr)); gap: 0.5rem; min-width: 54rem; } .sequencer-grid__step-label, .sequencer-lane__name, .sequencer-step { min-height: 3rem; } .sequencer-grid__step-label { display: grid; place-items: center; border-radius: 0.8rem; color: rgba(238, 247, 255, 0.6); font-family: "IBM Plex Mono", monospace; font-size: 0.8rem; background: rgba(255, 255, 255, 0.04); } .sequencer-grid__step-label.is-accent { color: var(--accent-2); } .sequencer-grid__corner { background: transparent; } .sequencer-lane__name { display: flex; align-items: center; gap: 0.75rem; padding: 0 0.9rem; border-radius: 1rem; background: rgba(255, 255, 255, 0.04); } .sequencer-lane__dot { width: 0.8rem; height: 0.8rem; border-radius: 999px; } .sequencer-lane__dot--kick { background: #65f2d1; } .sequencer-lane__dot--snare { background: #ffb36a; } .sequencer-lane__dot--hat { background: #87a7ff; } .sequencer-lane__dot--clap { background: #ff7c74; } .sequencer-lane__label { display: flex; flex-direction: column; gap: 0.1rem; } .sequencer-lane__label strong { font-size: 0.96rem; } .sequencer-lane__label span { color: var(--muted); font-family: "IBM Plex Mono", monospace; font-size: 0.72rem; text-transform: uppercase; letter-spacing: 0.06em; } .sequencer-step { border: 1px solid rgba(152, 214, 255, 0.14); border-radius: 0.95rem; background: linear-gradient(180deg, rgba(255, 255, 255, 0.07), rgba(255, 255, 255, 0.02)), rgba(9, 23, 37, 0.92); cursor: pointer; transition: transform 120ms ease, border-color 120ms ease, background 120ms ease; } .sequencer-step:hover, .sequencer-step:focus-visible { transform: translateY(-2px); border-color: rgba(152, 214, 255, 0.32); } .sequencer-step.is-active { border-color: rgba(101, 242, 209, 0.6); background: linear-gradient(180deg, rgba(101, 242, 209, 0.24), rgba(255, 179, 106, 0.08)), rgba(14, 41, 57, 0.95); box-shadow: inset 0 0 0 1px rgba(101, 242, 209, 0.14); } .sequencer-step.is-current { box-shadow: 0 0 0 1px rgba(255, 179, 106, 0.4), 0 0 20px rgba(255, 179, 106, 0.18); } .sequencer-step.is-accent { border-color: rgba(255, 179, 106, 0.16); } .board-row { display: grid; grid-template-columns: repeat(10, minmax(0, 1fr)); gap: 0.8rem; } .board-row--offset { grid-template-columns: repeat(9, minmax(0, 1fr)); padding-left: 2.5rem; } .board-row--wide { grid-template-columns: repeat(7, minmax(0, 1fr)); padding-right: 12rem; } .key { position: relative; min-height: 7.2rem; padding: 0.9rem; border-radius: 1.2rem; background: linear-gradient(180deg, rgba(255, 255, 255, 0.09), rgba(255, 255, 255, 0.02)), var(--panel-strong); color: var(--text); text-align: left; cursor: pointer; touch-action: none; transition: transform 140ms ease, border-color 140ms ease, box-shadow 140ms ease; } .key:hover, .key:focus-visible { transform: translateY(-3px); border-color: rgba(135, 167, 255, 0.45); } .key__letter, .key__note { display: block; } .key__shape-role, .key__shape-name { position: absolute; border-radius: 999px; font-family: "IBM Plex Mono", monospace; line-height: 1; pointer-events: none; } .key__letter { font-size: 1.45rem; font-weight: 700; } .key__note { margin-top: 0.35rem; color: var(--muted); font-family: "IBM Plex Mono", monospace; font-size: 0.95rem; } .key__shape-role { top: 0.75rem; right: 0.75rem; min-width: 1.7rem; padding: 0.25rem 0.35rem; background: rgba(255, 255, 255, 0.08); color: rgba(238, 247, 255, 0.76); font-size: 0.74rem; text-align: center; } .key__shape-name { left: 0.75rem; bottom: 0.72rem; padding: 0.22rem 0.42rem; background: rgba(101, 242, 209, 0.12); color: rgba(101, 242, 209, 0.9); font-size: 0.68rem; letter-spacing: 0.05em; text-transform: uppercase; } .key__index { position: absolute; right: 0.9rem; bottom: 0.9rem; color: rgba(238, 247, 255, 0.28); font-family: "IBM Plex Mono", monospace; font-size: 0.78rem; } .key.is-chord-tone { border-color: rgba(135, 167, 255, 0.34); box-shadow: 0 10px 28px rgba(0, 0, 0, 0.26), inset 0 0 0 1px rgba(135, 167, 255, 0.08); } .key.is-chord-root { border-color: rgba(255, 179, 106, 0.56); box-shadow: 0 14px 30px rgba(0, 0, 0, 0.3), 0 0 0 1px rgba(255, 179, 106, 0.12), 0 0 30px rgba(255, 179, 106, 0.12); } .key.is-chord-root .key__shape-role { background: rgba(255, 179, 106, 0.18); color: #ffd7b2; } .key.is-chord-tone .key__shape-role { background: rgba(135, 167, 255, 0.14); color: #ccdaff; } .key.is-active { transform: translateY(-4px) scale(1.01); border-color: rgba(101, 242, 209, 0.8); background: linear-gradient(180deg, rgba(101, 242, 209, 0.18), rgba(255, 179, 106, 0.08)), rgba(14, 38, 56, 0.96); box-shadow: 0 18px 38px rgba(0, 0, 0, 0.4), 0 0 0 1px rgba(101, 242, 209, 0.15), 0 0 38px rgba(101, 242, 209, 0.24); } .legend { grid-template-columns: repeat(3, minmax(0, 1fr)); margin-top: 1rem; animation: rise 1.1s ease-out both; } .legend__item { padding: 1rem 1.1rem; border: 1px solid rgba(152, 214, 255, 0.12); border-radius: 1.1rem; background: rgba(7, 20, 36, 0.56); } .legend__title { display: block; margin-bottom: 0.45rem; font-family: "IBM Plex Mono", monospace; font-size: 0.82rem; color: var(--accent-2); letter-spacing: 0.08em; text-transform: uppercase; } .legend p { margin: 0; color: var(--muted); line-height: 1.55; } @keyframes drift { 0%, 100% { transform: translate3d(0, 0, 0) scale(1); } 50% { transform: translate3d(1.2rem, -1rem, 0) scale(1.08); } } @keyframes rise { from { opacity: 0; transform: translateY(16px); } to { opacity: 1; transform: translateY(0); } } @media (max-width: 900px) { .controls, .legend { grid-template-columns: repeat(2, minmax(0, 1fr)); } .mapping-grid { grid-template-columns: 1fr; } .sequencer__header { align-items: start; flex-direction: column; } .sequencer__transport { justify-content: start; } .board-row--offset, .board-row--wide { padding: 0; } } @media (max-width: 700px) { .app { width: min(100% - 1rem, 48rem); padding-top: 1.2rem; } .controls, .legend { grid-template-columns: 1fr; } .board { padding: 0.9rem; gap: 0.7rem; } .board-row { grid-template-columns: repeat(5, minmax(0, 1fr)); } .board-row--offset { grid-template-columns: repeat(5, minmax(0, 1fr)); } .board-row--wide { grid-template-columns: repeat(4, minmax(0, 1fr)); } .key { min-height: 5.6rem; } }