agent: components — add accessibility controls panel

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
jake
2026-03-21 10:46:53 +00:00
parent ea99b4285d
commit 5ba4606de9

View File

@@ -0,0 +1,107 @@
<script>
import { getPreferences, updateAccessibility } from '$lib/stores/preferences.svelte.js';
import Toggle from '$lib/components/Toggle.svelte';
import SegmentedButton from '$lib/components/SegmentedButton.svelte';
const prefs = getPreferences();
const fontOptions = [
{ id: 'lexend', label: 'Lexend' },
{ id: 'atkinson', label: 'Atkinson' },
{ id: 'opendyslexic', label: 'OpenDyslexic' },
];
let bionicChecked = $state(prefs.accessibility.bionicReading || false);
let motionValue = $state(
prefs.accessibility.reduceMotion === 'on' ? 'On'
: prefs.accessibility.reduceMotion === 'off' ? 'Off'
: 'System'
);
$effect(() => {
if (bionicChecked !== prefs.accessibility.bionicReading) {
updateAccessibility({ bionicReading: bionicChecked });
}
});
$effect(() => {
const mapped = motionValue === 'On' ? 'on' : motionValue === 'Off' ? 'off' : 'system';
if (mapped !== prefs.accessibility.reduceMotion) {
updateAccessibility({ reduceMotion: mapped });
}
});
</script>
<div class="flex flex-col gap-5">
<!-- Font family -->
<div class="flex flex-col gap-2">
<p class="text-[12px] text-text-secondary font-medium">Body font</p>
<div class="flex gap-2">
{#each fontOptions as opt}
<button
class="flex-1 px-3 py-2 rounded-lg text-[12px] border
{prefs.accessibility.fontFamily === opt.id
? 'border-accent bg-accent-subtle text-text'
: 'border-border-subtle text-text-secondary hover:border-border'}"
style="font-family: {opt.id === 'lexend' ? "'Lexend'" : opt.id === 'atkinson' ? "'Atkinson Hyperlegible Next'" : "'OpenDyslexic'"}; transition-duration: var(--duration-ui)"
onclick={() => updateAccessibility({ fontFamily: opt.id })}
>
{opt.label}
</button>
{/each}
</div>
</div>
<!-- Font size -->
<div class="flex flex-col gap-1.5">
<div class="flex justify-between">
<p class="text-[12px] text-text-secondary font-medium">Font size</p>
<span class="text-[11px] text-text-tertiary">{prefs.accessibility.fontSize}px</span>
</div>
<input type="range" min="16" max="24" step="1" value={prefs.accessibility.fontSize}
oninput={(e) => updateAccessibility({ fontSize: Number(e.target.value) })}
class="w-full accent-accent" />
</div>
<!-- Letter spacing -->
<div class="flex flex-col gap-1.5">
<div class="flex justify-between">
<p class="text-[12px] text-text-secondary font-medium">Letter spacing</p>
<span class="text-[11px] text-text-tertiary">{prefs.accessibility.letterSpacing.toFixed(2)}em</span>
</div>
<input type="range" min="0" max="0.15" step="0.01" value={prefs.accessibility.letterSpacing}
oninput={(e) => updateAccessibility({ letterSpacing: Number(e.target.value) })}
class="w-full accent-accent" />
</div>
<!-- Line height -->
<div class="flex flex-col gap-1.5">
<div class="flex justify-between">
<p class="text-[12px] text-text-secondary font-medium">Line height</p>
<span class="text-[11px] text-text-tertiary">{prefs.accessibility.lineHeight.toFixed(1)}</span>
</div>
<input type="range" min="1.3" max="2.2" step="0.1" value={prefs.accessibility.lineHeight}
oninput={(e) => updateAccessibility({ lineHeight: Number(e.target.value) })}
class="w-full accent-accent" />
</div>
<!-- Transcript font size -->
<div class="flex flex-col gap-1.5">
<div class="flex justify-between">
<p class="text-[12px] text-text-secondary font-medium">Transcript font size</p>
<span class="text-[11px] text-text-tertiary">{prefs.accessibility.transcriptSize}px</span>
</div>
<input type="range" min="16" max="24" step="1" value={prefs.accessibility.transcriptSize}
oninput={(e) => updateAccessibility({ transcriptSize: Number(e.target.value) })}
class="w-full accent-accent" />
</div>
<!-- Bionic reading -->
<Toggle label="Bionic reading" description="Bold the first few characters of each word for faster scanning" bind:checked={bionicChecked} />
<!-- Reduce motion -->
<div class="flex flex-col gap-2">
<p class="text-[12px] text-text-secondary font-medium">Reduce motion</p>
<SegmentedButton options={['System', 'On', 'Off']} bind:value={motionValue} size="small" />
</div>
</div>