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">