Spaces:
Running on Zero
Running on Zero
Upload 8 files
Browse files- frontend/app.css +10 -8
- frontend/studio.css +82 -15
- frontend/studio.html +2 -2
- frontend/studio.js +14 -3
frontend/app.css
CHANGED
|
@@ -20,20 +20,23 @@
|
|
| 20 |
:host {
|
| 21 |
display: block;
|
| 22 |
min-height: 100vh;
|
|
|
|
| 23 |
color-scheme: dark;
|
|
|
|
|
|
|
| 24 |
background:
|
| 25 |
linear-gradient(115deg, rgba(69,209,181,.045) 0 1px, transparent 1px 100%),
|
| 26 |
linear-gradient(180deg, #101315 0%, #0b0d0e 34%, #090b0c 100%);
|
| 27 |
background-size: 56px 56px, auto;
|
| 28 |
}
|
| 29 |
|
| 30 |
-
html, body { min-height: 100%; background: var(--ui-bg) !important; }
|
| 31 |
body { margin: 0; color: var(--ui-text); font-family: var(--ui-font); -webkit-font-smoothing: antialiased; }
|
| 32 |
-
.gradio-container, .gradio-container.dark { min-height: 100vh !important; max-width: none !important; margin: 0 !important; padding: 0 !important; color: var(--ui-text) !important; background: transparent !important; font-family: var(--ui-font) !important; }
|
| 33 |
.gradio-container .prose, .gradio-container .prose * { color: inherit; }
|
| 34 |
.gradio-container footer { display: none !important; }
|
| 35 |
|
| 36 |
-
#app-shell { width: min(1360px, calc(100% - 44px)); margin: 0 auto; padding: 22px 0 48px; gap: 14px; }
|
| 37 |
#masthead, #intro { padding: 0 !important; border: 0 !important; background: transparent !important; }
|
| 38 |
|
| 39 |
.workbench-nav { display: flex; align-items: center; justify-content: space-between; min-height: 48px; gap: 20px; padding: 0 2px 11px; border-bottom: 1px solid var(--ui-line); }
|
|
@@ -72,9 +75,7 @@ body { margin: 0; color: var(--ui-text); font-family: var(--ui-font); -webkit-fo
|
|
| 72 |
|
| 73 |
#input-workbench, #transcription-panel { position: relative; min-width: 0; padding: clamp(16px,1.9vw,23px) !important; border: 1px solid var(--ui-line) !important; background: rgba(18,21,23,.94) !important; box-shadow: 0 20px 58px rgba(0,0,0,.19) !important; }
|
| 74 |
#input-workbench { border-radius: 14px !important; }
|
| 75 |
-
#
|
| 76 |
-
#transcription-panel { border-radius: 8px 17px 17px 17px !important; }
|
| 77 |
-
#transcription-panel::before { position: absolute; top: -1px; left: -1px; width: 84px; height: 5px; content: ""; background: linear-gradient(90deg,var(--ui-warm),#d8784f); }
|
| 78 |
|
| 79 |
.panel-heading { display: flex; align-items: flex-end; justify-content: space-between; gap: 20px; padding: 0 1px 13px; border-bottom: 1px solid var(--ui-line); }
|
| 80 |
.panel-heading span { display: block; margin-bottom: 5px; color: var(--ui-accent); font: 620 .57rem var(--ui-mono); letter-spacing: .1em; text-transform: uppercase; }
|
|
@@ -186,9 +187,9 @@ body { margin: 0; color: var(--ui-text); font-family: var(--ui-font); -webkit-fo
|
|
| 186 |
}
|
| 187 |
|
| 188 |
@media (max-width: 720px) {
|
| 189 |
-
#app-shell { width:
|
| 190 |
.workbench-nav, .panel-heading, .footnote { align-items: flex-start; flex-direction: column; }
|
| 191 |
-
.runtime-status { width: 100%; }
|
| 192 |
.workbench-intro { padding: 28px 2px 24px; }
|
| 193 |
.intro-statement h1 { font-size: clamp(2.35rem,12vw,3.6rem); }
|
| 194 |
.project-references { width: 100%; grid-template-columns: 1fr; }
|
|
@@ -199,6 +200,7 @@ body { margin: 0; color: var(--ui-text); font-family: var(--ui-font); -webkit-fo
|
|
| 199 |
#decode-panel, #notation-panel { width: 100% !important; flex-basis: 100% !important; }
|
| 200 |
#run-row { align-items: stretch; flex-direction: column !important; }
|
| 201 |
#transcribe-button { width: 100% !important; flex-basis: auto !important; }
|
|
|
|
| 202 |
}
|
| 203 |
|
| 204 |
@media (prefers-reduced-motion: reduce) {
|
|
|
|
| 20 |
:host {
|
| 21 |
display: block;
|
| 22 |
min-height: 100vh;
|
| 23 |
+
overflow-x: hidden;
|
| 24 |
color-scheme: dark;
|
| 25 |
+
-webkit-text-size-adjust: 100%;
|
| 26 |
+
text-size-adjust: 100%;
|
| 27 |
background:
|
| 28 |
linear-gradient(115deg, rgba(69,209,181,.045) 0 1px, transparent 1px 100%),
|
| 29 |
linear-gradient(180deg, #101315 0%, #0b0d0e 34%, #090b0c 100%);
|
| 30 |
background-size: 56px 56px, auto;
|
| 31 |
}
|
| 32 |
|
| 33 |
+
html, body { min-height: 100%; overflow-x: hidden; background: var(--ui-bg) !important; -webkit-text-size-adjust: 100%; text-size-adjust: 100%; }
|
| 34 |
body { margin: 0; color: var(--ui-text); font-family: var(--ui-font); -webkit-font-smoothing: antialiased; }
|
| 35 |
+
.gradio-container, .gradio-container.dark { min-height: 100vh !important; max-width: none !important; overflow-x: hidden !important; margin: 0 !important; padding: 0 !important; color: var(--ui-text) !important; background: transparent !important; font-family: var(--ui-font) !important; }
|
| 36 |
.gradio-container .prose, .gradio-container .prose * { color: inherit; }
|
| 37 |
.gradio-container footer { display: none !important; }
|
| 38 |
|
| 39 |
+
#app-shell { width: min(1360px, calc(100% - 44px)); min-width: 0; margin: 0 auto; padding: 22px 0 48px; gap: 14px; }
|
| 40 |
#masthead, #intro { padding: 0 !important; border: 0 !important; background: transparent !important; }
|
| 41 |
|
| 42 |
.workbench-nav { display: flex; align-items: center; justify-content: space-between; min-height: 48px; gap: 20px; padding: 0 2px 11px; border-bottom: 1px solid var(--ui-line); }
|
|
|
|
| 75 |
|
| 76 |
#input-workbench, #transcription-panel { position: relative; min-width: 0; padding: clamp(16px,1.9vw,23px) !important; border: 1px solid var(--ui-line) !important; background: rgba(18,21,23,.94) !important; box-shadow: 0 20px 58px rgba(0,0,0,.19) !important; }
|
| 77 |
#input-workbench { border-radius: 14px !important; }
|
| 78 |
+
#transcription-panel { border-radius: 14px !important; }
|
|
|
|
|
|
|
| 79 |
|
| 80 |
.panel-heading { display: flex; align-items: flex-end; justify-content: space-between; gap: 20px; padding: 0 1px 13px; border-bottom: 1px solid var(--ui-line); }
|
| 81 |
.panel-heading span { display: block; margin-bottom: 5px; color: var(--ui-accent); font: 620 .57rem var(--ui-mono); letter-spacing: .1em; text-transform: uppercase; }
|
|
|
|
| 187 |
}
|
| 188 |
|
| 189 |
@media (max-width: 720px) {
|
| 190 |
+
#app-shell { width: calc(100% - 18px); max-width: 1360px; padding-top: 14px; }
|
| 191 |
.workbench-nav, .panel-heading, .footnote { align-items: flex-start; flex-direction: column; }
|
| 192 |
+
.runtime-status { width: 100%; flex-wrap: wrap; }
|
| 193 |
.workbench-intro { padding: 28px 2px 24px; }
|
| 194 |
.intro-statement h1 { font-size: clamp(2.35rem,12vw,3.6rem); }
|
| 195 |
.project-references { width: 100%; grid-template-columns: 1fr; }
|
|
|
|
| 200 |
#decode-panel, #notation-panel { width: 100% !important; flex-basis: 100% !important; }
|
| 201 |
#run-row { align-items: stretch; flex-direction: column !important; }
|
| 202 |
#transcribe-button { width: 100% !important; flex-basis: auto !important; }
|
| 203 |
+
#input-workbench input[type="text"], #input-workbench input[type="number"], #input-workbench input[type="search"], #input-workbench input[type="email"], #input-workbench input[type="url"], #input-workbench textarea, #input-workbench select { font-size: 16px !important; }
|
| 204 |
}
|
| 205 |
|
| 206 |
@media (prefers-reduced-motion: reduce) {
|
frontend/studio.css
CHANGED
|
@@ -1,5 +1,7 @@
|
|
| 1 |
:root {
|
| 2 |
color-scheme: dark;
|
|
|
|
|
|
|
| 3 |
--ms-bg: #0b0e0f;
|
| 4 |
--ms-panel: #121617;
|
| 5 |
--ms-panel-2: #171c1e;
|
|
@@ -19,18 +21,21 @@
|
|
| 19 |
}
|
| 20 |
|
| 21 |
* { box-sizing: border-box; }
|
| 22 |
-
.ms-root { display: grid; min-width: 0; gap: 12px; color: var(--ms-text); font-family: Inter, ui-sans-serif, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif; container-type: inline-size; }
|
| 23 |
.ms-root [hidden] { display: none !important; }
|
| 24 |
-
.ms-root button, .ms-root input, .ms-root select { font: inherit; }
|
| 25 |
|
| 26 |
-
.ms-topbar { display: flex; align-items: flex-start; justify-content: space-between; min-width: 0; gap: 20px; padding:
|
| 27 |
-
.ms-root[data-state="queued"] .ms-topbar, .ms-root[data-state="loading"] .ms-topbar, .ms-root[data-state="transcribing"] .ms-topbar, .ms-root[data-state="generating_score"] .ms-topbar { border-left-color: var(--ms-warning); }
|
| 28 |
.ms-root[data-state="complete"] .ms-topbar, .ms-root[data-state="ready"] .ms-topbar { border-left-color: var(--ms-success); }
|
| 29 |
-
.ms-root[data-state="error"] .ms-topbar, .ms-root[data-state="notation_error"] .ms-topbar { border-left-color: var(--ms-danger); }
|
| 30 |
.ms-heading { min-width: 0; }
|
| 31 |
.ms-heading h2 { overflow: hidden; max-width: 760px; margin: 0; color: var(--ms-text); font-size: clamp(1.02rem,2vw,1.3rem); font-weight: 620; letter-spacing: -.03em; text-overflow: ellipsis; white-space: nowrap; }
|
| 32 |
-
.ms-eyebrow { display: flex; align-items: center; gap: 8px; margin: 0 0
|
| 33 |
.ms-state-dot { width: 7px; height: 7px; flex: none; border-radius: 2px; background: var(--ms-faint); transform: rotate(45deg); }
|
|
|
|
|
|
|
|
|
|
| 34 |
.ms-root[data-state="queued"] .ms-state-dot, .ms-root[data-state="loading"] .ms-state-dot, .ms-root[data-state="transcribing"] .ms-state-dot, .ms-root[data-state="generating_score"] .ms-state-dot { background: var(--ms-warning); box-shadow: 0 0 12px rgba(238,173,104,.55); animation: ms-blink 1.3s ease-in-out infinite; }
|
| 35 |
.ms-root[data-state="complete"] .ms-state-dot, .ms-root[data-state="ready"] .ms-state-dot { background: var(--ms-success); box-shadow: 0 0 10px rgba(102,214,167,.42); }
|
| 36 |
.ms-root[data-state="error"] .ms-state-dot, .ms-root[data-state="notation_error"] .ms-state-dot { background: var(--ms-danger); }
|
|
@@ -38,19 +43,25 @@
|
|
| 38 |
.ms-subtitle b { color: var(--ms-faint); font: 550 .55rem var(--ms-mono); white-space: nowrap; }
|
| 39 |
.ms-subtitle b::before { margin-right: 8px; content: "/"; }
|
| 40 |
|
| 41 |
-
.ms-quick-downloads { display: flex; flex: none; gap: 5px; }
|
| 42 |
.ms-quick-downloads a, .ms-tracks-heading button, .ms-track-controls button, .ms-track-controls a { display: inline-flex; align-items: center; justify-content: center; border: 1px solid var(--ms-line); border-radius: 4px; color: var(--ms-soft); background: rgba(255,255,255,.018); cursor: pointer; text-decoration: none; transition: border-color 130ms ease, color 130ms ease, background 130ms ease; }
|
| 43 |
.ms-quick-downloads a { min-height: 31px; gap: 6px; padding: 0 9px; font: 610 .56rem var(--ms-mono); text-transform: uppercase; }
|
| 44 |
.ms-quick-downloads svg { width: 13px; height: 13px; fill: none; stroke: currentColor; stroke-linecap: round; stroke-linejoin: round; stroke-width: 1.6; }
|
| 45 |
.ms-quick-downloads a:hover:not([aria-disabled="true"]), .ms-tracks-heading button:hover, .ms-track-controls button:hover, .ms-track-controls a:hover:not([aria-disabled="true"]) { border-color: rgba(69,209,181,.42); color: #d9fff7; background: rgba(69,209,181,.075); }
|
| 46 |
.ms-quick-downloads a[aria-disabled="true"], .ms-track-controls a[aria-disabled="true"] { pointer-events: none; opacity: .28; }
|
| 47 |
|
| 48 |
-
.ms-progress { display: grid; grid-template-columns: minmax(0,1fr) minmax(
|
| 49 |
-
.ms-progress > div { display: flex; justify-content: space-between; gap:
|
| 50 |
-
.ms-progress
|
| 51 |
-
.ms-progress
|
|
|
|
|
|
|
| 52 |
.ms-progress i span { display: block; width: 0; height: 100%; background: repeating-linear-gradient(90deg,var(--ms-warm) 0 calc(10% - 2px),rgba(216,120,79,.35) calc(10% - 2px),rgba(216,120,79,.35) 10%); box-shadow: 0 0 13px rgba(238,173,104,.2); transition: width 300ms ease; }
|
| 53 |
.ms-progress[data-indeterminate="true"] i span { width: 34% !important; animation: ms-progress-scan 1.25s ease-in-out infinite; }
|
|
|
|
|
|
|
|
|
|
|
|
|
| 54 |
|
| 55 |
.ms-empty { min-height: 440px; display: grid; align-content: center; justify-items: center; padding: 35px 20px; border: 1px dashed var(--ms-line-strong); background: repeating-linear-gradient(90deg,transparent 0 79px,rgba(255,255,255,.018) 80px), #0b0f10; text-align: center; }
|
| 56 |
.ms-empty-icon { display: grid; width: 46px; height: 46px; border: 1px solid rgba(69,209,181,.27); color: var(--ms-accent); background: rgba(69,209,181,.035); place-items: center; }
|
|
@@ -118,7 +129,7 @@
|
|
| 118 |
.ms-roll-surface { display: grid; grid-template-columns: 56px minmax(0,1fr); min-width: 0; min-height: 0; flex: 1; overflow: hidden; border: 1px solid var(--ms-line); background: #090c0d; }
|
| 119 |
.ms-roll-surface canvas { display: block; }
|
| 120 |
.ms-piano-keys { width: 56px; height: 100%; border-right: 1px solid rgba(255,255,255,.09); background: #10141b; }
|
| 121 |
-
.ms-roll-scroll { position: relative; min-width: 0; min-height: 0; overflow-x: auto; overflow-y: hidden; scrollbar-width: thin; scrollbar-color: rgba(255,255,255,.16) #090c0d; overscroll-behavior-x: contain; }
|
| 122 |
.ms-roll-scroll::-webkit-scrollbar { height: 8px; }
|
| 123 |
.ms-roll-scroll::-webkit-scrollbar-track { background: #090c0d; }
|
| 124 |
.ms-roll-scroll::-webkit-scrollbar-thumb { border: 2px solid #090c0d; border-radius: 999px; background: rgba(255,255,255,.18); }
|
|
@@ -146,13 +157,13 @@
|
|
| 146 |
.ms-root[data-state="generating_score"] .ms-score-empty span { animation: ms-score-pulse 1.15s ease-in-out infinite; }
|
| 147 |
.ms-score-document { width: 100%; height: 100%; }
|
| 148 |
.ms-score-document[hidden] { display: none; }
|
| 149 |
-
.ms-score-document[data-mode="pages"] { display: grid; overflow: auto; min-width:
|
| 150 |
.ms-score-document[data-mode="message"] { display: grid; overflow: auto; padding: 24px; place-items: center; }
|
| 151 |
.ms-score-message { display: grid; max-width: 420px; justify-items: center; padding: 24px; border: 1px solid var(--ms-line); border-radius: 4px; color: var(--ms-muted); background: #131819; text-align: center; }
|
| 152 |
.ms-score-message strong { color: var(--ms-soft); font-size: .76rem; }
|
| 153 |
.ms-score-message p { margin: 7px 0 14px; font-size: .62rem; line-height: 1.5; }
|
| 154 |
.ms-score-message a { display: inline-flex; min-height: 31px; align-items: center; padding: 0 10px; border: 1px solid rgba(238,173,104,.38); border-radius: 3px; color: #ffe4c4; background: rgba(238,173,104,.07); font: 600 .56rem var(--ms-mono); text-decoration: none; }
|
| 155 |
-
.ms-score-page { position: relative; margin: 0; padding: 17px; background: #fffdf7; box-shadow: 0 10px 30px rgba(0,0,0,.3); }
|
| 156 |
.ms-score-page img, .ms-score-page svg { display: block; width: 100%; height: auto; color: #111; }
|
| 157 |
.ms-score-page-number { position: absolute; right: 8px; bottom: 5px; color: rgba(18,18,18,.45); font: 8px var(--ms-mono); letter-spacing: .02em; }
|
| 158 |
|
|
@@ -162,7 +173,7 @@
|
|
| 162 |
.ms-kicker { color: var(--ms-soft); font-size: .67rem; font-weight: 620; }
|
| 163 |
.ms-tracks-heading strong { margin-top: 3px; color: var(--ms-faint); font: .53rem var(--ms-mono); }
|
| 164 |
.ms-tracks-heading button { min-height: 27px; padding: 0 7px; font-size: .54rem; }
|
| 165 |
-
.ms-track-list { display: grid; align-content: start; min-height: 0; overflow-y: auto; scrollbar-color: rgba(255,255,255,.14) transparent; }
|
| 166 |
.ms-track-placeholder { padding: 18px 12px; color: var(--ms-faint); font-size: .63rem; line-height: 1.5; text-align: center; }
|
| 167 |
.ms-track-row { display: grid; grid-template-columns: 5px minmax(0,1fr) auto; align-items: center; min-width: 0; min-height: 76px; gap: 9px; padding: 10px; border-bottom: 1px solid var(--ms-line); background: rgba(255,255,255,.008); transition: opacity 130ms ease, background 130ms ease; }
|
| 168 |
.ms-track-row:hover { background: rgba(255,255,255,.025); }
|
|
@@ -189,6 +200,7 @@
|
|
| 189 |
.ms-announcer { position: absolute; overflow: hidden; width: 1px; height: 1px; clip: rect(0 0 0 0); }
|
| 190 |
|
| 191 |
@keyframes ms-blink { 0%,100% { opacity:.35; } 50% { opacity:1; } }
|
|
|
|
| 192 |
@keyframes ms-progress-scan { 0% { transform: translateX(-120%); } 60%,100% { transform: translateX(310%); } }
|
| 193 |
@keyframes ms-score-pulse { 0%,100% { opacity:.45; transform: translateY(0); } 50% { opacity:1; transform: translateY(-4px); } }
|
| 194 |
|
|
@@ -224,6 +236,10 @@
|
|
| 224 |
.ms-synth-state { width: 100%; max-width: none; }
|
| 225 |
.ms-view-shell { height: 350px; }
|
| 226 |
.ms-tabs > span { display: none; }
|
|
|
|
|
|
|
|
|
|
|
|
|
| 227 |
.ms-score-toolbar { grid-template-columns: minmax(0,1fr) auto; gap: 6px; }
|
| 228 |
.ms-score-toolbar > span { display: none; }
|
| 229 |
.ms-score-toolbar label > span { display: none; }
|
|
@@ -231,6 +247,57 @@
|
|
| 231 |
.ms-track-row:nth-child(odd) { border-right: 0; }
|
| 232 |
.ms-notation-info { align-items: flex-start; }
|
| 233 |
.ms-notation-info dl { display: grid; grid-template-columns: repeat(2,1fr); gap: 5px 12px; }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 234 |
}
|
| 235 |
|
| 236 |
@media (prefers-reduced-motion: reduce) {
|
|
|
|
| 1 |
:root {
|
| 2 |
color-scheme: dark;
|
| 3 |
+
-webkit-text-size-adjust: 100%;
|
| 4 |
+
text-size-adjust: 100%;
|
| 5 |
--ms-bg: #0b0e0f;
|
| 6 |
--ms-panel: #121617;
|
| 7 |
--ms-panel-2: #171c1e;
|
|
|
|
| 21 |
}
|
| 22 |
|
| 23 |
* { box-sizing: border-box; }
|
| 24 |
+
.ms-root { display: grid; width: 100%; max-width: 100%; min-width: 0; overflow: hidden; gap: 12px; color: var(--ms-text); font-family: Inter, ui-sans-serif, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif; -webkit-text-size-adjust: 100%; text-size-adjust: 100%; container-type: inline-size; }
|
| 25 |
.ms-root [hidden] { display: none !important; }
|
| 26 |
+
.ms-root button, .ms-root input, .ms-root select { min-width: 0; font: inherit; }
|
| 27 |
|
| 28 |
+
.ms-topbar { display: flex; align-items: flex-start; justify-content: space-between; width: 100%; max-width: 100%; min-width: 0; gap: 20px; padding: 7px 7px 11px 12px; border-left: 3px solid var(--ms-faint); transition: border-color 160ms ease, background 160ms ease; }
|
| 29 |
+
.ms-root[data-state="queued"] .ms-topbar, .ms-root[data-state="loading"] .ms-topbar, .ms-root[data-state="transcribing"] .ms-topbar, .ms-root[data-state="generating_score"] .ms-topbar { border-left-color: var(--ms-warning); background: linear-gradient(90deg,rgba(238,173,104,.055),transparent 58%); }
|
| 30 |
.ms-root[data-state="complete"] .ms-topbar, .ms-root[data-state="ready"] .ms-topbar { border-left-color: var(--ms-success); }
|
| 31 |
+
.ms-root[data-state="error"] .ms-topbar, .ms-root[data-state="notation_error"] .ms-topbar { border-left-color: var(--ms-danger); background: linear-gradient(90deg,rgba(251,113,133,.06),transparent 58%); }
|
| 32 |
.ms-heading { min-width: 0; }
|
| 33 |
.ms-heading h2 { overflow: hidden; max-width: 760px; margin: 0; color: var(--ms-text); font-size: clamp(1.02rem,2vw,1.3rem); font-weight: 620; letter-spacing: -.03em; text-overflow: ellipsis; white-space: nowrap; }
|
| 34 |
+
.ms-eyebrow { display: flex; width: max-content; min-height: 23px; align-items: center; gap: 8px; margin: 0 0 8px; padding: 0 8px; border: 1px solid var(--ms-line); border-radius: 999px; color: var(--ms-muted); background: rgba(255,255,255,.018); font: 630 .57rem/1 var(--ms-mono); letter-spacing: .1em; text-transform: uppercase; }
|
| 35 |
.ms-state-dot { width: 7px; height: 7px; flex: none; border-radius: 2px; background: var(--ms-faint); transform: rotate(45deg); }
|
| 36 |
+
.ms-root[data-state="queued"] .ms-eyebrow, .ms-root[data-state="loading"] .ms-eyebrow, .ms-root[data-state="transcribing"] .ms-eyebrow, .ms-root[data-state="generating_score"] .ms-eyebrow { border-color: rgba(238,173,104,.38); color: #ffd8aa; background: rgba(238,173,104,.09); }
|
| 37 |
+
.ms-root[data-state="complete"] .ms-eyebrow, .ms-root[data-state="ready"] .ms-eyebrow { border-color: rgba(102,214,167,.34); color: #c8f8e2; background: rgba(102,214,167,.075); }
|
| 38 |
+
.ms-root[data-state="error"] .ms-eyebrow, .ms-root[data-state="notation_error"] .ms-eyebrow { border-color: rgba(251,113,133,.42); color: #ffc1cb; background: rgba(251,113,133,.085); }
|
| 39 |
.ms-root[data-state="queued"] .ms-state-dot, .ms-root[data-state="loading"] .ms-state-dot, .ms-root[data-state="transcribing"] .ms-state-dot, .ms-root[data-state="generating_score"] .ms-state-dot { background: var(--ms-warning); box-shadow: 0 0 12px rgba(238,173,104,.55); animation: ms-blink 1.3s ease-in-out infinite; }
|
| 40 |
.ms-root[data-state="complete"] .ms-state-dot, .ms-root[data-state="ready"] .ms-state-dot { background: var(--ms-success); box-shadow: 0 0 10px rgba(102,214,167,.42); }
|
| 41 |
.ms-root[data-state="error"] .ms-state-dot, .ms-root[data-state="notation_error"] .ms-state-dot { background: var(--ms-danger); }
|
|
|
|
| 43 |
.ms-subtitle b { color: var(--ms-faint); font: 550 .55rem var(--ms-mono); white-space: nowrap; }
|
| 44 |
.ms-subtitle b::before { margin-right: 8px; content: "/"; }
|
| 45 |
|
| 46 |
+
.ms-quick-downloads { display: flex; min-width: 0; flex: none; flex-wrap: wrap; gap: 5px; }
|
| 47 |
.ms-quick-downloads a, .ms-tracks-heading button, .ms-track-controls button, .ms-track-controls a { display: inline-flex; align-items: center; justify-content: center; border: 1px solid var(--ms-line); border-radius: 4px; color: var(--ms-soft); background: rgba(255,255,255,.018); cursor: pointer; text-decoration: none; transition: border-color 130ms ease, color 130ms ease, background 130ms ease; }
|
| 48 |
.ms-quick-downloads a { min-height: 31px; gap: 6px; padding: 0 9px; font: 610 .56rem var(--ms-mono); text-transform: uppercase; }
|
| 49 |
.ms-quick-downloads svg { width: 13px; height: 13px; fill: none; stroke: currentColor; stroke-linecap: round; stroke-linejoin: round; stroke-width: 1.6; }
|
| 50 |
.ms-quick-downloads a:hover:not([aria-disabled="true"]), .ms-tracks-heading button:hover, .ms-track-controls button:hover, .ms-track-controls a:hover:not([aria-disabled="true"]) { border-color: rgba(69,209,181,.42); color: #d9fff7; background: rgba(69,209,181,.075); }
|
| 51 |
.ms-quick-downloads a[aria-disabled="true"], .ms-track-controls a[aria-disabled="true"] { pointer-events: none; opacity: .28; }
|
| 52 |
|
| 53 |
+
.ms-progress { display: grid; grid-template-columns: minmax(0,1fr) minmax(220px,.42fr); align-items: center; gap: 16px; padding: 12px 13px; border: 1px solid rgba(238,173,104,.3); border-left: 4px solid var(--ms-warning); border-radius: 6px; background: linear-gradient(105deg,rgba(238,173,104,.09),rgba(238,173,104,.025) 62%); box-shadow: inset 0 1px rgba(255,255,255,.025), 0 8px 24px rgba(0,0,0,.12); }
|
| 54 |
+
.ms-progress > div { display: flex; align-items: center; justify-content: space-between; min-width: 0; gap: 10px; color: var(--ms-soft); font-size: .71rem; }
|
| 55 |
+
.ms-progress > div::before { width: 9px; height: 9px; flex: none; border-radius: 50%; content: ""; background: var(--ms-warning); box-shadow: 0 0 0 4px rgba(238,173,104,.1),0 0 15px rgba(238,173,104,.45); animation: ms-status-pulse 1.25s ease-in-out infinite; }
|
| 56 |
+
.ms-progress > div > span { overflow: hidden; flex: 1; font-weight: 620; text-overflow: ellipsis; white-space: nowrap; }
|
| 57 |
+
.ms-progress b { flex: none; color: #ffd5a3; font: 650 .67rem var(--ms-mono); }
|
| 58 |
+
.ms-progress i { display: block; overflow: hidden; height: 7px; border-radius: 999px; background: repeating-linear-gradient(90deg,rgba(255,255,255,.065) 0 calc(10% - 2px),transparent calc(10% - 2px) 10%); }
|
| 59 |
.ms-progress i span { display: block; width: 0; height: 100%; background: repeating-linear-gradient(90deg,var(--ms-warm) 0 calc(10% - 2px),rgba(216,120,79,.35) calc(10% - 2px),rgba(216,120,79,.35) 10%); box-shadow: 0 0 13px rgba(238,173,104,.2); transition: width 300ms ease; }
|
| 60 |
.ms-progress[data-indeterminate="true"] i span { width: 34% !important; animation: ms-progress-scan 1.25s ease-in-out infinite; }
|
| 61 |
+
.ms-root[data-state="error"] .ms-progress, .ms-root[data-state="notation_error"] .ms-progress { border-color: rgba(251,113,133,.35); border-left-color: var(--ms-danger); background: linear-gradient(105deg,rgba(251,113,133,.1),rgba(251,113,133,.025) 62%); }
|
| 62 |
+
.ms-root[data-state="error"] .ms-progress > div::before, .ms-root[data-state="notation_error"] .ms-progress > div::before { background: var(--ms-danger); box-shadow: 0 0 0 4px rgba(251,113,133,.1),0 0 15px rgba(251,113,133,.38); animation: none; }
|
| 63 |
+
.ms-root[data-state="error"] .ms-progress b, .ms-root[data-state="notation_error"] .ms-progress b { color: #ffc1cb; }
|
| 64 |
+
.ms-root[data-state="error"] .ms-progress i span, .ms-root[data-state="notation_error"] .ms-progress i span { background: var(--ms-danger); }
|
| 65 |
|
| 66 |
.ms-empty { min-height: 440px; display: grid; align-content: center; justify-items: center; padding: 35px 20px; border: 1px dashed var(--ms-line-strong); background: repeating-linear-gradient(90deg,transparent 0 79px,rgba(255,255,255,.018) 80px), #0b0f10; text-align: center; }
|
| 67 |
.ms-empty-icon { display: grid; width: 46px; height: 46px; border: 1px solid rgba(69,209,181,.27); color: var(--ms-accent); background: rgba(69,209,181,.035); place-items: center; }
|
|
|
|
| 129 |
.ms-roll-surface { display: grid; grid-template-columns: 56px minmax(0,1fr); min-width: 0; min-height: 0; flex: 1; overflow: hidden; border: 1px solid var(--ms-line); background: #090c0d; }
|
| 130 |
.ms-roll-surface canvas { display: block; }
|
| 131 |
.ms-piano-keys { width: 56px; height: 100%; border-right: 1px solid rgba(255,255,255,.09); background: #10141b; }
|
| 132 |
+
.ms-roll-scroll { position: relative; min-width: 0; min-height: 0; overflow-x: auto; overflow-y: hidden; -webkit-overflow-scrolling: touch; scrollbar-width: thin; scrollbar-color: rgba(255,255,255,.16) #090c0d; overscroll-behavior-x: contain; }
|
| 133 |
.ms-roll-scroll::-webkit-scrollbar { height: 8px; }
|
| 134 |
.ms-roll-scroll::-webkit-scrollbar-track { background: #090c0d; }
|
| 135 |
.ms-roll-scroll::-webkit-scrollbar-thumb { border: 2px solid #090c0d; border-radius: 999px; background: rgba(255,255,255,.18); }
|
|
|
|
| 157 |
.ms-root[data-state="generating_score"] .ms-score-empty span { animation: ms-score-pulse 1.15s ease-in-out infinite; }
|
| 158 |
.ms-score-document { width: 100%; height: 100%; }
|
| 159 |
.ms-score-document[hidden] { display: none; }
|
| 160 |
+
.ms-score-document[data-mode="pages"] { display: grid; overflow: auto; min-width: 0; gap: 14px; padding: 13px; -webkit-overflow-scrolling: touch; overscroll-behavior: contain; }
|
| 161 |
.ms-score-document[data-mode="message"] { display: grid; overflow: auto; padding: 24px; place-items: center; }
|
| 162 |
.ms-score-message { display: grid; max-width: 420px; justify-items: center; padding: 24px; border: 1px solid var(--ms-line); border-radius: 4px; color: var(--ms-muted); background: #131819; text-align: center; }
|
| 163 |
.ms-score-message strong { color: var(--ms-soft); font-size: .76rem; }
|
| 164 |
.ms-score-message p { margin: 7px 0 14px; font-size: .62rem; line-height: 1.5; }
|
| 165 |
.ms-score-message a { display: inline-flex; min-height: 31px; align-items: center; padding: 0 10px; border: 1px solid rgba(238,173,104,.38); border-radius: 3px; color: #ffe4c4; background: rgba(238,173,104,.07); font: 600 .56rem var(--ms-mono); text-decoration: none; }
|
| 166 |
+
.ms-score-page { position: relative; min-width: 680px; margin: 0; padding: 17px; background: #fffdf7; box-shadow: 0 10px 30px rgba(0,0,0,.3); }
|
| 167 |
.ms-score-page img, .ms-score-page svg { display: block; width: 100%; height: auto; color: #111; }
|
| 168 |
.ms-score-page-number { position: absolute; right: 8px; bottom: 5px; color: rgba(18,18,18,.45); font: 8px var(--ms-mono); letter-spacing: .02em; }
|
| 169 |
|
|
|
|
| 173 |
.ms-kicker { color: var(--ms-soft); font-size: .67rem; font-weight: 620; }
|
| 174 |
.ms-tracks-heading strong { margin-top: 3px; color: var(--ms-faint); font: .53rem var(--ms-mono); }
|
| 175 |
.ms-tracks-heading button { min-height: 27px; padding: 0 7px; font-size: .54rem; }
|
| 176 |
+
.ms-track-list { display: grid; align-content: start; min-height: 0; overflow-y: auto; -webkit-overflow-scrolling: touch; scrollbar-color: rgba(255,255,255,.14) transparent; }
|
| 177 |
.ms-track-placeholder { padding: 18px 12px; color: var(--ms-faint); font-size: .63rem; line-height: 1.5; text-align: center; }
|
| 178 |
.ms-track-row { display: grid; grid-template-columns: 5px minmax(0,1fr) auto; align-items: center; min-width: 0; min-height: 76px; gap: 9px; padding: 10px; border-bottom: 1px solid var(--ms-line); background: rgba(255,255,255,.008); transition: opacity 130ms ease, background 130ms ease; }
|
| 179 |
.ms-track-row:hover { background: rgba(255,255,255,.025); }
|
|
|
|
| 200 |
.ms-announcer { position: absolute; overflow: hidden; width: 1px; height: 1px; clip: rect(0 0 0 0); }
|
| 201 |
|
| 202 |
@keyframes ms-blink { 0%,100% { opacity:.35; } 50% { opacity:1; } }
|
| 203 |
+
@keyframes ms-status-pulse { 0%,100% { opacity:.55; transform: scale(.82); } 50% { opacity:1; transform: scale(1); } }
|
| 204 |
@keyframes ms-progress-scan { 0% { transform: translateX(-120%); } 60%,100% { transform: translateX(310%); } }
|
| 205 |
@keyframes ms-score-pulse { 0%,100% { opacity:.45; transform: translateY(0); } 50% { opacity:1; transform: translateY(-4px); } }
|
| 206 |
|
|
|
|
| 236 |
.ms-synth-state { width: 100%; max-width: none; }
|
| 237 |
.ms-view-shell { height: 350px; }
|
| 238 |
.ms-tabs > span { display: none; }
|
| 239 |
+
.ms-tabs { min-height: 0; flex-wrap: wrap; gap: 0 14px; padding: 0 8px 7px; }
|
| 240 |
+
.ms-tabs button { min-height: 40px; }
|
| 241 |
+
.ms-roll-zoom { width: 100%; padding-top: 7px; border-top: 1px solid var(--ms-line); }
|
| 242 |
+
.ms-roll-zoom input { width: auto; flex: 1; }
|
| 243 |
.ms-score-toolbar { grid-template-columns: minmax(0,1fr) auto; gap: 6px; }
|
| 244 |
.ms-score-toolbar > span { display: none; }
|
| 245 |
.ms-score-toolbar label > span { display: none; }
|
|
|
|
| 247 |
.ms-track-row:nth-child(odd) { border-right: 0; }
|
| 248 |
.ms-notation-info { align-items: flex-start; }
|
| 249 |
.ms-notation-info dl { display: grid; grid-template-columns: repeat(2,1fr); gap: 5px 12px; }
|
| 250 |
+
.ms-program-select, .ms-score-toolbar select { font-size: 16px; }
|
| 251 |
+
.ms-empty { min-height: 320px; }
|
| 252 |
+
}
|
| 253 |
+
|
| 254 |
+
/* Viewport fallbacks for Safari versions without reliable container queries. */
|
| 255 |
+
@media (max-width: 1030px) {
|
| 256 |
+
.ms-transport { grid-template-columns: 1fr; }
|
| 257 |
+
.ms-transport-options { padding-top: 7px; padding-left: 68px; border-top: 1px solid var(--ms-line); border-left: 0; }
|
| 258 |
+
.ms-studio-grid { grid-template-columns: 1fr; height: auto; }
|
| 259 |
+
.ms-view-shell { width: 100%; height: 440px; }
|
| 260 |
+
.ms-mixer { width: 100%; max-height: 430px; }
|
| 261 |
+
.ms-track-list { grid-template-columns: repeat(2,minmax(0,1fr)); }
|
| 262 |
+
.ms-track-row:nth-child(odd) { border-right: 1px solid var(--ms-line); }
|
| 263 |
+
}
|
| 264 |
+
|
| 265 |
+
@media (max-width: 650px) {
|
| 266 |
+
.ms-topbar { display: grid; gap: 12px; }
|
| 267 |
+
.ms-quick-downloads { width: 100%; }
|
| 268 |
+
.ms-quick-downloads a { min-width: 0; flex: 1; }
|
| 269 |
+
.ms-subtitle { align-items: flex-start; flex-direction: column; }
|
| 270 |
+
.ms-subtitle b::before { display: none; }
|
| 271 |
+
.ms-progress { grid-template-columns: 1fr; gap: 10px; }
|
| 272 |
+
.ms-progress > div > span { white-space: normal; }
|
| 273 |
+
.ms-stats { grid-template-columns: repeat(2,minmax(0,1fr)); }
|
| 274 |
+
.ms-stats > div:nth-child(3) { border-top: 1px solid var(--ms-line); border-left: 0; }
|
| 275 |
+
.ms-stats > div:nth-child(4) { border-top: 1px solid var(--ms-line); }
|
| 276 |
+
.ms-transport-main { flex-wrap: wrap; }
|
| 277 |
+
.ms-seek { min-width: calc(100% - 132px); }
|
| 278 |
+
.ms-transport-options { padding-left: 0; flex-wrap: wrap; }
|
| 279 |
+
.ms-loop-strip { align-items: flex-start; flex-direction: column; gap: 6px; }
|
| 280 |
+
.ms-loop-actions { width: 100%; flex-wrap: wrap; }
|
| 281 |
+
.ms-loop-actions button { flex: 1; }
|
| 282 |
+
.ms-loop-readout { width: 100%; justify-content: space-between; }
|
| 283 |
+
.ms-source-mix { width: 100%; }
|
| 284 |
+
.ms-source-mix input { flex: 1; }
|
| 285 |
+
.ms-synth-state { width: 100%; max-width: none; }
|
| 286 |
+
.ms-view-shell { height: 350px; }
|
| 287 |
+
.ms-tabs > span { display: none; }
|
| 288 |
+
.ms-tabs { min-height: 0; flex-wrap: wrap; gap: 0 14px; padding: 0 8px 7px; }
|
| 289 |
+
.ms-tabs button { min-height: 40px; }
|
| 290 |
+
.ms-roll-zoom { width: 100%; padding-top: 7px; border-top: 1px solid var(--ms-line); }
|
| 291 |
+
.ms-roll-zoom input { width: auto; flex: 1; }
|
| 292 |
+
.ms-score-toolbar { grid-template-columns: minmax(0,1fr) auto; gap: 6px; }
|
| 293 |
+
.ms-score-toolbar > span, .ms-score-toolbar label > span { display: none; }
|
| 294 |
+
.ms-score-page { min-width: 620px; }
|
| 295 |
+
.ms-track-list { grid-template-columns: 1fr; }
|
| 296 |
+
.ms-track-row:nth-child(odd) { border-right: 0; }
|
| 297 |
+
.ms-notation-info { align-items: flex-start; }
|
| 298 |
+
.ms-notation-info dl { display: grid; grid-template-columns: repeat(2,1fr); gap: 5px 12px; }
|
| 299 |
+
.ms-program-select, .ms-score-toolbar select { font-size: 16px; }
|
| 300 |
+
.ms-empty { min-height: 320px; }
|
| 301 |
}
|
| 302 |
|
| 303 |
@media (prefers-reduced-motion: reduce) {
|
frontend/studio.html
CHANGED
|
@@ -12,9 +12,9 @@
|
|
| 12 |
</div>
|
| 13 |
</header>
|
| 14 |
|
| 15 |
-
<div class="ms-progress" hidden>
|
| 16 |
<div><span data-field="progress-label">Preparing inference…</span><b data-field="progress-value">0%</b></div>
|
| 17 |
-
<i role="progressbar" aria-valuemin="0" aria-valuemax="100"><span data-field="progress-bar"></span></i>
|
| 18 |
</div>
|
| 19 |
|
| 20 |
<section class="ms-empty">
|
|
|
|
| 12 |
</div>
|
| 13 |
</header>
|
| 14 |
|
| 15 |
+
<div class="ms-progress" role="status" aria-live="polite" hidden>
|
| 16 |
<div><span data-field="progress-label">Preparing inference…</span><b data-field="progress-value">0%</b></div>
|
| 17 |
+
<i role="progressbar" aria-label="Transcription progress" aria-valuemin="0" aria-valuemax="100" aria-valuenow="0"><span data-field="progress-bar"></span></i>
|
| 18 |
</div>
|
| 19 |
|
| 20 |
<section class="ms-empty">
|
frontend/studio.js
CHANGED
|
@@ -10,7 +10,7 @@ const ui = {
|
|
| 10 |
status: $('[data-field="status"]'), audioName: $('[data-field="audio-name"]'),
|
| 11 |
summary: $('[data-field="summary"]'), progress: $('.ms-progress'),
|
| 12 |
progressLabel: $('[data-field="progress-label"]'), progressValue: $('[data-field="progress-value"]'),
|
| 13 |
-
progressBar: $('[data-field="progress-bar"]'), play: $('[data-action="play"]'),
|
| 14 |
stop: $('[data-action="stop"]'), seek: $('[data-action="seek"]'), clock: $('[data-field="clock"]'),
|
| 15 |
duration: $('[data-field="duration"]'), volume: $('[data-action="volume"]'),
|
| 16 |
loop: $('[data-action="loop"]'), selectRegion: $('[data-action="select-region"]'),
|
|
@@ -1123,14 +1123,25 @@ function render(data, { silent = false } = {}) {
|
|
| 1123 |
state.songTime = clamp(state.songTime, 0, Math.max(data.duration, playableEnd()));
|
| 1124 |
}
|
| 1125 |
root.dataset.state = data.state; const active = ['queued', 'loading', 'transcribing', 'generating_score'].includes(data.state);
|
|
|
|
| 1126 |
const hasResults = data.tracks.length > 0 || active;
|
| 1127 |
ui.empty.hidden = hasResults; ui.workspace.hidden = !hasResults;
|
| 1128 |
ui.state.textContent = ({ idle: 'Ready for audio', queued: 'ZeroGPU queued', loading: 'Loading model', transcribing: 'Transcribing', generating_score: 'Generating score', complete: 'MIDI ready', ready: 'Score ready', error: 'Error', notation_error: 'MIDI ready' })[data.state] || data.state;
|
| 1129 |
ui.status.textContent = data.status; ui.audioName.textContent = data.audio_name || 'Your transcription';
|
| 1130 |
ui.summary.textContent = data.audio_name ? `${data.note_count.toLocaleString('en-US')} notes · ${data.tracks.length} tracks` : '—';
|
| 1131 |
const indeterminate = data.state === 'generating_score';
|
| 1132 |
-
|
| 1133 |
-
ui.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1134 |
ui.duration.textContent = formatTime(data.duration); ui.seek.max = String(Math.max(.01, data.duration));
|
| 1135 |
setText('[data-field="track-count"]', data.tracks.length ? `${data.tracks.length} track${data.tracks.length > 1 ? 's' : ''}` : 'No tracks yet');
|
| 1136 |
setText('[data-field="info-duration"]', formatTime(data.duration)); setText('[data-field="note-count"]', data.note_count ? data.note_count.toLocaleString('en-US') : '—');
|
|
|
|
| 10 |
status: $('[data-field="status"]'), audioName: $('[data-field="audio-name"]'),
|
| 11 |
summary: $('[data-field="summary"]'), progress: $('.ms-progress'),
|
| 12 |
progressLabel: $('[data-field="progress-label"]'), progressValue: $('[data-field="progress-value"]'),
|
| 13 |
+
progressBar: $('[data-field="progress-bar"]'), progressTrack: $('.ms-progress [role="progressbar"]'), play: $('[data-action="play"]'),
|
| 14 |
stop: $('[data-action="stop"]'), seek: $('[data-action="seek"]'), clock: $('[data-field="clock"]'),
|
| 15 |
duration: $('[data-field="duration"]'), volume: $('[data-action="volume"]'),
|
| 16 |
loop: $('[data-action="loop"]'), selectRegion: $('[data-action="select-region"]'),
|
|
|
|
| 1123 |
state.songTime = clamp(state.songTime, 0, Math.max(data.duration, playableEnd()));
|
| 1124 |
}
|
| 1125 |
root.dataset.state = data.state; const active = ['queued', 'loading', 'transcribing', 'generating_score'].includes(data.state);
|
| 1126 |
+
const failed = ['error', 'notation_error'].includes(data.state);
|
| 1127 |
const hasResults = data.tracks.length > 0 || active;
|
| 1128 |
ui.empty.hidden = hasResults; ui.workspace.hidden = !hasResults;
|
| 1129 |
ui.state.textContent = ({ idle: 'Ready for audio', queued: 'ZeroGPU queued', loading: 'Loading model', transcribing: 'Transcribing', generating_score: 'Generating score', complete: 'MIDI ready', ready: 'Score ready', error: 'Error', notation_error: 'MIDI ready' })[data.state] || data.state;
|
| 1130 |
ui.status.textContent = data.status; ui.audioName.textContent = data.audio_name || 'Your transcription';
|
| 1131 |
ui.summary.textContent = data.audio_name ? `${data.note_count.toLocaleString('en-US')} notes · ${data.tracks.length} tracks` : '—';
|
| 1132 |
const indeterminate = data.state === 'generating_score';
|
| 1133 |
+
const progressPercent = failed ? 100 : Math.round(data.progress * 100);
|
| 1134 |
+
ui.progress.hidden = !(active || failed); ui.progress.dataset.indeterminate = String(indeterminate);
|
| 1135 |
+
ui.progressLabel.textContent = data.status;
|
| 1136 |
+
ui.progressValue.textContent = failed ? (data.state === 'notation_error' ? 'Score issue' : 'Failed') : indeterminate ? 'Rendering…' : `${progressPercent}%`;
|
| 1137 |
+
ui.progressBar.style.width = `${progressPercent}%`;
|
| 1138 |
+
if (indeterminate) {
|
| 1139 |
+
ui.progressTrack.removeAttribute('aria-valuenow');
|
| 1140 |
+
ui.progressTrack.setAttribute('aria-valuetext', 'Rendering in progress');
|
| 1141 |
+
} else {
|
| 1142 |
+
ui.progressTrack.setAttribute('aria-valuenow', String(progressPercent));
|
| 1143 |
+
ui.progressTrack.setAttribute('aria-valuetext', failed ? 'Operation failed' : `${progressPercent}% complete`);
|
| 1144 |
+
}
|
| 1145 |
ui.duration.textContent = formatTime(data.duration); ui.seek.max = String(Math.max(.01, data.duration));
|
| 1146 |
setText('[data-field="track-count"]', data.tracks.length ? `${data.tracks.length} track${data.tracks.length > 1 ? 's' : ''}` : 'No tracks yet');
|
| 1147 |
setText('[data-field="info-duration"]', formatTime(data.duration)); setText('[data-field="note-count"]', data.note_count ? data.note_count.toLocaleString('en-US') : '—');
|