{#if nav.timing}
{#if confirmDiscard}
Discard?
{:else}
{/if}
Tap in time
{tapSync.identity?.title ?? ""}
{done} / {rows.length}
{#if wrong}
Another track is playing — a tap follows what plays. Play “{tapSync.identity?.title}” again to keep going.
{:else if tapSync.error}
{tapSync.error}
{/if} {#if cols.length}
{#each cols as v, i (i)}
{/each} {#each rows as r, i (i)} {#if r.time_ms != null}
{/if} {/each}
{/if}
{ if (tapSync.estimated) clearEstimate(); else estimateTimings(); }} disabled={tapSync.reading !== "ready"}>{estLabel}
{at > 0 ? rows[at - 1].text : ""}
{#if at < rows.length}
{rows[at].text}
{at + 1 < rows.length ? rows[at + 1].text : ""}
{tapSync.estimated ? "Estimated — tap to correct each line" : "Tap anywhere as the line begins"}
{:else}
That’s every line — save the timing.
Undo puts the last one back
{/if}
{at > 0 ? mark(rows[at - 1].time_ms) : mmss(player.position)}
−5 s
{ void saveTapSync(); }} disabled={!done || tapSync.saving}> {tapSync.saving ? "Saving…" : (done && done < rows.length ? `Save ${done} line${done === 1 ? "" : "s"}` : (tapSync.estimated && done === rows.length ? "Save the estimate" : "Save timing"))}
{/if}