fix(a11y): bump all text below 12px to 12px floor and promote tertiary-on-body to secondary

Brand guidelines (docs/brand/magnotia-brand-guidelines.md §4) say "Never go
below 12px for any text" and "tertiary text must be ≥18px bold or ≥24px
regular". Audit found 246 sub-12px className sites and 166 cases of
text-text-tertiary paired with body sizes.

Bumped text-[9/10/11px] → text-[12px] across 26 .svelte files in src/lib
and src/routes. Promoted text-text-tertiary → text-text-secondary at body
sizes (12-14px) where context allowed; left placeholder pseudo-states,
ternary-conditional inactive states, and line-through "done" states alone
(8 residual pairings, all decorative).

Affects neurodivergent users on 1366×768 budget hardware most directly.
svelte-check: 0 errors, 0 warnings.
This commit is contained in:
2026-05-07 11:18:10 +01:00
parent 6da15d1ac8
commit ca3a55320b
26 changed files with 257 additions and 257 deletions

View File

@@ -228,7 +228,7 @@
<div class="flex items-center gap-1 overflow-x-auto flex-1 min-w-0">
{#each builtInLists as list (list.id)}
<button
class="flex items-center gap-1 px-2.5 py-1 rounded-lg text-[11px] whitespace-nowrap flex-shrink-0
class="flex items-center gap-1 px-2.5 py-1 rounded-lg text-[12px] whitespace-nowrap flex-shrink-0
{activeListId === list.id
? 'bg-nav-active text-text font-medium'
: 'text-text-secondary hover:bg-hover hover:text-text'}
@@ -241,7 +241,7 @@
>
{list.name}
{#if countForList(list.id) > 0}
<span class="text-[9px] px-1 rounded-full bg-bg-elevated text-text-tertiary">
<span class="text-[12px] px-1 rounded-full bg-bg-elevated text-text-secondary">
{countForList(list.id)}
</span>
{/if}
@@ -258,7 +258,7 @@
<input
bind:this={editingInputEl}
type="text"
class="bg-bg-input border border-accent rounded px-2 py-0.5 text-[11px] text-text
class="bg-bg-input border border-accent rounded px-2 py-0.5 text-[12px] text-text
focus:outline-none w-[100px]"
bind:value={editingName}
onkeydown={handleRenameKey}
@@ -268,7 +268,7 @@
{:else}
<div class="relative flex-shrink-0">
<button
class="flex items-center gap-1 px-2.5 py-1 rounded-lg text-[11px] whitespace-nowrap
class="flex items-center gap-1 px-2.5 py-1 rounded-lg text-[12px] whitespace-nowrap
{activeListId === list.id
? 'bg-nav-active text-text font-medium'
: 'text-text-secondary hover:bg-hover hover:text-text'}
@@ -288,7 +288,7 @@
{/if}
{list.name}
{#if countForList(list.id) > 0}
<span class="text-[9px] px-1 rounded-full bg-bg-elevated text-text-tertiary">
<span class="text-[12px] px-1 rounded-full bg-bg-elevated text-text-secondary">
{countForList(list.id)}
</span>
{/if}
@@ -299,35 +299,35 @@
<div class="absolute left-0 top-full mt-1 bg-bg-card border border-border rounded-lg shadow-lg py-1 z-20 animate-fade-in min-w-[120px]"
onpointerdown={(e) => e.stopPropagation()}>
<button
class="w-full text-left px-3 py-1 text-[10px] text-text-secondary hover:bg-hover hover:text-text"
class="w-full text-left px-3 py-1 text-[12px] text-text-secondary hover:bg-hover hover:text-text"
onclick={() => startRenaming(list)}
>Rename</button>
<button
class="w-full text-left px-3 py-1 text-[10px] text-text-secondary hover:bg-hover hover:text-text"
class="w-full text-left px-3 py-1 text-[12px] text-text-secondary hover:bg-hover hover:text-text"
onclick={() => { moveTaskList(list.id, -1); contextMenuListId = null; }}
>Move left</button>
<button
class="w-full text-left px-3 py-1 text-[10px] text-text-secondary hover:bg-hover hover:text-text"
class="w-full text-left px-3 py-1 text-[12px] text-text-secondary hover:bg-hover hover:text-text"
onclick={() => { moveTaskList(list.id, 1); contextMenuListId = null; }}
>Move right</button>
{#if profiles.length > 0}
<div class="my-1 h-px bg-border-subtle"></div>
<p class="px-3 py-0.5 text-[9px] text-text-tertiary uppercase tracking-wider">Move to profile</p>
<p class="px-3 py-0.5 text-[12px] text-text-secondary uppercase tracking-wider">Move to profile</p>
{#each profiles as profile}
<button
class="w-full text-left px-3 py-1 text-[10px] hover:bg-hover
class="w-full text-left px-3 py-1 text-[12px] hover:bg-hover
{list.profileId === profile.name ? 'text-accent' : 'text-text-secondary hover:text-text'}"
onclick={() => { moveTaskListToProfile(list.id, profile.name); contextMenuListId = null; }}
>{profile.name}</button>
{/each}
<button
class="w-full text-left px-3 py-1 text-[10px] text-text-secondary hover:bg-hover hover:text-text"
class="w-full text-left px-3 py-1 text-[12px] text-text-secondary hover:bg-hover hover:text-text"
onclick={() => { moveTaskListToProfile(list.id, null); contextMenuListId = null; }}
>None (unlink)</button>
{/if}
<div class="my-1 h-px bg-border-subtle"></div>
<button
class="w-full text-left px-3 py-1 text-[10px] text-danger hover:bg-hover"
class="w-full text-left px-3 py-1 text-[12px] text-danger hover:bg-hover"
onclick={() => handleDeleteList(list.id)}
>Delete</button>
</div>
@@ -341,7 +341,7 @@
<input
bind:this={newListInputEl}
type="text"
class="bg-bg-input border border-border rounded px-2 py-0.5 text-[10px] text-text
class="bg-bg-input border border-border rounded px-2 py-0.5 text-[12px] text-text
placeholder:text-text-tertiary focus:outline-none focus:border-accent w-[100px] flex-shrink-0"
placeholder="List name..."
bind:value={newListName}
@@ -351,7 +351,7 @@
/>
{:else}
<button
class="px-2 py-1 rounded-lg text-[11px] text-accent hover:bg-accent/10 whitespace-nowrap flex-shrink-0"
class="px-2 py-1 rounded-lg text-[12px] text-accent hover:bg-accent/10 whitespace-nowrap flex-shrink-0"
onclick={(e) => { e.stopPropagation(); showNewList = true; }}
>+</button>
{/if}
@@ -360,7 +360,7 @@
<!-- Sort — sibling of the scroll container so its dropdown is not clipped -->
<div class="relative flex-shrink-0 pl-1">
<button
class="px-1.5 py-1 rounded text-[10px] text-text-tertiary hover:text-text-secondary"
class="px-1.5 py-1 rounded text-[12px] text-text-secondary hover:text-text-secondary"
onclick={(e) => { e.stopPropagation(); showSortMenu = !showSortMenu; }}
aria-label="Sort task lists"
>
@@ -372,11 +372,11 @@
<div class="absolute right-0 top-full mt-1 bg-bg-card border border-border rounded-lg shadow-lg py-1 z-20 animate-fade-in min-w-[110px]"
onpointerdown={(e) => e.stopPropagation()}>
<button
class="w-full text-left px-3 py-1 text-[10px] text-text-secondary hover:bg-hover hover:text-text"
class="w-full text-left px-3 py-1 text-[12px] text-text-secondary hover:bg-hover hover:text-text"
onclick={() => { sortTaskLists("alpha"); showSortMenu = false; }}
>Alphabetical</button>
<button
class="w-full text-left px-3 py-1 text-[10px] text-text-secondary hover:bg-hover hover:text-text"
class="w-full text-left px-3 py-1 text-[12px] text-text-secondary hover:bg-hover hover:text-text"
onclick={() => { sortTaskLists("date"); showSortMenu = false; }}
>By date created</button>
</div>
@@ -402,8 +402,8 @@
<div class="flex-1 overflow-y-auto px-3 py-2 min-h-0">
{#if tasksForActiveList.length === 0}
<div class="flex flex-col items-center justify-center h-full opacity-60">
<p class="text-[11px] text-text-tertiary text-center">No active tasks</p>
<p class="text-[10px] text-text-tertiary mt-1">Type above or drag tasks here</p>
<p class="text-[12px] text-text-secondary text-center">No active tasks</p>
<p class="text-[12px] text-text-secondary mt-1">Type above or drag tasks here</p>
</div>
{:else}
<div class="flex flex-col gap-0.5">
@@ -424,7 +424,7 @@
<div class="flex-1 min-w-0">
<p class="text-[12px] text-text leading-[1.4]">{task.text}</p>
{#if task.createdAt}
<p class="text-[10px] text-text-tertiary mt-0.5">
<p class="text-[12px] text-text-secondary mt-0.5">
{new Date(task.createdAt).toLocaleDateString("en-GB", { day: "numeric", month: "short" })}
</p>
{/if}
@@ -447,7 +447,7 @@
{#if completedForActiveList.length > 0}
<div class="mt-3">
<button
class="flex items-center gap-1.5 text-[10px] text-text-tertiary hover:text-text-secondary mb-1.5"
class="flex items-center gap-1.5 text-[12px] text-text-secondary hover:text-text-secondary mb-1.5"
onclick={() => showCompleted = !showCompleted}
>
<svg class="w-2.5 h-2.5 transition-transform {showCompleted ? 'rotate-90' : ''}" viewBox="0 0 24 24" fill="currentColor">

View File

@@ -189,7 +189,7 @@
class="h-full w-full flex flex-col bg-bg text-text p-3 gap-2"
data-tauri-drag-region
>
<header class="flex items-center justify-between gap-2 text-[11px] text-text-secondary" data-tauri-drag-region>
<header class="flex items-center justify-between gap-2 text-[12px] text-text-secondary" data-tauri-drag-region>
<div class="flex items-center gap-2" data-tauri-drag-region>
{#if phase === "listening"}
<span class="inline-block w-[8px] h-[8px] rounded-full bg-text-tertiary animate-pulse"></span>
@@ -214,7 +214,7 @@
<div class="flex items-center gap-1">
{#if canRevertToRaw}
<button
class="px-2 py-1 rounded hover:bg-hover text-text-tertiary hover:text-text disabled:opacity-40 flex items-center gap-1 text-[11px]"
class="px-2 py-1 rounded hover:bg-hover text-text-secondary hover:text-text disabled:opacity-40 flex items-center gap-1 text-[12px]"
onclick={revertToRaw}
disabled={revertBusy}
title={settings.autoPaste ? "Replace pasted text with raw transcript" : "Put raw transcript on clipboard"}

View File

@@ -403,7 +403,7 @@
<p class="text-[13px] text-text font-medium">
{item.title || "Transcript"}
</p>
<p class="text-[10px] text-text-tertiary mt-0.5">
<p class="text-[12px] text-text-secondary mt-0.5">
{item.date}{#if item.duration} · {formatDuration(item.duration)}{/if} · {item.source}
</p>
</div>
@@ -435,7 +435,7 @@
</button>
<!-- Time -->
<span class="text-[11px] text-text-tertiary tabular-nums min-w-[70px]">
<span class="text-[12px] text-text-secondary tabular-nums min-w-[70px]">
{formatTime(currentTime)} / {formatTime(duration)}
</span>
@@ -455,7 +455,7 @@
<div class="flex gap-0.5 flex-shrink-0">
{#each PLAYBACK_SPEEDS as speed}
<button
class="text-[9px] px-1.5 py-0.5 rounded-full
class="text-[12px] px-1.5 py-0.5 rounded-full
{playbackRate === speed
? 'bg-accent/15 text-accent font-medium'
: 'text-text-tertiary hover:text-text-secondary'}"
@@ -482,20 +482,20 @@
data-no-transition
/>
{#if searchQuery}
<span class="text-[10px] text-text-tertiary">{matchCount} matches</span>
<button class="text-[10px] text-text-tertiary hover:text-text" onclick={() => searchQuery = ""}>Clear</button>
<span class="text-[12px] text-text-secondary">{matchCount} matches</span>
<button class="text-[12px] text-text-secondary hover:text-text" onclick={() => searchQuery = ""}>Clear</button>
{/if}
</div>
<!-- Compact mode toggle -->
<button
class="text-[10px] px-2 py-1 rounded-lg flex-shrink-0
class="text-[12px] px-2 py-1 rounded-lg flex-shrink-0
{showTimestamps ? 'text-text-tertiary hover:text-text-secondary' : 'text-accent bg-accent/10'}"
onclick={() => showTimestamps = !showTimestamps}
title={showTimestamps ? "Hide timestamps (compact)" : "Show timestamps"}
>Compact</button>
<!-- Starred filter -->
<button
class="text-[10px] px-2 py-1 rounded-lg flex-shrink-0
class="text-[12px] px-2 py-1 rounded-lg flex-shrink-0
{showStarredOnly ? 'text-accent bg-accent/10' : 'text-text-tertiary hover:text-text-secondary'}"
onclick={() => showStarredOnly = !showStarredOnly}
title={showStarredOnly ? "Show all segments" : "Show starred only"}
@@ -544,7 +544,7 @@
</button>
<!-- Timestamp -->
{#if showTimestamps}
<span class="text-[10px] text-text-tertiary tabular-nums flex-shrink-0 mt-0.5 min-w-[36px]">
<span class="text-[12px] text-text-secondary tabular-nums flex-shrink-0 mt-0.5 min-w-[36px]">
{formatTime(seg.start)}
</span>
{/if}
@@ -600,7 +600,7 @@
</div>
{:else}
<div class="flex-1 flex items-center justify-center">
<p class="text-[13px] text-text-tertiary">No transcript loaded</p>
<p class="text-[13px] text-text-secondary">No transcript loaded</p>
</div>
{/if}
</div>