accompy / static /style.css
jasonmdong's picture
Sync from GitHub via hub-sync
c78e8af verified
Raw
History Blame Contribute Delete
58.2 kB
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
body {
--bg: #060b17;
--text: #f4f7ff;
--panel: #0b1328;
--panel-alt: #101a33;
--border: #1d2a44;
--border-strong: #2d3d5f;
--muted: #98a3b8;
--muted-2: #667085;
--surface: #081123;
--accent: #2563ff;
--accent-2: #6aa3ff;
--success: #38d996;
--success-bg: #0d3028;
--key-next: #39ff7a;
--key-next-2: #7dff9e;
--brand-navy: #06122b;
--brand-ink: #f7faff;
}
body.light {
--bg: #f4f6fb;
--text: #07142d;
--panel: #ffffff;
--panel-alt: #edf2fb;
--border: #d8deea;
--border-strong: #c2cbda;
--muted: #626b7c;
--muted-2: #8790a0;
--surface: #f8faff;
--accent: #2563ff;
--accent-2: #4d83ff;
--success: #16945f;
--success-bg: #def7eb;
--key-next: #22e062;
--key-next-2: #5dff8c;
--brand-navy: #06122b;
--brand-ink: #07142d;
}
body {
font-family: Inter, ui-sans-serif, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
background:
linear-gradient(180deg, color-mix(in srgb, var(--bg) 92%, #10295f), var(--bg) 42%),
var(--bg);
color: var(--text);
min-height: 100vh;
}
/* ── Header ── */
header {
display: flex;
align-items: center;
gap: 1rem;
padding: .8rem 2rem;
margin: -2rem calc(50% - 50vw) 1.5rem;
border-bottom: 1px solid var(--border);
background: color-mix(in srgb, var(--panel) 82%, transparent);
box-shadow: 0 12px 34px rgba(0,0,0,.18);
}
header[hidden],
body.practice-mode #app-header,
body:has(#play-screen.active) #app-header {
display: none !important;
}
.brand-home {
border: 0;
background: transparent;
color: var(--text);
padding: 0;
font: inherit;
display: inline-flex;
align-items: center;
gap: .65rem;
font-size: 1.25rem;
font-weight: 800;
letter-spacing: -.01em;
cursor: pointer;
}
.brand-word > span { color: var(--accent); }
.brand-home:hover,
.brand-home:focus-visible { color: var(--accent); outline: none; }
.brand-mark {
width: 2.35rem;
height: 2.35rem;
color: var(--accent);
overflow: visible;
flex: 0 0 auto;
}
.brand-mark-ring {
fill: none;
stroke: currentColor;
stroke-width: 5;
stroke-linecap: square;
stroke-dasharray: 5 7;
opacity: .92;
transform-origin: 25px 38px;
transform: rotate(-18deg);
}
.brand-mark-note {
fill: var(--brand-ink);
filter: drop-shadow(0 5px 10px rgba(0,0,0,.24));
}
body:not(.light) .brand-mark-note {
fill: #f7faff;
}
.brand-mark-arrow {
fill: var(--accent);
}
.midi-badge {
display: inline-flex;
align-items: center;
gap: .45rem;
border: 1px solid var(--border-strong);
background: var(--panel);
border-radius: 999px;
padding: .35rem .75rem;
font-size: .78rem;
font-weight: 600;
color: var(--text);
white-space: nowrap;
}
.midi-badge-dot {
width: .6rem;
height: .6rem;
border-radius: 50%;
background: #888;
box-shadow: 0 0 0 0 rgba(0,0,0,0);
flex-shrink: 0;
}
.midi-badge-connected .midi-badge-dot {
background: #22c55e;
box-shadow: 0 0 6px rgba(34,197,94,.7);
}
.midi-badge-disconnected .midi-badge-dot {
background: #ef4444;
}
.midi-badge-unsupported .midi-badge-dot {
background: #888;
}
.theme-toggle {
border: 1px solid var(--border-strong);
background: var(--panel);
color: var(--text);
border-radius: 999px;
padding: .42rem .85rem;
font-size: .8rem;
cursor: pointer;
}
.top-nav-actions {
margin-left: auto;
display: flex;
align-items: center;
gap: .75rem;
}
.nav-auth-user {
align-items: center;
gap: .65rem;
color: var(--muted);
font-size: .82rem;
min-width: 0;
}
.nav-auth-user span {
max-width: min(34vw, 260px);
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.nav-logout-btn {
padding: .38rem .72rem;
border-radius: 999px;
font-size: .78rem;
}
.auth-panel {
margin: 0 0 1.75rem;
}
body.auth-mode {
height: 100vh;
overflow: hidden;
}
body.auth-mode #list-screen {
height: 100vh;
max-width: none;
box-sizing: border-box;
overflow: hidden;
}
body.auth-mode #auth-panel {
min-height: 0;
height: calc(100vh - 7rem);
margin: 0;
display: grid !important;
place-items: center;
overflow: auto;
}
.auth-card {
background: var(--panel);
border: 1px solid var(--border);
border-radius: 10px;
padding: 1rem 1.1rem;
max-width: 520px;
}
body.auth-mode .auth-card {
width: min(720px, calc(100vw - 3rem));
max-width: none;
border-radius: 14px;
padding: 1.65rem 1.8rem 1.8rem;
box-shadow: 0 24px 80px rgba(0,0,0,.26);
}
.auth-card h3 {
font-size: 1rem;
margin-bottom: .3rem;
}
body.auth-mode .auth-card h3 {
font-size: 1.35rem;
}
.auth-copy {
font-size: .82rem;
color: var(--muted);
line-height: 1.45;
}
.auth-form {
display: flex;
flex-direction: column;
gap: .75rem;
margin-top: .8rem;
}
.google-signin-btn {
width: 100%;
justify-content: center;
gap: .6rem;
border: 1px solid var(--border-strong);
background: color-mix(in srgb, var(--surface) 88%, white 12%);
color: var(--text);
}
.google-signin-btn:hover {
border-color: var(--accent);
}
.google-signin-btn span {
width: 1.35rem;
height: 1.35rem;
border-radius: 50%;
display: inline-flex;
align-items: center;
justify-content: center;
background: #fff;
color: #2563ff;
font-weight: 900;
font-size: .8rem;
}
.auth-divider {
display: flex;
align-items: center;
gap: .75rem;
color: var(--muted);
font-size: .74rem;
text-transform: uppercase;
letter-spacing: .12em;
}
.auth-divider::before,
.auth-divider::after {
content: "";
height: 1px;
background: var(--border);
flex: 1;
}
.auth-form input {
width: 100%;
border: 1px solid var(--border-strong);
background: var(--surface);
color: var(--text);
border-radius: 8px;
padding: .7rem .8rem;
font-size: .9rem;
}
body.auth-mode .auth-form input {
padding: .95rem 1rem;
font-size: 1rem;
}
.auth-actions {
display: grid;
grid-template-columns: repeat(3, minmax(0, 1fr));
gap: .65rem;
align-items: stretch;
}
.auth-actions .btn {
width: 100%;
min-height: 42px;
justify-content: center;
white-space: normal;
text-align: center;
}
.guest-signin-btn {
border-color: color-mix(in srgb, var(--accent) 45%, var(--border-strong));
color: var(--accent-2);
}
body.auth-mode .auth-actions .btn {
padding: .72rem 1rem;
font-size: .92rem;
}
@media (max-width: 620px) {
.auth-actions {
grid-template-columns: 1fr;
}
}
.auth-status {
min-height: 1.1rem;
font-size: .8rem;
color: var(--muted);
}
body.auth-mode .library-header,
body.auth-mode .score-grid-toolbar,
body.auth-mode .score-grid {
display: none;
}
.guest-banner {
align-items: center;
justify-content: space-between;
gap: 1rem;
margin: 0 0 1.25rem;
padding: .8rem .95rem;
border: 1px solid color-mix(in srgb, var(--accent) 42%, var(--border));
border-radius: 10px;
background:
linear-gradient(135deg, color-mix(in srgb, var(--accent) 12%, transparent), transparent 55%),
var(--panel);
box-shadow: 0 14px 40px rgba(0,0,0,.16);
}
.guest-banner strong {
display: block;
font-size: .9rem;
}
.guest-banner span {
display: block;
margin-top: .15rem;
color: var(--muted);
font-size: .8rem;
}
.guest-banner-actions {
display: inline-flex;
align-items: center;
gap: .55rem;
flex-shrink: 0;
}
@media (max-width: 720px) {
.guest-banner {
align-items: flex-start;
flex-direction: column;
}
}
.modal-section h4 {
font-size: .88rem;
color: var(--text);
margin-bottom: .25rem;
}
.modal-copy {
font-size: .8rem;
color: var(--muted);
line-height: 1.45;
}
.upload-divider {
height: 1px;
background: var(--border);
margin: 1rem 0;
}
.upload-form {
display: flex;
flex-direction: column;
gap: .75rem;
}
.upload-form input[type="text"],
.upload-form input[type="file"] {
width: 100%;
border: 1px solid var(--border-strong);
background: var(--surface);
color: var(--text);
border-radius: 8px;
padding: .7rem .8rem;
font-size: .9rem;
}
.file-input-hidden {
position: absolute;
width: 1px;
height: 1px;
opacity: 0;
pointer-events: none;
}
.file-dropzone {
border: 1px dashed color-mix(in srgb, var(--border-strong) 85%, var(--accent));
background: color-mix(in srgb, var(--surface) 88%, var(--accent) 12%);
border-radius: 8px;
padding: 1rem;
cursor: pointer;
transition: border-color .15s, background .15s, box-shadow .15s;
}
.file-dropzone:hover,
.file-dropzone:focus-visible,
.file-dropzone.drag-over {
border-color: var(--accent);
background: color-mix(in srgb, var(--surface) 76%, var(--accent) 24%);
box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 18%, transparent);
outline: none;
}
.file-dropzone-title {
color: var(--text);
font-weight: 800;
font-size: .95rem;
}
.file-dropzone-copy,
.file-dropzone-selection {
margin-top: .25rem;
color: var(--muted);
font-size: .78rem;
line-height: 1.35;
}
.file-dropzone-selection {
color: var(--text);
font-weight: 650;
}
.upload-actions {
display: flex;
align-items: center;
gap: .75rem;
}
.import-status {
font-size: .8rem;
color: var(--muted);
}
/* ── Screens ── */
.screen { display: none; padding: 2rem; max-width: 960px; margin: 0 auto; }
.screen.active { display: block; }
#play-screen { max-width: min(1800px, calc(100% - 2rem)); }
@media (min-width: 1400px) {
#play-screen { padding: 2rem 3rem; }
}
/* ── Library header ── */
.library-header {
display: flex;
align-items: flex-end;
justify-content: space-between;
gap: 1.25rem;
margin: .2rem 0 1.35rem;
}
.library-header h2 {
font-size: clamp(2rem, 4vw, 3.1rem);
line-height: .95;
letter-spacing: -.045em;
font-weight: 880;
}
.library-header p {
color: var(--muted);
font-size: .92rem;
line-height: 1.45;
margin-top: .7rem;
max-width: 620px;
}
@media (max-width: 720px) {
header {
padding: .75rem 1rem;
}
.brand-home {
font-size: 1.05rem;
}
.brand-mark {
width: 2rem;
height: 2rem;
}
.library-header {
align-items: flex-start;
flex-direction: column;
}
.top-nav-actions {
gap: .5rem;
}
.nav-auth-user span {
max-width: 34vw;
}
}
/* ── Score grid ── */
.score-grid {
--score-grid-columns: 3;
display: grid;
grid-template-columns: repeat(var(--score-grid-columns), minmax(0, 1fr));
gap: 1rem;
margin-top: 1.5rem;
}
.score-grid-empty {
grid-column: 1 / -1;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
gap: .85rem;
padding: 4rem 1.5rem;
text-align: center;
color: var(--muted);
border: 2px dashed var(--border);
border-radius: 14px;
background: color-mix(in srgb, var(--panel) 60%, transparent);
}
.score-grid-empty h3 {
margin: 0;
color: var(--text);
font-size: 1.15rem;
}
.score-grid-empty p {
margin: 0;
font-size: .95rem;
}
.score-grid-toolbar {
display: flex;
align-items: center;
justify-content: flex-end;
gap: .6rem;
margin-top: .75rem;
}
.score-grid-toolbar label {
font-size: .82rem;
color: var(--muted);
}
.score-card {
position: relative;
background: var(--panel);
border: 1px solid var(--border);
border-radius: 10px;
padding: 1rem;
display: flex;
flex-direction: column;
align-items: stretch;
gap: .9rem;
transition: border-color .15s, transform .15s;
cursor: pointer;
}
.score-card:hover { border-color: var(--accent); transform: translateY(-2px); }
.score-card h3 { font-size: 1.05rem; margin-bottom: .4rem; }
.score-card small { color: var(--muted); font-size: .8rem; }
.score-card-meta {
min-width: 0;
}
.guest-demo-card {
min-height: 300px;
justify-content: space-between;
}
.guest-demo-card.primary {
border-color: color-mix(in srgb, var(--accent) 58%, var(--border));
box-shadow: 0 18px 50px rgba(37, 99, 255, .16);
}
.guest-demo-preview {
min-height: 128px;
border: 1px solid var(--border);
border-radius: 8px;
background:
radial-gradient(circle at 82% 20%, color-mix(in srgb, var(--accent) 35%, transparent), transparent 30%),
linear-gradient(135deg, color-mix(in srgb, var(--surface) 92%, white 8%), var(--panel-alt));
display: flex;
flex-direction: column;
justify-content: space-between;
padding: .9rem;
overflow: hidden;
}
.guest-demo-preview span,
.guest-demo-kicker {
color: var(--accent-2);
font-size: .72rem;
font-weight: 800;
text-transform: uppercase;
letter-spacing: .12em;
}
.guest-demo-preview strong {
color: var(--text);
font-size: clamp(1.7rem, 4vw, 2.4rem);
line-height: .9;
letter-spacing: -.04em;
}
.guest-card-action {
justify-content: center;
}
.score-preview {
position: relative;
aspect-ratio: 960 / 1240;
overflow: hidden;
border-radius: 8px;
background: var(--panel-alt);
border: 1px solid var(--border);
--preview-scale: 0.22;
}
.score-preview-frame {
display: block;
width: 960px;
height: 1240px;
border: none;
background: #fff;
transform: scale(var(--preview-scale));
transform-origin: top left;
pointer-events: none;
}
.score-preview.empty {
display: flex;
align-items: center;
justify-content: center;
}
.score-preview-empty {
color: var(--muted-2);
font-size: .85rem;
}
.delete-btn {
position: absolute;
top: .55rem;
right: .55rem;
z-index: 2;
flex-shrink: 0; background: color-mix(in srgb, var(--bg) 86%, transparent); border: none; color: var(--muted);
font-size: 1rem; cursor: pointer; padding: .25rem .4rem; border-radius: 4px;
transition: color .15s, background .15s;
}
.delete-btn:hover { color: #e05c5c; background: #2a1a1a; }
@media (max-width: 1100px) {
.score-grid {
grid-template-columns: repeat(min(var(--score-grid-columns), 3), minmax(0, 1fr));
}
}
@media (max-width: 760px) {
.score-grid {
grid-template-columns: repeat(min(var(--score-grid-columns), 2), minmax(0, 1fr));
}
}
@media (max-width: 520px) {
.score-grid {
grid-template-columns: 1fr;
}
.score-grid-toolbar {
justify-content: flex-start;
}
}
/* ── Play screen ── */
#play-screen h2 { font-size: 1.1rem; color: #aaa; margin-bottom: 1.5rem; }
.play-shell {
display: grid;
grid-template-columns: minmax(220px, 280px) minmax(0, 1fr);
gap: 1.5rem;
align-items: start;
}
.play-shell[data-sidebar="collapsed"] {
grid-template-columns: 58px minmax(0, 1fr);
}
.play-content {
min-width: 0;
}
.play-sidebar {
position: sticky;
top: 1.5rem;
display: flex;
flex-direction: column;
background: var(--panel);
border-radius: 12px;
border: 1px solid var(--border);
padding: 1rem;
max-height: calc(100vh - 3rem);
overflow: hidden;
transition: padding .14s ease, width .14s ease;
}
.play-sidebar-footer {
margin-top: auto;
padding-top: .75rem;
border-top: 1px solid var(--border);
display: flex;
align-items: center;
justify-content: space-between;
gap: .65rem;
}
.sidebar-brand-home {
min-width: 0;
appearance: none;
border: 0;
box-shadow: none !important;
background: transparent;
color: var(--text);
padding: 0;
display: inline-flex;
align-items: center;
gap: .5rem;
font: inherit;
font-size: .92rem;
font-weight: 850;
letter-spacing: -.01em;
cursor: pointer;
}
.sidebar-brand-dot {
width: 1.55rem;
height: 1.55rem;
border-radius: 50%;
background: linear-gradient(135deg, var(--brand-navy), color-mix(in srgb, var(--accent) 55%, var(--brand-navy)));
color: #fff;
display: inline-flex;
align-items: center;
justify-content: center;
font-size: .78rem;
font-weight: 900;
line-height: 1;
box-shadow: 0 5px 14px color-mix(in srgb, var(--accent) 22%, transparent);
flex: 0 0 auto;
}
.sidebar-brand-word {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.sidebar-brand-word > span {
color: var(--accent);
}
.sidebar-brand-home:hover,
.sidebar-brand-home:focus-visible {
color: var(--accent);
outline: none;
}
.sidebar-brand-home:focus-visible .sidebar-brand-dot {
box-shadow:
0 0 0 3px color-mix(in srgb, var(--accent) 22%, transparent),
0 5px 14px color-mix(in srgb, var(--accent) 22%, transparent);
}
.sidebar-theme-toggle {
flex: 0 0 auto;
padding: .34rem .65rem;
font-size: .72rem;
}
.sidebar-footer-actions {
position: relative;
display: inline-flex;
align-items: center;
gap: .4rem;
flex: 0 0 auto;
}
.sidebar-account-menu {
position: relative;
flex: 0 0 auto;
}
.sidebar-account-btn {
width: 30px;
height: 30px;
border-radius: 999px;
border: 1px solid var(--border-strong);
background: color-mix(in srgb, var(--surface) 82%, var(--accent) 18%);
color: var(--text);
display: inline-flex;
align-items: center;
justify-content: center;
font-size: .72rem;
font-weight: 850;
cursor: pointer;
}
.sidebar-account-btn:hover,
.sidebar-account-btn:focus-visible {
border-color: var(--accent);
outline: none;
}
.sidebar-account-popover {
position: absolute;
right: 0;
bottom: calc(100% + .55rem);
z-index: 20;
width: 220px;
padding: .85rem;
border: 1px solid var(--border);
border-radius: 10px;
background: var(--panel);
box-shadow: 0 18px 52px rgba(0,0,0,.35);
}
.sidebar-account-popover::after {
content: "";
position: absolute;
right: 11px;
bottom: -6px;
width: 10px;
height: 10px;
background: var(--panel);
border-right: 1px solid var(--border);
border-bottom: 1px solid var(--border);
transform: rotate(45deg);
}
.sidebar-account-eyebrow,
.sidebar-account-popover strong,
.sidebar-account-popover span {
display: block;
}
.sidebar-account-eyebrow {
color: var(--accent-2);
font-size: .66rem;
font-weight: 850;
text-transform: uppercase;
letter-spacing: .08em;
margin-bottom: .35rem;
}
.sidebar-account-popover strong {
color: var(--text);
font-size: .86rem;
line-height: 1.25;
word-break: break-word;
}
.sidebar-account-popover #sidebar-account-detail {
margin-top: .25rem;
color: var(--muted);
font-size: .74rem;
line-height: 1.35;
}
.sidebar-account-popover .btn {
width: 100%;
justify-content: center;
margin-top: .75rem;
padding: .42rem .6rem;
font-size: .74rem;
}
.play-sidebar-header {
display: flex;
align-items: flex-start;
justify-content: space-between;
gap: .6rem;
margin-bottom: .9rem;
}
.play-sidebar-copy {
min-width: 0;
flex: 1;
}
.play-sidebar-header h3 {
font-size: .92rem;
color: var(--text);
margin-bottom: .3rem;
}
.play-sidebar-header p {
font-size: .76rem;
color: var(--muted);
line-height: 1.45;
}
.play-sidebar-toggle {
flex-shrink: 0;
width: 32px;
height: 32px;
border-radius: 8px;
border: 1px solid var(--border-strong);
background: var(--surface);
color: var(--text);
cursor: pointer;
font-size: .95rem;
line-height: 1;
transition: border-color .12s ease, color .12s ease, background .12s ease;
}
.play-sidebar-toggle:hover {
border-color: var(--accent);
color: var(--accent);
}
.play-piece-list {
display: flex;
flex-direction: column;
gap: .45rem;
max-height: calc(100vh - 8rem);
overflow: auto;
padding-right: .2rem;
}
.play-guest-banner {
margin-top: .75rem;
padding: .75rem;
border: 1px solid color-mix(in srgb, var(--accent) 35%, var(--border));
border-radius: 10px;
background: color-mix(in srgb, var(--accent) 8%, var(--surface));
}
.play-guest-banner strong,
.play-guest-banner span {
display: block;
}
.play-guest-banner strong {
font-size: .78rem;
}
.play-guest-banner span {
margin-top: .2rem;
color: var(--muted);
font-size: .72rem;
line-height: 1.35;
}
.play-guest-banner div {
display: grid;
grid-template-columns: 1fr;
gap: .45rem;
margin-top: .65rem;
}
.play-guest-banner .btn {
width: 100%;
justify-content: center;
padding: .42rem .55rem;
font-size: .72rem;
}
.play-piece-item {
width: 100%;
text-align: left;
border: 1px solid var(--border);
background: var(--surface);
color: var(--text);
border-radius: 10px;
padding: .7rem .8rem;
cursor: pointer;
transition: border-color .12s ease, background .12s ease, transform .12s ease;
}
.play-piece-item:hover {
border-color: var(--accent);
background: color-mix(in srgb, var(--accent) 10%, var(--surface));
}
.play-piece-item.active {
border-color: var(--accent);
background: color-mix(in srgb, var(--accent) 14%, var(--surface));
box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--accent) 18%, transparent);
}
.play-piece-item:disabled {
cursor: default;
opacity: 1;
}
.play-piece-title {
display: block;
font-size: .86rem;
font-weight: 700;
color: var(--text);
}
.play-piece-slug {
display: block;
margin-top: .2rem;
font-size: .72rem;
color: var(--muted);
word-break: break-word;
}
.play-shell[data-sidebar="collapsed"] .play-sidebar {
padding: .75rem .45rem;
}
.play-shell[data-sidebar="collapsed"] .play-sidebar-header {
margin-bottom: 0;
justify-content: center;
}
.play-shell[data-sidebar="collapsed"] .play-sidebar-copy,
.play-shell[data-sidebar="collapsed"] .play-piece-list,
.play-shell[data-sidebar="collapsed"] .play-guest-banner,
.play-shell[data-sidebar="collapsed"] .sidebar-brand-word,
.play-shell[data-sidebar="collapsed"] .sidebar-footer-actions,
.play-shell[data-sidebar="collapsed"] .sidebar-theme-toggle {
display: none;
}
.play-shell[data-sidebar="collapsed"] .play-sidebar-footer {
justify-content: center;
border-top: 0;
padding-top: .75rem;
}
.play-header {
display: flex;
align-items: flex-start;
justify-content: space-between;
gap: 1.5rem;
margin-bottom: 1.5rem;
}
.play-bottom {
display: grid;
grid-template-columns: repeat(2, minmax(0, 1fr));
gap: 1.5rem;
margin-top: 1.5rem;
align-items: stretch;
}
.controls-panel {
display: flex;
flex-direction: column;
gap: 1rem;
min-width: 0;
}
.controls-top {
width: min(430px, 100%);
margin-left: auto;
}
/* BPM + controls */
.controls { background: var(--panel); border-radius: 10px; padding: 1.25rem; }
.controls label { font-size: .85rem; color: var(--muted); display: block; margin-bottom: .4rem; }
.tempo-row {
display: flex;
align-items: center;
justify-content: space-between;
gap: 1rem;
}
.bpm-row { display: flex; align-items: center; gap: .75rem; }
.tempo-actions {
display: flex;
align-items: center;
gap: .6rem;
flex-shrink: 0;
}
.latency-row {
display: grid;
grid-template-columns: auto 1fr auto;
align-items: center;
gap: .75rem;
margin-top: .85rem;
}
.latency-row label {
margin: 0;
white-space: nowrap;
}
.latency-row input[type="range"] {
width: 100%;
}
.latency-row span {
font-size: .82rem;
color: var(--muted);
min-width: 58px;
text-align: right;
}
.bpm-row input {
width: 90px; padding: .45rem .7rem; border-radius: 6px;
border: 1px solid var(--border-strong); background: var(--surface); color: var(--text);
font-size: 1rem;
}
.btn {
padding: .5rem 1.2rem; border-radius: 6px; border: none;
font-size: .9rem; font-weight: 600; cursor: pointer; transition: opacity .15s;
}
.btn:hover { opacity: .85; }
.btn-primary { background: var(--accent); color: #fff; }
.btn-danger { background: #e05c5c; color: #fff; }
.btn-ghost { background: var(--border); color: var(--text); }
/* Status panel */
.status-panel {
background: var(--panel);
border-radius: 10px;
padding: 1.25rem;
height: 100%;
}
.status-row { display: flex; justify-content: space-between; margin-bottom: .6rem; font-size: .85rem; color: var(--muted); }
.status-val { color: var(--text); font-weight: 600; }
#next-note-display {
font-size: 3rem; font-weight: 700; text-align: center;
color: var(--accent); margin-top: .5rem; letter-spacing: .05em;
}
/* ── Input mode ── */
.input-mode-section {
background: var(--panel); border-radius: 10px; padding: 1.25rem; margin-top: 1rem; margin-bottom: 1.5rem;
}
.input-mode-section h4 {
font-size: .85rem;
color: var(--muted);
margin-bottom: .75rem;
}
.input-mode-tabs { display: flex; gap: .5rem; margin-bottom: .75rem; }
.mode-tab {
padding: .4rem 1rem; border-radius: 6px; border: 1px solid var(--border-strong);
background: var(--surface); color: var(--muted); font-size: .85rem; cursor: pointer; transition: all .15s;
display: inline-flex;
align-items: center;
justify-content: center;
gap: .35rem;
}
.mode-tab.active { background: var(--accent); border-color: var(--accent); color: #fff; font-weight: 600; }
.beta-badge {
border: 1px solid color-mix(in srgb, currentColor 42%, transparent);
border-radius: 999px;
padding: .08rem .32rem;
font-size: .58rem;
line-height: 1.1;
font-weight: 800;
text-transform: uppercase;
letter-spacing: .04em;
opacity: .82;
}
.mic-row { display: flex; align-items: center; gap: .6rem; }
.mic-status-dot {
width: 10px; height: 10px; border-radius: 50%; background: #333; flex-shrink: 0;
transition: background .2s;
}
.mic-status-dot.active { background: #5aaa60; box-shadow: 0 0 6px #5aaa60; }
.mic-status-dot.hearing { background: #7c6af7; box-shadow: 0 0 8px #7c6af7; }
.level-meter-wrap { width: 100%; }
.level-meter-track {
position: relative; width: 100%; height: 28px;
background: var(--surface); border-radius: 6px; overflow: visible;
border: 1px solid var(--border);
}
.level-meter-fill {
position: absolute; left: 0; top: 0; height: 100%;
width: 0%; border-radius: 6px;
background: linear-gradient(to right, #2a7a35, #5aaa60);
transition: width 0.04s linear;
}
.level-meter-fill.active {
background: linear-gradient(to right, #5040b0, #7c6af7);
}
.level-meter-peak {
position: absolute; top: 4px; width: 3px; height: 20px;
background: #fff; border-radius: 2px; opacity: 0.7;
transition: left 0.05s;
}
.level-meter-gate {
position: absolute; top: 0; width: 2px; height: 100%;
background: #e05c5c;
}
.level-gate-label {
position: absolute; top: 50%; transform: translateY(-50%);
font-size: 10px; color: #e05c5c; white-space: nowrap; pointer-events: none;
}
/* Keyboard viz */
.play-main {
display: grid;
grid-template-columns: 1fr;
gap: 1.5rem;
margin-bottom: 1.5rem;
align-items: start;
}
@media (min-width: 1500px) {
.play-main {
grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
}
.play-main .keyboard-section,
.play-main .sheet-section {
margin-bottom: 0;
}
}
.keyboard-section { background: var(--panel); border-radius: 10px; padding: 1.25rem; margin-bottom: 1.5rem; }
.mini-keyboard-panel {
display: block;
}
.keyboard-heading {
display: flex;
align-items: center;
justify-content: space-between;
gap: .55rem;
margin-bottom: .75rem;
}
.keyboard-heading-main {
display: flex;
align-items: center;
gap: .55rem;
}
.keyboard-section h4 { font-size: .85rem; color: var(--muted); margin-bottom: 0; }
.keyboard-view-toggle {
display: inline-flex;
align-items: center;
gap: .35rem;
padding: .2rem;
border-radius: 999px;
background: var(--surface);
border: 1px solid var(--border);
}
.keyboard-view-btn {
border: none;
background: transparent;
color: var(--muted);
font-size: .74rem;
font-weight: 700;
padding: .32rem .8rem;
border-radius: 999px;
cursor: pointer;
transition: background .12s ease, color .12s ease;
}
.keyboard-view-btn.active {
background: var(--accent);
color: #fff;
}
.keyboard-view-btn:hover:not(.active) {
background: color-mix(in srgb, var(--accent) 12%, transparent);
color: var(--text);
}
.help-tip {
position: relative;
display: inline-flex;
align-items: center;
justify-content: center;
width: 20px;
height: 20px;
border-radius: 50%;
border: 1px solid var(--border-strong);
background: var(--surface);
color: var(--muted);
font-size: .72rem;
font-weight: 700;
cursor: help;
}
.help-tip-popup {
position: absolute;
left: 50%;
top: calc(100% + 10px);
transform: translateX(-50%);
width: max-content;
max-width: 260px;
padding: .6rem .75rem;
border-radius: 8px;
background: var(--panel-alt);
border: 1px solid var(--border);
color: var(--text);
font-size: .76rem;
line-height: 1.45;
box-shadow: 0 10px 24px rgba(0,0,0,.25);
opacity: 0;
pointer-events: none;
transition: opacity .12s ease;
z-index: 20;
white-space: normal;
}
.help-tip:hover .help-tip-popup,
.help-tip:focus .help-tip-popup,
.help-tip:focus-within .help-tip-popup {
opacity: 1;
}
.piano-stage {
border: 1px solid var(--border);
border-radius: 12px;
background: linear-gradient(to bottom, color-mix(in srgb, var(--panel-alt) 60%, transparent), var(--panel));
overflow: hidden;
}
.note-highway {
position: relative;
display: grid;
grid-template-columns: repeat(12, minmax(0, 1fr));
gap: .2rem;
height: 210px;
padding: .65rem .65rem 0;
background: linear-gradient(to bottom, color-mix(in srgb, var(--panel-alt) 86%, transparent), color-mix(in srgb, var(--surface) 78%, transparent));
border-bottom: 1px solid var(--border);
}
.note-lane {
position: relative;
border-left: 1px solid color-mix(in srgb, var(--border) 70%, transparent);
border-right: 1px solid color-mix(in srgb, var(--border) 70%, transparent);
background: linear-gradient(to bottom, transparent, color-mix(in srgb, var(--surface) 35%, transparent));
}
.note-lane.black {
background: linear-gradient(to bottom, color-mix(in srgb, var(--panel-alt) 92%, transparent), color-mix(in srgb, var(--panel-alt) 65%, transparent));
}
.note-lane-label {
position: absolute;
top: .35rem;
left: 50%;
transform: translateX(-50%);
font-size: .68rem;
font-weight: 700;
color: var(--muted);
pointer-events: none;
white-space: nowrap;
}
.note-hit-line {
position: absolute;
left: 6px;
right: 6px;
bottom: 6px;
height: 4px;
border-radius: 99px;
background: color-mix(in srgb, var(--accent) 68%, white);
box-shadow: 0 0 10px color-mix(in srgb, var(--accent) 32%, transparent);
}
.note-bar {
position: absolute;
left: 8px;
right: 8px;
border-radius: 6px;
background: linear-gradient(to bottom, color-mix(in srgb, var(--accent) 88%, white), var(--accent));
border: 1px solid color-mix(in srgb, var(--accent) 52%, white);
box-shadow: 0 6px 14px color-mix(in srgb, var(--accent) 28%, transparent);
}
.note-bar.current {
background: linear-gradient(to bottom, color-mix(in srgb, var(--success) 90%, white), var(--success));
border-color: color-mix(in srgb, var(--success) 55%, white);
box-shadow: 0 6px 16px color-mix(in srgb, var(--success) 30%, transparent);
}
.kb-layout {
padding: 0 .65rem .65rem;
}
.kb-layout.hidden,
.reference-keyboard-panel.hidden,
.mini-keyboard-panel.hidden {
display: none;
}
.keyboard-section[data-layout-mode="full"] .mini-keyboard-panel {
display: none !important;
}
.keyboard-section[data-layout-mode="mini"] .reference-keyboard-panel {
display: none !important;
}
.kb-row {
display: grid;
grid-template-columns: repeat(7, minmax(0, 1fr));
gap: .3rem;
align-items: end;
}
.kb-key-wrap {
position: relative;
min-width: 0;
padding-top: 0;
}
.kb-key {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
width: 100%;
height: 120px;
border-radius: 0 0 10px 10px;
background: linear-gradient(to bottom, #fffefb, #ebe6d9);
border: 1px solid color-mix(in srgb, var(--border-strong) 90%, #fff);
font-size: .75rem;
line-height: 1.3;
transition: background .1s, border-color .1s;
user-select: none;
padding-top: 1.8rem;
color: #1b1b20;
cursor: pointer;
}
.kb-key-white {
height: 120px;
border-radius: 0 0 10px 10px;
background: linear-gradient(to bottom, #fffefb, #ebe6d9);
border: 1px solid color-mix(in srgb, var(--border-strong) 90%, #fff);
color: #1b1b20;
}
.kb-key .key-char { font-weight: 700; font-size: .9rem; }
.kb-key .note-name { color: #6f6b62; font-size: .65rem; }
.kb-key-black {
position: absolute;
top: 0;
right: -22%;
width: 58%;
height: 78px;
border-radius: 0 0 8px 8px;
background: linear-gradient(to bottom, #343642, #0f1015);
border: 1px solid #0a0b10;
color: #fff;
padding-top: 1rem;
z-index: 3;
}
.kb-key-black .note-name { color: #b6bbc8; }
.kb-key-black.active { background: linear-gradient(to bottom, color-mix(in srgb, var(--accent) 70%, #fff), var(--accent)); border-color: var(--accent-2); }
.kb-key-black.next { background: linear-gradient(to bottom, var(--key-next-2), var(--key-next)); border-color: var(--key-next); box-shadow: 0 0 14px color-mix(in srgb, var(--key-next) 65%, transparent), 0 0 28px color-mix(in srgb, var(--key-next) 35%, transparent); color: #052a10; }
.kb-key-white.active { background: linear-gradient(to bottom, color-mix(in srgb, var(--accent) 28%, white), color-mix(in srgb, var(--accent) 18%, #ebe6d9)); border-color: var(--accent-2); }
.kb-key-white.next { background: linear-gradient(to bottom, var(--key-next-2), var(--key-next)); border-color: var(--key-next); box-shadow: 0 0 14px color-mix(in srgb, var(--key-next) 65%, transparent), 0 0 28px color-mix(in srgb, var(--key-next) 35%, transparent); color: #052a10; }
.reference-keyboard-panel {
margin-top: 0;
padding-top: 0;
border-top: 0;
}
.full-note-highway {
position: relative;
height: 210px;
margin-bottom: .7rem;
border-radius: 10px;
overflow: hidden;
background:
linear-gradient(to bottom, color-mix(in srgb, var(--panel-alt) 92%, transparent), color-mix(in srgb, var(--surface) 80%, transparent)),
repeating-linear-gradient(
to right,
color-mix(in srgb, var(--border) 42%, transparent) 0,
color-mix(in srgb, var(--border) 42%, transparent) 1px,
transparent 1px,
transparent calc(100% / 52)
);
border: 1px solid var(--border);
}
.full-note-hit-line {
position: absolute;
left: 10px;
right: 10px;
bottom: 8px;
height: 4px;
border-radius: 99px;
background: color-mix(in srgb, var(--accent) 68%, white);
box-shadow: 0 0 10px color-mix(in srgb, var(--accent) 32%, transparent);
}
.full-note-bar {
position: absolute;
border-radius: 6px;
background: linear-gradient(to bottom, color-mix(in srgb, var(--accent) 88%, white), var(--accent));
border: 1px solid color-mix(in srgb, var(--accent) 52%, white);
box-shadow: 0 6px 14px color-mix(in srgb, var(--accent) 28%, transparent);
}
.full-note-bar.current {
background: linear-gradient(to bottom, color-mix(in srgb, var(--success) 90%, white), var(--success));
border-color: color-mix(in srgb, var(--success) 55%, white);
box-shadow: 0 6px 16px color-mix(in srgb, var(--success) 30%, transparent);
}
.reference-keyboard-shell {
overflow: hidden;
padding: .25rem 0 .15rem;
}
.reference-keyboard {
--ref-white-width: calc(100% / 52);
--ref-black-width: calc(var(--ref-white-width) * 0.62);
--ref-black-offset: calc(var(--ref-black-width) / 2);
width: 100%;
min-width: 0;
height: 174px;
position: relative;
border-radius: 12px;
background: linear-gradient(to bottom, color-mix(in srgb, var(--surface) 92%, #fff), color-mix(in srgb, var(--surface) 88%, #000));
border: 1px solid var(--border-strong);
box-shadow: inset 0 1px 0 rgba(255,255,255,.03), 0 10px 24px rgba(0,0,0,.08);
}
.reference-whites {
position: absolute;
inset: 0;
display: flex;
align-items: stretch;
}
.reference-blacks {
position: absolute;
inset: 0;
pointer-events: none;
}
.ref-key {
box-sizing: border-box;
user-select: none;
cursor: pointer;
transition: background .12s ease, border-color .12s ease, box-shadow .12s ease, transform .12s ease;
}
.ref-key-black { pointer-events: auto; }
.ref-key-note {
display: block;
white-space: nowrap;
letter-spacing: -.01em;
}
.ref-key-white {
width: var(--ref-white-width);
min-width: var(--ref-white-width);
height: 100%;
border-right: 1px solid color-mix(in srgb, var(--border-strong) 88%, #fff);
border-bottom-left-radius: 8px;
border-bottom-right-radius: 8px;
background: linear-gradient(to bottom, #fffefb, #e7e1d4);
color: #20232b;
display: flex;
align-items: flex-end;
justify-content: center;
padding: 0 1px .55rem;
font-size: .46rem;
text-align: center;
overflow: hidden;
}
.ref-key-white .ref-key-note {
color: #656458;
transform: scale(.96);
transform-origin: center bottom;
}
.ref-key-black {
position: absolute;
top: 0;
width: var(--ref-black-width);
height: 108px;
border-radius: 0 0 6px 6px;
background: linear-gradient(to bottom, #383b46, #11131a);
border: 1px solid #090a0f;
color: #f4f6fb;
display: flex;
align-items: flex-end;
justify-content: center;
padding: 0 0 .42rem;
font-size: .38rem;
text-align: center;
z-index: 4;
box-shadow: 0 4px 12px rgba(0,0,0,.38);
overflow: hidden;
}
.ref-key-black .ref-key-note {
color: #c6cad7;
transform: scale(.96);
transform-origin: center bottom;
}
.ref-key-white.active {
background: linear-gradient(to bottom, color-mix(in srgb, var(--accent) 28%, white), color-mix(in srgb, var(--accent) 18%, #ebe6d9));
border-color: var(--accent-2);
box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--accent-2) 35%, transparent);
}
.ref-key-white.next {
background: linear-gradient(to bottom, var(--key-next-2), var(--key-next));
border-color: var(--key-next);
box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--key-next) 50%, transparent),
0 0 14px color-mix(in srgb, var(--key-next) 65%, transparent),
0 0 28px color-mix(in srgb, var(--key-next) 35%, transparent);
color: #052a10;
}
.ref-key-black.active {
background: linear-gradient(to bottom, color-mix(in srgb, var(--accent) 70%, #fff), var(--accent));
border-color: var(--accent-2);
box-shadow: 0 6px 14px color-mix(in srgb, var(--accent) 26%, transparent);
}
.ref-key-black.next {
background: linear-gradient(to bottom, var(--key-next-2), var(--key-next));
border-color: var(--key-next);
box-shadow: 0 0 14px color-mix(in srgb, var(--key-next) 65%, transparent),
0 0 28px color-mix(in srgb, var(--key-next) 40%, transparent);
color: #052a10;
}
/* Part picker */
.part-picker {
background: var(--panel);
border-radius: 10px;
padding: 1.25rem;
margin-bottom: 0;
height: 100%;
}
.part-picker h4 { font-size: .85rem; color: var(--muted); margin-bottom: .75rem; }
.part-buttons { display: flex; flex-direction: column; gap: .5rem; }
.part-row { display: flex; align-items: center; gap: .5rem; }
.part-btn {
padding: .45rem 1rem; border-radius: 6px; border: 1px solid var(--border-strong);
background: var(--surface); color: var(--muted); font-size: .85rem; cursor: pointer;
transition: all .15s;
}
.part-btn:hover { border-color: var(--accent); color: var(--text); }
.part-btn.selected { background: var(--accent); border-color: var(--accent); color: #fff; font-weight: 600; }
.instr-select {
padding: .35rem .6rem; border-radius: 6px; border: 1px solid var(--border-strong);
background: var(--surface); color: var(--muted); font-size: .8rem; cursor: pointer;
}
.instr-select:focus { outline: none; border-color: var(--accent); }
/* Progress bar */
.progress-bar { background: var(--border); border-radius: 99px; height: 6px; margin-bottom: 1.5rem; overflow: hidden; }
.progress-fill { height: 100%; background: var(--accent); border-radius: 99px; transition: width .3s; }
/* Sheet music */
.sheet-section { background: var(--panel); border-radius: 10px; overflow: hidden; }
.sheet-header {
display: flex;
align-items: center;
justify-content: space-between;
gap: .75rem;
padding: .55rem 1rem .55rem 1.25rem;
border-bottom: 1px solid var(--border);
}
.sheet-title-row {
display: flex;
align-items: center;
gap: .65rem;
}
.sheet-section h4 { font-size: .85rem; color: var(--muted); padding: 0; border: none; }
.sheet-status-badge {
display: inline-flex;
align-items: center;
border: 1px solid var(--border-strong);
border-radius: 999px;
padding: .22rem .55rem;
font-size: .72rem;
color: var(--muted);
background: color-mix(in srgb, var(--surface) 88%, transparent);
white-space: nowrap;
}
.sheet-status-badge[data-state="ok"] {
color: var(--text);
border-color: color-mix(in srgb, var(--accent) 35%, var(--border-strong));
}
.sheet-status-badge[data-state="warning"] {
color: #f0c35a;
border-color: rgba(240, 195, 90, .35);
background: rgba(184, 128, 0, .12);
}
.sheet-toolbar {
display: flex;
align-items: center;
gap: .3rem;
flex-wrap: wrap;
justify-content: flex-end;
}
.sheet-fingering-progress {
padding: .75rem 1.25rem .2rem;
border-bottom: 1px solid color-mix(in srgb, var(--border) 65%, transparent);
background: color-mix(in srgb, var(--panel) 92%, var(--surface));
}
.sheet-fingering-progress-meta {
display: flex;
align-items: center;
justify-content: space-between;
gap: .75rem;
margin-bottom: .45rem;
font-size: .78rem;
color: var(--muted);
}
.sheet-fingering-progress-bar {
height: 8px;
border-radius: 999px;
background: color-mix(in srgb, var(--border) 78%, transparent);
overflow: hidden;
}
.sheet-fingering-progress-fill {
width: 0%;
height: 100%;
border-radius: 999px;
background: linear-gradient(90deg, color-mix(in srgb, var(--accent) 82%, white), var(--accent));
box-shadow: 0 0 14px color-mix(in srgb, var(--accent) 28%, transparent);
transition: width .28s cubic-bezier(.22, 1, .36, 1);
}
.sheet-action-btn {
background: var(--panel-alt);
color: var(--text);
border: 1px solid var(--border-strong);
border-radius: 999px;
padding: .32rem .7rem;
font-size: .76rem;
cursor: pointer;
line-height: 1;
white-space: nowrap;
}
.sheet-action-btn:hover:not(:disabled) {
border-color: var(--accent);
color: var(--accent);
}
.sheet-action-btn:disabled {
opacity: .5;
cursor: default;
}
.sheet-tool-btn {
background: var(--surface);
color: var(--text);
border: 1px solid var(--border-strong);
border-radius: 6px;
padding: .25rem .55rem;
font-size: .85rem;
cursor: pointer;
line-height: 1;
min-width: 28px;
}
.sheet-tool-btn:hover { border-color: var(--accent); color: var(--accent); }
.sheet-zoom-label {
font-size: .78rem;
color: var(--muted);
min-width: 3.1rem;
text-align: center;
font-variant-numeric: tabular-nums;
}
.sheet-viewer {
position: relative;
width: 100%;
height: 500px;
overflow: auto;
scrollbar-gutter: stable both-edges;
background: var(--panel-alt);
}
.sheet-content-wrap {
transform-origin: top left;
transition: transform .18s ease;
width: 100%;
padding-right: .65rem;
padding-bottom: .65rem;
}
#sheet-frame { width: 100%; height: 500px; border: none; display: block; background: #fff; }
.sheet-placeholder { padding: 2rem; text-align: center; color: var(--muted-2); font-size: .9rem; }
.sheet-musicxml-fallback {
display: none;
min-height: 500px;
padding: 1rem;
background: #181824;
color: #f2efe8;
border-radius: 0;
overflow: visible;
}
.sheet-musicxml-fallback[data-theme="light"],
body.light .sheet-musicxml-fallback {
background: #fff;
color: #111318;
}
.sheet-musicxml-fallback[data-theme="dark"],
body:not(.light) .sheet-musicxml-fallback {
background: #181824;
color: #f2efe8;
}
.sheet-musicxml-fallback svg {
color: currentColor !important;
}
.sheet-musicxml-fallback[data-theme="dark"] svg :is(path, ellipse, polygon, polyline, line, text, tspan, use):not(.accompy-measure-highlight),
body:not(.light) .sheet-musicxml-fallback svg :is(path, ellipse, polygon, polyline, line, text, tspan, use):not(.accompy-measure-highlight) {
fill: #f2efe8 !important;
stroke: #f2efe8 !important;
}
.sheet-musicxml-fallback[data-theme="dark"] svg rect:not(.accompy-measure-highlight),
body:not(.light) .sheet-musicxml-fallback svg rect:not(.accompy-measure-highlight) {
fill: #f2efe8 !important;
stroke: #f2efe8 !important;
}
.sheet-musicxml-fallback[data-theme="dark"] svg [fill="none"],
body:not(.light) .sheet-musicxml-fallback svg [fill="none"] {
fill: none !important;
}
.sheet-musicxml-fallback[data-theme="dark"] svg [stroke="none"],
body:not(.light) .sheet-musicxml-fallback svg [stroke="none"] {
stroke: none !important;
}
.sheet-musicxml-fallback[data-theme="dark"] svg rect[fill="white"],
.sheet-musicxml-fallback[data-theme="dark"] svg rect[fill="#ffffff"],
.sheet-musicxml-fallback[data-theme="dark"] svg rect[fill="#FFF"],
.sheet-musicxml-fallback[data-theme="dark"] svg rect[fill="#fff"],
body:not(.light) .sheet-musicxml-fallback svg rect[fill="white"],
body:not(.light) .sheet-musicxml-fallback svg rect[fill="#ffffff"],
body:not(.light) .sheet-musicxml-fallback svg rect[fill="#FFF"],
body:not(.light) .sheet-musicxml-fallback svg rect[fill="#fff"] {
fill: #181824 !important;
stroke: #181824 !important;
}
/* Back button row */
.top-row { display: flex; align-items: center; gap: 1rem; margin-bottom: 1.5rem; }
.top-row h2 { margin: 0; }
@media (max-width: 900px) {
.play-shell {
grid-template-columns: 1fr;
}
.play-sidebar {
position: static;
max-height: none;
}
.play-piece-list {
max-height: 220px;
}
.play-header,
.play-bottom {
grid-template-columns: 1fr;
display: grid;
}
.tempo-row {
flex-direction: column;
align-items: stretch;
}
.tempo-actions {
justify-content: flex-start;
}
.latency-row {
grid-template-columns: 1fr;
}
.latency-row span {
text-align: left;
}
.keyboard-heading {
flex-direction: column;
align-items: flex-start;
}
}
/* ── Practice workspace refactor ── */
#play-screen {
height: calc(100vh - 70px);
overflow: hidden;
}
body.practice-mode #play-screen {
height: 100vh;
max-width: 100%;
padding: 1rem;
}
body:has(#play-screen.active) #play-screen {
height: 100vh;
max-width: 100%;
padding: .25rem;
}
#play-screen h2 {
margin: 0;
color: var(--text);
}
.play-shell {
grid-template-columns: 260px 12px minmax(0, 1fr);
column-gap: .5rem;
row-gap: 1rem;
align-items: stretch;
height: 100%;
min-height: 0;
}
.play-shell[data-sidebar="collapsed"] {
grid-template-columns: 58px 12px minmax(0, 1fr);
}
.play-sidebar {
position: relative;
top: auto;
height: 100%;
max-height: none;
border-radius: 8px;
}
.play-piece-list {
max-height: none;
min-height: 0;
}
.play-content {
display: grid;
grid-template-rows: 4px minmax(0, 1fr);
gap: .35rem;
min-height: 0;
}
.progress-bar {
margin-bottom: 0;
height: 5px;
}
.practice-area {
display: grid;
grid-template-columns: minmax(0, 1fr) 12px 320px;
column-gap: .5rem;
row-gap: 1rem;
min-height: 0;
overflow: hidden;
}
.layout-splitter {
position: relative;
min-width: 12px;
cursor: col-resize;
display: flex;
align-items: center;
justify-content: center;
touch-action: none;
}
.layout-splitter::before {
content: "";
position: absolute;
top: .5rem;
bottom: .5rem;
left: 50%;
width: 1px;
background: var(--border);
}
.layout-splitter span {
position: relative;
width: 5px;
height: 54px;
border-radius: 999px;
background: color-mix(in srgb, var(--border-strong) 82%, var(--surface));
box-shadow: 0 0 0 1px color-mix(in srgb, var(--surface) 75%, transparent);
}
.layout-splitter:hover span,
.layout-splitter:focus-visible span,
body.layout-resizing .layout-splitter span {
background: color-mix(in srgb, var(--accent) 72%, white);
}
body.layout-resizing {
cursor: col-resize;
user-select: none;
}
.practice-workspace {
min-width: 0;
min-height: 0;
display: grid;
grid-template-rows: minmax(0, 1fr) 12px minmax(0, 1fr);
gap: 0;
}
.practice-area .sheet-section {
min-width: 0;
min-height: 0;
display: flex;
flex-direction: column;
border-radius: 8px;
border: 1px solid var(--border);
}
.sheet-header {
flex-shrink: 0;
}
.sheet-viewer {
flex: 1;
min-height: 0;
height: auto;
}
.sheet-content-wrap {
height: 100%;
min-height: 100%;
}
#sheet-frame {
display: block;
height: 100%;
min-height: 0;
}
.sheet-musicxml-fallback {
height: 100%;
min-height: 100%;
overflow: auto;
}
.practice-splitter {
position: relative;
min-height: 12px;
cursor: row-resize;
display: flex;
align-items: center;
justify-content: center;
touch-action: none;
}
.practice-splitter::before {
content: "";
position: absolute;
left: .5rem;
right: .5rem;
top: 50%;
height: 1px;
background: var(--border);
}
.practice-splitter span {
position: relative;
width: 54px;
height: 5px;
border-radius: 999px;
background: color-mix(in srgb, var(--border-strong) 82%, var(--surface));
box-shadow: 0 0 0 1px color-mix(in srgb, var(--surface) 75%, transparent);
}
.practice-splitter:hover span,
.practice-splitter:focus-visible span,
body.practice-resizing .practice-splitter span {
background: color-mix(in srgb, var(--accent) 72%, white);
}
body.practice-resizing {
cursor: row-resize;
user-select: none;
}
.practice-panel {
min-height: 0;
display: flex;
flex-direction: column;
gap: .75rem;
overflow: auto;
scrollbar-gutter: stable;
padding-right: .65rem;
margin-right: -.65rem;
}
.practice-card {
min-width: 0;
border: 1px solid var(--border);
border-radius: 8px;
background: var(--panel);
padding: .9rem;
}
.practice-card h4,
.practice-card h5 {
margin: 0 0 .75rem;
font-size: .78rem;
color: var(--muted);
letter-spacing: 0;
}
.practice-card-header {
display: flex;
align-items: center;
justify-content: space-between;
gap: .6rem;
margin-bottom: .75rem;
}
.practice-card-header h4 {
margin: 0;
}
.guest-tips-card ul {
display: grid;
gap: .55rem;
list-style: none;
}
.guest-tips-card li {
position: relative;
padding-left: 1rem;
color: var(--text);
font-size: .82rem;
line-height: 1.4;
}
.guest-tips-card li::before {
content: "";
position: absolute;
left: 0;
top: .48rem;
width: .38rem;
height: .38rem;
border-radius: 50%;
background: var(--accent);
}
.guest-annotation-actions {
display: grid;
grid-template-columns: 1fr 1fr;
gap: .45rem;
margin-top: .8rem;
}
.guest-annotation-actions .btn {
justify-content: center;
padding: .46rem .55rem;
font-size: .72rem;
}
.guest-annotation-list {
display: flex;
flex-wrap: wrap;
gap: .4rem;
margin-top: .65rem;
}
.guest-annotation-list span,
.guest-annotation-list small {
border: 1px solid var(--border);
border-radius: 999px;
background: var(--surface);
color: var(--muted);
padding: .28rem .48rem;
font-size: .7rem;
}
.practice-pill {
border: 1px solid var(--border-strong);
border-radius: 999px;
padding: .18rem .55rem;
color: var(--muted);
font-size: .72rem;
background: var(--surface);
}
.next-note-card {
border-radius: 8px;
border: 1px solid color-mix(in srgb, var(--accent) 25%, var(--border));
background: color-mix(in srgb, var(--accent) 8%, var(--surface));
padding: .85rem;
text-align: center;
margin-bottom: .75rem;
}
.next-note-card > span {
display: block;
color: var(--muted);
font-size: .76rem;
margin-bottom: .35rem;
}
.practice-panel .status-panel {
background: transparent;
border-radius: 0;
padding: 0;
height: auto;
}
.practice-panel .status-row {
margin-bottom: .55rem;
}
.practice-panel .status-row:last-child {
margin-bottom: 0;
}
#next-note-display {
margin-top: 0;
font-size: 2.55rem;
line-height: 1;
}
.upgrade-toast {
position: fixed;
right: 1.25rem;
bottom: 1.25rem;
z-index: 80;
width: min(360px, calc(100vw - 2rem));
border: 1px solid color-mix(in srgb, var(--accent) 42%, var(--border));
border-radius: 12px;
background: var(--panel);
color: var(--text);
padding: 1rem;
box-shadow: 0 24px 80px rgba(0,0,0,.34);
}
.upgrade-toast strong {
display: block;
font-size: .98rem;
margin-bottom: .35rem;
}
.upgrade-toast p {
color: var(--muted);
font-size: .82rem;
line-height: 1.45;
padding-right: 1.25rem;
}
.upgrade-toast-actions {
display: flex;
gap: .55rem;
margin-top: .85rem;
}
.upgrade-toast-close {
position: absolute;
top: .55rem;
right: .55rem;
border: 0;
background: transparent;
color: var(--muted);
cursor: pointer;
font-size: .85rem;
}
.setup-control-block {
display: grid;
gap: .35rem;
margin-bottom: .75rem;
}
.setup-control-block label,
.setup-card .latency-row label {
color: var(--muted);
font-size: .76rem;
font-weight: 700;
}
.setup-control-block .bpm-row {
display: grid;
grid-template-columns: minmax(0, 1fr) auto;
align-items: center;
gap: .5rem;
}
.setup-control-block .bpm-row input {
width: 100%;
min-width: 0;
}
.setup-control-block .bpm-row span,
.setup-card .latency-row span {
color: var(--muted);
font-size: .76rem;
}
.setup-actions {
display: grid;
grid-template-columns: 1fr 1fr;
gap: .5rem;
margin: 0 0 .8rem;
}
.setup-actions .btn {
justify-content: center;
}
.setup-card .latency-row {
display: grid;
grid-template-columns: auto minmax(0, 1fr) 42px;
align-items: center;
gap: .5rem;
margin: 0 0 .85rem;
}
.setup-card .part-picker,
.input-mode-section {
margin: 0;
height: auto;
background: transparent;
border-radius: 0;
padding: 0;
}
.setup-card .part-picker h5 {
margin-bottom: .55rem;
}
.part-buttons {
gap: .45rem;
}
.part-row {
display: grid;
grid-template-columns: minmax(0, 1fr) minmax(110px, .8fr);
}
.part-btn {
width: 100%;
text-align: left;
}
.accompaniment-row {
display: flex;
align-items: center;
justify-content: space-between;
gap: .75rem;
margin-top: .75rem;
padding-top: .75rem;
border-top: 1px solid var(--border);
color: var(--muted);
font-size: .8rem;
}
.accompaniment-row strong {
color: var(--text);
font-size: .8rem;
}
.practice-panel .input-mode-section h4 {
margin-bottom: .65rem;
}
.practice-panel .input-mode-tabs {
margin-bottom: .65rem;
}
.practice-panel .mode-tab {
flex: 1;
padding: .42rem .55rem;
white-space: nowrap;
}
.keyboard-section {
min-height: 0;
margin-bottom: 0;
padding: .55rem .7rem .7rem;
border-radius: 8px;
border: 1px solid var(--border);
overflow: hidden;
display: flex;
flex-direction: column;
}
.keyboard-heading {
flex-shrink: 0;
margin-bottom: .5rem;
gap: .6rem;
}
.keyboard-section h4 {
font-size: .78rem;
}
.keyboard-view-toggle {
flex-wrap: wrap;
}
.keyboard-view-btn {
white-space: nowrap;
}
.piano-stage {
border-radius: 8px;
flex: 1;
min-height: 0;
overflow: hidden;
}
.mini-keyboard-panel {
min-height: 0;
height: 100%;
display: flex;
flex-direction: column;
}
.note-highway {
height: 110px;
min-height: 80px;
flex: 1;
}
.kb-layout {
padding: .5rem;
flex-shrink: 0;
}
.kb-key {
height: 92px;
padding-top: 1.25rem;
}
.kb-key-white {
height: 92px;
}
.kb-key-black {
height: 58px;
padding-top: .65rem;
}
.reference-keyboard-panel {
margin-top: 0;
padding: 0;
border-top: 0;
min-height: 0;
height: 100%;
display: flex;
flex-direction: column;
}
.full-note-highway {
flex: 1;
min-height: 72px;
margin-bottom: .55rem;
}
.reference-keyboard-shell {
flex-shrink: 0;
height: clamp(72px, 18vh, 118px);
padding: 0;
}
.reference-keyboard {
height: 100%;
border-radius: 8px;
}
.ref-key-white {
padding-bottom: .2rem;
font-size: 0;
}
.ref-key-black {
height: 58%;
padding-bottom: .12rem;
font-size: 0;
}
@media (max-width: 1180px) {
#play-screen {
height: auto;
overflow: visible;
}
.play-shell {
grid-template-columns: 220px 12px minmax(0, 1fr);
align-items: start;
}
.practice-area {
grid-template-columns: 1fr !important;
}
.panel-splitter {
display: none;
}
.practice-panel {
display: grid;
grid-template-columns: repeat(3, minmax(0, 1fr));
align-items: start;
padding-right: 0;
margin-right: 0;
}
}
@media (max-width: 900px) {
.play-shell,
.play-shell[data-sidebar="collapsed"] {
grid-template-columns: 1fr !important;
height: auto;
}
.shell-splitter {
display: none;
}
.practice-workspace {
grid-template-rows: minmax(420px, 1fr) 12px minmax(260px, .7fr);
}
.practice-panel {
grid-template-columns: 1fr;
}
#sheet-frame,
.sheet-musicxml-fallback {
min-height: 100%;
}
.setup-card .latency-row {
grid-template-columns: minmax(0, 1fr);
}
.setup-card .latency-row span {
text-align: left;
}
}
/* ── Modal ── */
.modal-backdrop {
position: fixed; inset: 0; background: rgba(0,0,0,.65);
display: flex; align-items: center; justify-content: center; z-index: 100;
}
.modal {
background: var(--panel); border: 1px solid var(--border); border-radius: 12px;
width: min(600px, 94vw); max-height: 80vh; display: flex; flex-direction: column;
}
.modal-header {
display: flex; align-items: center; justify-content: space-between;
padding: 1rem 1.25rem; border-bottom: 1px solid #2a2a38;
}
.modal-header h3 { font-size: 1rem; }
.modal-close {
background: none; border: none; color: #aaa; font-size: 1.1rem;
cursor: pointer; padding: .2rem .5rem; border-radius: 4px;
}
.modal-close:hover { background: #2a2a38; }
.modal-body { padding: 1rem 1.25rem; overflow-y: auto; }
.confirm-modal { max-width: 420px; }
.confirm-modal-message { margin: 0 0 1.25rem; color: var(--text); font-size: .95rem; line-height: 1.45; }
.confirm-modal-actions { display: flex; justify-content: flex-end; gap: .6rem; }
.search-row {
display: flex; align-items: center; gap: .5rem; margin-bottom: .75rem;
}
.search-row input {
flex: 1; padding: .55rem .9rem; border-radius: 8px;
border: 1px solid #3a3a50; background: #0f0f13; color: #e8e8f0;
font-size: .95rem;
}
.search-hint { color: #555; font-size: .85rem; text-align: center; padding: 1rem 0; }
.search-results { display: flex; flex-direction: column; gap: .4rem; }
.result-item {
display: flex; align-items: center; justify-content: space-between;
padding: .6rem .85rem; background: #0f0f13; border-radius: 8px;
border: 1px solid #2a2a38;
}
.result-item .result-info { min-width: 0; }
.result-item .result-path { font-size: .8rem; color: #888; margin-top: .15rem; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.result-item .result-name { font-size: .9rem; font-weight: 500; }
.result-item .btn { flex-shrink: 0; font-size: .8rem; padding: .35rem .8rem; }
.result-item.adding { opacity: .6; pointer-events: none; }
.result-item.done { border-color: #5aaa60; }
/* Responsive */
@media (max-width: 640px) {
.play-top { grid-template-columns: 1fr; }
}