fix(copy): replace em-dashes in user-facing strings with commas/periods
Per the project's no-dashes feedback rule (see CORBEL-Main memory
feedback_no_dashes.md), em-dashes in user-visible copy are the single
biggest "AI wrote this" surface tell. Forty-two occurrences across ten
files: ten in SettingsPage's group descriptions and option labels
(audio device picker, vocabulary help, prompt placeholders, model
descriptions), four in FirstRunPage's setup steps, three in
DictationPage / FilesPage / Energy chip tooltips, plus the privacy
bullets ("100% offline, no Python required, no cloud, no accounts,
no telemetry"), the rejection toast, MicroSteps thumb labels, and the
shutdown ritual prompts.
Replacement rule: subordinate-clause em-dashes followed by lowercase
become commas; sentence-break em-dashes followed by capitals become
full stops. Code comments left intact.
One non-em-dash regression caught while reviewing: TasksPage's energy
filter "no selection" placeholder showed "—" as a literal label; the
script changed it to a comma which read as a UI bug. Replaced with
"Any" instead.
This commit is contained in:
@@ -54,7 +54,7 @@
|
|||||||
let tooltip = $derived(
|
let tooltip = $derived(
|
||||||
energy === null
|
energy === null
|
||||||
? "Tag energy (click to set)"
|
? "Tag energy (click to set)"
|
||||||
: `Energy: ${labelFor(energy)} — click to change`
|
: `Energy: ${labelFor(energy)}, click to change`
|
||||||
);
|
);
|
||||||
|
|
||||||
// Icon dimensions. `md` is the one used on the Tasks-page main rows;
|
// Icon dimensions. `md` is the one used on the Tasks-page main rows;
|
||||||
|
|||||||
@@ -211,7 +211,7 @@
|
|||||||
</button>
|
</button>
|
||||||
{#if rejectionReason}
|
{#if rejectionReason}
|
||||||
<span class="text-[11px] text-warning" role="alert">
|
<span class="text-[11px] text-warning" role="alert">
|
||||||
Couldn't bind that combo — {rejectionReason}.
|
Couldn't bind that combo. {rejectionReason}.
|
||||||
</span>
|
</span>
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -263,8 +263,8 @@
|
|||||||
class="opacity-0 group-hover:opacity-100 p-0.5 text-text-tertiary hover:text-success
|
class="opacity-0 group-hover:opacity-100 p-0.5 text-text-tertiary hover:text-success
|
||||||
{rating[step.id] === 1 ? '!opacity-100 text-success' : ''}"
|
{rating[step.id] === 1 ? '!opacity-100 text-success' : ''}"
|
||||||
onclick={() => recordThumb(step, 1)}
|
onclick={() => recordThumb(step, 1)}
|
||||||
aria-label={rating[step.id] === 1 ? 'Remove thumbs up' : 'Thumbs up — this is a good step'}
|
aria-label={rating[step.id] === 1 ? 'Remove thumbs up' : 'Thumbs up, this is a good step'}
|
||||||
title="Thumbs up — train the model on this style"
|
title="Thumbs up, train the model on this style"
|
||||||
style={reduceMotion ? '' : 'transition: opacity var(--duration-ui), color var(--duration-ui)'}
|
style={reduceMotion ? '' : 'transition: opacity var(--duration-ui), color var(--duration-ui)'}
|
||||||
>
|
>
|
||||||
<ThumbsUp size={10} aria-hidden="true" />
|
<ThumbsUp size={10} aria-hidden="true" />
|
||||||
@@ -273,8 +273,8 @@
|
|||||||
class="opacity-0 group-hover:opacity-100 p-0.5 text-text-tertiary hover:text-danger
|
class="opacity-0 group-hover:opacity-100 p-0.5 text-text-tertiary hover:text-danger
|
||||||
{rating[step.id] === -1 ? '!opacity-100 text-danger' : ''}"
|
{rating[step.id] === -1 ? '!opacity-100 text-danger' : ''}"
|
||||||
onclick={() => recordThumb(step, -1)}
|
onclick={() => recordThumb(step, -1)}
|
||||||
aria-label={rating[step.id] === -1 ? 'Remove thumbs down' : 'Thumbs down — this misses the mark'}
|
aria-label={rating[step.id] === -1 ? 'Remove thumbs down' : 'Thumbs down, this misses the mark'}
|
||||||
title="Thumbs down — avoid this style"
|
title="Thumbs down, avoid this style"
|
||||||
style={reduceMotion ? '' : 'transition: opacity var(--duration-ui), color var(--duration-ui)'}
|
style={reduceMotion ? '' : 'transition: opacity var(--duration-ui), color var(--duration-ui)'}
|
||||||
>
|
>
|
||||||
<ThumbsDown size={10} aria-hidden="true" />
|
<ThumbsDown size={10} aria-hidden="true" />
|
||||||
@@ -283,7 +283,7 @@
|
|||||||
class="opacity-0 group-hover:opacity-100 p-0.5 text-text-tertiary hover:text-accent"
|
class="opacity-0 group-hover:opacity-100 p-0.5 text-text-tertiary hover:text-accent"
|
||||||
onclick={() => startEdit(step)}
|
onclick={() => startEdit(step)}
|
||||||
aria-label="Edit this step (the correction trains future suggestions)"
|
aria-label="Edit this step (the correction trains future suggestions)"
|
||||||
title="Edit — this is the strongest training signal"
|
title="Edit, this is the strongest training signal"
|
||||||
style={reduceMotion ? '' : 'transition: opacity var(--duration-ui)'}
|
style={reduceMotion ? '' : 'transition: opacity var(--duration-ui)'}
|
||||||
>
|
>
|
||||||
<Pencil size={10} aria-hidden="true" />
|
<Pencil size={10} aria-hidden="true" />
|
||||||
|
|||||||
@@ -1004,7 +1004,7 @@
|
|||||||
<Card classes="h-full flex flex-col">
|
<Card classes="h-full flex flex-col">
|
||||||
{#if transcriptionFailed && !transcript.trim() && !page.recording}
|
{#if transcriptionFailed && !transcript.trim() && !page.recording}
|
||||||
<div class="flex-1 flex items-center justify-center">
|
<div class="flex-1 flex items-center justify-center">
|
||||||
<EmptyState icon={AlertTriangle} message="Something went wrong with that transcription. Your audio is saved — try again when you're ready." />
|
<EmptyState icon={AlertTriangle} message="Something went wrong with that transcription. Your audio is saved, try again when you're ready." />
|
||||||
</div>
|
</div>
|
||||||
{:else if !transcript.trim() && !page.recording && !transcribing}
|
{:else if !transcript.trim() && !page.recording && !transcribing}
|
||||||
<div class="flex-1 flex items-center justify-center">
|
<div class="flex-1 flex items-center justify-center">
|
||||||
|
|||||||
@@ -109,7 +109,7 @@
|
|||||||
modelId: result.modelId ?? null,
|
modelId: result.modelId ?? null,
|
||||||
});
|
});
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
error = `Failed: ${fileName} — ${typeof err === "string" ? err : err.message}`;
|
error = `Failed: ${fileName}. ${typeof err === "string" ? err : err.message}`;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -227,7 +227,7 @@
|
|||||||
<Play size={32} strokeWidth={1.5} class="text-accent mx-auto mb-3" />
|
<Play size={32} strokeWidth={1.5} class="text-accent mx-auto mb-3" />
|
||||||
<h2 class="text-xl font-medium text-text">Launch Magnotia at login?</h2>
|
<h2 class="text-xl font-medium text-text">Launch Magnotia at login?</h2>
|
||||||
<p class="text-sm text-text-secondary mt-3 leading-relaxed">
|
<p class="text-sm text-text-secondary mt-3 leading-relaxed">
|
||||||
So Magnotia is already there when you need it — especially useful if you said yes to morning triage. Uses your OS's standard autostart. No background tricks, no telemetry.
|
So Magnotia is already there when you need it, especially useful if you said yes to morning triage. Uses your OS's standard autostart. No background tricks, no telemetry.
|
||||||
</p>
|
</p>
|
||||||
<p class="text-[11px] text-text-tertiary mt-3">You can change this any time in Settings.</p>
|
<p class="text-[11px] text-text-tertiary mt-3">You can change this any time in Settings.</p>
|
||||||
<div class="flex items-center justify-center gap-3 mt-6">
|
<div class="flex items-center justify-center gap-3 mt-6">
|
||||||
@@ -264,7 +264,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<p class="text-xs text-text-tertiary mt-2">{downloadProgress}%</p>
|
<p class="text-xs text-text-tertiary mt-2">{downloadProgress}%</p>
|
||||||
{#if estimatedMinutes > 2}
|
{#if estimatedMinutes > 2}
|
||||||
<p class="text-xs text-text-secondary mt-3">Download in background — this may take a while</p>
|
<p class="text-xs text-text-secondary mt-3">Download in background, this may take a while</p>
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -296,7 +296,7 @@
|
|||||||
{#if models.length > 0}
|
{#if models.length > 0}
|
||||||
<div class="mt-6">
|
<div class="mt-6">
|
||||||
<h3 class="text-xs font-medium text-text-tertiary uppercase tracking-wider mb-3">Pick a model</h3>
|
<h3 class="text-xs font-medium text-text-tertiary uppercase tracking-wider mb-3">Pick a model</h3>
|
||||||
<p class="text-xs text-text-tertiary mb-3">One tap — we handle the rest.</p>
|
<p class="text-xs text-text-tertiary mb-3">One tap, we handle the rest.</p>
|
||||||
<div class="space-y-2">
|
<div class="space-y-2">
|
||||||
{#each models as model, i}
|
{#each models as model, i}
|
||||||
<button
|
<button
|
||||||
@@ -330,7 +330,7 @@
|
|||||||
style="transition-duration: var(--duration-ui)"
|
style="transition-duration: var(--duration-ui)"
|
||||||
onclick={skipSetup}
|
onclick={skipSetup}
|
||||||
>
|
>
|
||||||
Skip setup — I'll configure later
|
Skip setup. I'll configure later
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
|
|||||||
@@ -223,7 +223,7 @@
|
|||||||
candidates.push(trimmed);
|
candidates.push(trimmed);
|
||||||
}
|
}
|
||||||
if (candidates.length === 0) {
|
if (candidates.length === 0) {
|
||||||
vocabularyError = "Nothing to import — paste one term per line or separated by commas.";
|
vocabularyError = "Nothing to import, paste one term per line or separated by commas.";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1033,10 +1033,10 @@
|
|||||||
bind:value={settings.microphoneDevice}
|
bind:value={settings.microphoneDevice}
|
||||||
onfocus={refreshAudioDevices}
|
onfocus={refreshAudioDevices}
|
||||||
>
|
>
|
||||||
<option value="">Auto (recommended) — let Magnotia pick the working mic</option>
|
<option value="">Auto (recommended), let Magnotia pick the working mic</option>
|
||||||
{#each visibleAudioDevices as dev}
|
{#each visibleAudioDevices as dev}
|
||||||
<option value={dev.name} disabled={dev.is_likely_monitor}>
|
<option value={dev.name} disabled={dev.is_likely_monitor}>
|
||||||
{friendlyLabel(dev)}{#if dev.is_default && dev.name !== "default"} (system default){/if}{#if dev.is_likely_monitor} — speaker monitor, skip{/if}
|
{friendlyLabel(dev)}{#if dev.is_default && dev.name !== "default"} (system default){/if}{#if dev.is_likely_monitor}, speaker monitor, skip{/if}
|
||||||
</option>
|
</option>
|
||||||
{/each}
|
{/each}
|
||||||
</select>
|
</select>
|
||||||
@@ -1077,7 +1077,7 @@
|
|||||||
>
|
>
|
||||||
<div class="animate-fade-in">
|
<div class="animate-fade-in">
|
||||||
<p class="text-[12px] text-text-tertiary mb-4">
|
<p class="text-[12px] text-text-tertiary mb-4">
|
||||||
Words and phrases the AI cleanup pass should preserve exactly. Useful for medication names, place names, jargon, names of people in your support network, anything Whisper tends to mishear. Vocabulary is scoped to a profile — switch profiles to swap whole vocabularies.
|
Words and phrases the AI cleanup pass should preserve exactly. Useful for medication names, place names, jargon, names of people in your support network, anything Whisper tends to mishear. Vocabulary is scoped to a profile, switch profiles to swap whole vocabularies.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<!-- Profile selector -->
|
<!-- Profile selector -->
|
||||||
@@ -1123,7 +1123,7 @@
|
|||||||
focus:outline-none focus:border-accent"
|
focus:outline-none focus:border-accent"
|
||||||
/>
|
/>
|
||||||
<textarea
|
<textarea
|
||||||
placeholder="Initial prompt (optional) — extra context Whisper primes on before every session in this profile"
|
placeholder="Initial prompt (optional), extra context Whisper primes on before every session in this profile"
|
||||||
bind:value={newVocabProfilePrompt}
|
bind:value={newVocabProfilePrompt}
|
||||||
class="bg-bg border border-border rounded-lg px-3 py-2 text-[12px] text-text resize-none h-[72px]
|
class="bg-bg border border-border rounded-lg px-3 py-2 text-[12px] text-text resize-none h-[72px]
|
||||||
focus:outline-none focus:border-accent"
|
focus:outline-none focus:border-accent"
|
||||||
@@ -1164,7 +1164,7 @@
|
|||||||
<div class="mb-5">
|
<div class="mb-5">
|
||||||
<p class="text-[10px] font-medium text-text-tertiary uppercase tracking-wider mb-2">Initial Prompt</p>
|
<p class="text-[10px] font-medium text-text-tertiary uppercase tracking-wider mb-2">Initial Prompt</p>
|
||||||
<p class="text-[11px] text-text-tertiary mb-2">
|
<p class="text-[11px] text-text-tertiary mb-2">
|
||||||
Passed to Whisper before every transcription in this profile. Used as a biasing prompt — keep it short and topic-specific (names, domain terms, tone cues).
|
Passed to Whisper before every transcription in this profile. Used as a biasing prompt, keep it short and topic-specific (names, domain terms, tone cues).
|
||||||
</p>
|
</p>
|
||||||
<textarea
|
<textarea
|
||||||
bind:value={initialPromptDraft}
|
bind:value={initialPromptDraft}
|
||||||
@@ -1181,7 +1181,7 @@
|
|||||||
onclick={saveInitialPrompt}
|
onclick={saveInitialPrompt}
|
||||||
class="text-[11px] text-accent hover:text-accent-hover"
|
class="text-[11px] text-accent hover:text-accent-hover"
|
||||||
>Save prompt</button>
|
>Save prompt</button>
|
||||||
<span class="text-[11px] text-text-tertiary">Unsaved changes — saves on blur.</span>
|
<span class="text-[11px] text-text-tertiary">Unsaved changes, saves on blur.</span>
|
||||||
{:else}
|
{:else}
|
||||||
<span class="text-[11px] text-text-tertiary">Saved.</span>
|
<span class="text-[11px] text-text-tertiary">Saved.</span>
|
||||||
{/if}
|
{/if}
|
||||||
@@ -1228,7 +1228,7 @@
|
|||||||
<div class="p-3 bg-bg-input border border-border-subtle rounded-lg animate-fade-in">
|
<div class="p-3 bg-bg-input border border-border-subtle rounded-lg animate-fade-in">
|
||||||
<textarea
|
<textarea
|
||||||
bind:value={bulkVocabText}
|
bind:value={bulkVocabText}
|
||||||
placeholder="Paste terms — one per line, or separated by commas. Duplicates are skipped automatically."
|
placeholder="Paste terms, one per line, or separated by commas. Duplicates are skipped automatically."
|
||||||
rows="4"
|
rows="4"
|
||||||
disabled={bulkVocabBusy}
|
disabled={bulkVocabBusy}
|
||||||
class="w-full bg-bg border border-border rounded-lg px-3 py-2 text-[13px] text-text font-mono
|
class="w-full bg-bg border border-border rounded-lg px-3 py-2 text-[13px] text-text font-mono
|
||||||
@@ -1446,7 +1446,7 @@
|
|||||||
<p class="text-[11px] text-text-tertiary mt-2">
|
<p class="text-[11px] text-text-tertiary mt-2">
|
||||||
{settings.engine === "whisper"
|
{settings.engine === "whisper"
|
||||||
? "Whisper with the currently shipped English-only models in this build"
|
? "Whisper with the currently shipped English-only models in this build"
|
||||||
: "Parakeet CTC 0.6B — English-only, fast when the model is installed"}
|
: "Parakeet CTC 0.6B. English-only, fast when the model is installed"}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -1496,7 +1496,7 @@
|
|||||||
{:else}
|
{:else}
|
||||||
<div class="mb-6">
|
<div class="mb-6">
|
||||||
<p class="text-[10px] font-medium text-text-tertiary uppercase tracking-wider mb-2">Parakeet Model</p>
|
<p class="text-[10px] font-medium text-text-tertiary uppercase tracking-wider mb-2">Parakeet Model</p>
|
||||||
<p class="text-[11px] text-text-tertiary mb-3">Parakeet CTC 0.6B (int8) — ~613MB, near-instant transcription</p>
|
<p class="text-[11px] text-text-tertiary mb-3">Parakeet CTC 0.6B (int8). ~613MB, near-instant transcription</p>
|
||||||
|
|
||||||
<div class="flex items-center gap-2">
|
<div class="flex items-center gap-2">
|
||||||
{#if parakeetOk}
|
{#if parakeetOk}
|
||||||
@@ -1815,13 +1815,13 @@
|
|||||||
/>
|
/>
|
||||||
<p class="text-[11px] text-text-tertiary mt-2">
|
<p class="text-[11px] text-text-tertiary mt-2">
|
||||||
{#if settings.llmPromptPreset === "email"}
|
{#if settings.llmPromptPreset === "email"}
|
||||||
Formats output as an email paragraph — tight sentences, no markdown, no auto-added greeting or signoff.
|
Formats output as an email paragraph, tight sentences, no markdown, no auto-added greeting or signoff.
|
||||||
{:else if settings.llmPromptPreset === "notes"}
|
{:else if settings.llmPromptPreset === "notes"}
|
||||||
Formats action items as a bullet list led by imperative verbs; keeps prose informational sentences as prose.
|
Formats action items as a bullet list led by imperative verbs; keeps prose informational sentences as prose.
|
||||||
{:else if settings.llmPromptPreset === "code"}
|
{:else if settings.llmPromptPreset === "code"}
|
||||||
Preserves technical terms, variable names, file paths, and symbols exactly as spoken. No translation of identifiers.
|
Preserves technical terms, variable names, file paths, and symbols exactly as spoken. No translation of identifiers.
|
||||||
{:else}
|
{:else}
|
||||||
No preset — the active profile's prompt governs tone alone.
|
No preset, the active profile's prompt governs tone alone.
|
||||||
{/if}
|
{/if}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
@@ -1955,7 +1955,7 @@
|
|||||||
<div class="flex-1 min-w-0">
|
<div class="flex-1 min-w-0">
|
||||||
<p class="text-[13px] text-text leading-tight">Launch Magnotia at login</p>
|
<p class="text-[13px] text-text leading-tight">Launch Magnotia at login</p>
|
||||||
<p class="text-[11px] text-text-tertiary mt-0.5 leading-snug">
|
<p class="text-[11px] text-text-tertiary mt-0.5 leading-snug">
|
||||||
So Magnotia is already there at the start of the day. Uses your OS's standard autostart — no background tricks.
|
So Magnotia is already there at the start of the day. Uses your OS's standard autostart, no background tricks.
|
||||||
</p>
|
</p>
|
||||||
{#if autostartSyncing}
|
{#if autostartSyncing}
|
||||||
<p class="text-[11px] text-text-tertiary mt-1">Updating…</p>
|
<p class="text-[11px] text-text-tertiary mt-1">Updating…</p>
|
||||||
@@ -2117,7 +2117,7 @@
|
|||||||
<Toggle
|
<Toggle
|
||||||
bind:checked={settings.meetingAutoCapture}
|
bind:checked={settings.meetingAutoCapture}
|
||||||
label="Remind me when a meeting starts"
|
label="Remind me when a meeting starts"
|
||||||
description="Toasts when a matching app appears in the process list. You still hit the hotkey — Magnotia never records on its own."
|
description="Toasts when a matching app appears in the process list. You still hit the hotkey. Magnotia never records on its own."
|
||||||
/>
|
/>
|
||||||
{#if settings.meetingAutoCapture}
|
{#if settings.meetingAutoCapture}
|
||||||
<div class="ml-[50px] mt-2 mb-1 animate-fade-in">
|
<div class="ml-[50px] mt-2 mb-1 animate-fade-in">
|
||||||
@@ -2139,7 +2139,7 @@
|
|||||||
<Toggle
|
<Toggle
|
||||||
bind:checked={settings.soundCues}
|
bind:checked={settings.soundCues}
|
||||||
label="Sound cues on start / stop / complete"
|
label="Sound cues on start / stop / complete"
|
||||||
description="Short synthesised tones for eyes-off feedback. Synthesised locally via Web Audio — no assets bundled."
|
description="Short synthesised tones for eyes-off feedback. Synthesised locally via Web Audio, no assets bundled."
|
||||||
/>
|
/>
|
||||||
{#if settings.soundCues}
|
{#if settings.soundCues}
|
||||||
<div class="ml-[50px] mt-2 mb-1 animate-fade-in flex items-center gap-3">
|
<div class="ml-[50px] mt-2 mb-1 animate-fade-in flex items-center gap-3">
|
||||||
@@ -2296,11 +2296,11 @@
|
|||||||
|
|
||||||
<div class="space-y-1.5">
|
<div class="space-y-1.5">
|
||||||
{#each [
|
{#each [
|
||||||
"100% offline — all processing on your machine",
|
"100% offline, all processing on your machine",
|
||||||
"No Python required — compiled Whisper engine",
|
"No Python required, compiled Whisper engine",
|
||||||
"No cloud — audio never leaves your computer",
|
"No cloud, audio never leaves your computer",
|
||||||
"No accounts — no sign-up, no tracking",
|
"No accounts, no sign-up, no tracking",
|
||||||
"No telemetry — zero data collection",
|
"No telemetry, zero data collection",
|
||||||
] as item}
|
] as item}
|
||||||
<div class="flex items-start gap-2">
|
<div class="flex items-start gap-2">
|
||||||
<Check class="w-3.5 h-3.5 text-success mt-0.5 flex-shrink-0" />
|
<Check class="w-3.5 h-3.5 text-success mt-0.5 flex-shrink-0" />
|
||||||
@@ -2315,7 +2315,7 @@
|
|||||||
<div class="mt-6 pt-5 border-t border-border-subtle">
|
<div class="mt-6 pt-5 border-t border-border-subtle">
|
||||||
<p class="text-[10px] font-medium text-text-tertiary uppercase tracking-wider mb-2">Diagnostics</p>
|
<p class="text-[10px] font-medium text-text-tertiary uppercase tracking-wider mb-2">Diagnostics</p>
|
||||||
<p class="text-[11px] text-text-tertiary mb-3">
|
<p class="text-[11px] text-text-tertiary mb-3">
|
||||||
If something goes wrong, generate a diagnostic report to share with the developer. The report contains your settings, recent errors, any crash dumps, and the tail of the log file. Nothing is sent automatically — you preview it first, then choose copy or save.
|
If something goes wrong, generate a diagnostic report to share with the developer. The report contains your settings, recent errors, any crash dumps, and the tail of the log file. Nothing is sent automatically, you preview it first, then choose copy or save.
|
||||||
</p>
|
</p>
|
||||||
<div class="flex gap-2 mb-3">
|
<div class="flex gap-2 mb-3">
|
||||||
<button
|
<button
|
||||||
|
|||||||
@@ -117,7 +117,7 @@
|
|||||||
<p class="text-[12px] text-text-secondary">Nothing in the list.</p>
|
<p class="text-[12px] text-text-secondary">Nothing in the list.</p>
|
||||||
{:else}
|
{:else}
|
||||||
<p class="text-[11px] text-text-tertiary mb-3">
|
<p class="text-[11px] text-text-tertiary mb-3">
|
||||||
These are still here. Naming them silences the loop — you don't have to act now.
|
These are still here. Naming them silences the loop, you don't have to act now.
|
||||||
</p>
|
</p>
|
||||||
<ul class="flex flex-col gap-1">
|
<ul class="flex flex-col gap-1">
|
||||||
{#each openLoops.slice(0, 12) as task (task.id)}
|
{#each openLoops.slice(0, 12) as task (task.id)}
|
||||||
@@ -146,7 +146,7 @@
|
|||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<span class="font-medium text-text">Pick a closing line.</span>
|
<span class="font-medium text-text">Pick a closing line.</span>
|
||||||
Say it out loud when you're ready — something like "I'm done for today."
|
Say it out loud when you're ready, something like "I'm done for today."
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<span class="font-medium text-text">Let it rest.</span>
|
<span class="font-medium text-text">Let it rest.</span>
|
||||||
|
|||||||
@@ -120,7 +120,7 @@
|
|||||||
// rot over time.
|
// rot over time.
|
||||||
type EnergyOption = { value: EnergyLevel | null; label: string };
|
type EnergyOption = { value: EnergyLevel | null; label: string };
|
||||||
const energyOptions: EnergyOption[] = [
|
const energyOptions: EnergyOption[] = [
|
||||||
{ value: null, label: "—" },
|
{ value: null, label: "Any" },
|
||||||
{ value: "high", label: "High" },
|
{ value: "high", label: "High" },
|
||||||
{ value: "medium", label: "Med" },
|
{ value: "medium", label: "Med" },
|
||||||
{ value: "brain_dead", label: "Low" },
|
{ value: "brain_dead", label: "Low" },
|
||||||
@@ -351,7 +351,7 @@
|
|||||||
style="transition-duration: var(--duration-ui)"
|
style="transition-duration: var(--duration-ui)"
|
||||||
onclick={toggleMatchMyEnergy}
|
onclick={toggleMatchMyEnergy}
|
||||||
aria-pressed={settings.matchMyEnergy}
|
aria-pressed={settings.matchMyEnergy}
|
||||||
aria-label={settings.matchMyEnergy ? 'Match my energy is on — click to turn off' : 'Match my energy is off — click to turn on'}
|
aria-label={settings.matchMyEnergy ? 'Match my energy is on, click to turn off' : 'Match my energy is off, click to turn on'}
|
||||||
title="Sort matching tasks to the top (unset counts as Medium)"
|
title="Sort matching tasks to the top (unset counts as Medium)"
|
||||||
>
|
>
|
||||||
<Zap size={12} aria-hidden="true" />
|
<Zap size={12} aria-hidden="true" />
|
||||||
|
|||||||
@@ -133,7 +133,7 @@
|
|||||||
const msg = err instanceof Error ? err.message : String(err);
|
const msg = err instanceof Error ? err.message : String(err);
|
||||||
toasts.error(
|
toasts.error(
|
||||||
"Hotkey not registered",
|
"Hotkey not registered",
|
||||||
`${hotkey} — ${msg}. Reverted to ${registeredHotkey ?? "previous value"}.`,
|
`${hotkey}. ${msg}. Reverted to ${registeredHotkey ?? "previous value"}.`,
|
||||||
);
|
);
|
||||||
// Revert the in-memory setting to the last successfully-registered hotkey
|
// Revert the in-memory setting to the last successfully-registered hotkey
|
||||||
// so the UI does not lie about what is actually bound.
|
// so the UI does not lie about what is actually bound.
|
||||||
|
|||||||
Reference in New Issue
Block a user