mirror of
https://github.com/snapotter-hq/SnapOtter.git
synced 2026-08-03 07:46:42 +02:00
fix(a11y): focus indicators meet the 3:1 non-text contrast bar (#574)
Fixes #568. Adds a real --color-ring token (ink orange #A85518 light / #F0A766 dark) and sweeps all 57 focus-indicator occurrences onto it: soft opacity rings blended to 1.2-1.7:1, border-only indicators sat at 2.6-3.0:1, and four focus:ring-ring sites referenced a token that never existed. Sponsor button keeps pink via pink-700; range sliders and the file list gain their missing keyboard indicators; landing skip link and form borders hardened; the palette contrast guard pins the ring at 3:1 in both themes.
This commit is contained in:
@@ -45,7 +45,7 @@ function renderIcon(iconName: string): string {
|
||||
id="hero-tool-search"
|
||||
autocomplete="off"
|
||||
placeholder={t(locale, "home.hero.searchPlaceholder")}
|
||||
class="w-full rounded-2xl border border-border bg-surface py-4 pe-4 ps-12 text-base shadow-sm outline-none transition-all placeholder:text-muted focus:border-primary focus:shadow-md"
|
||||
class="w-full rounded-2xl border border-border bg-surface py-4 pe-4 ps-12 text-base shadow-sm outline-none transition-all placeholder:text-muted focus:border-primary-ink focus:shadow-md"
|
||||
aria-label={t(locale, "home.hero.searchPlaceholder")}
|
||||
aria-expanded="false"
|
||||
aria-controls="hero-search-results"
|
||||
|
||||
@@ -220,7 +220,7 @@ const safeStringsJson = JSON.stringify(toolGridStrings).replace(/</g, "\\u003c")
|
||||
autocomplete="off"
|
||||
aria-label={t(locale, "home.toolGrid.searchLabel")}
|
||||
placeholder={t(locale, "home.toolGrid.searchPlaceholder")}
|
||||
class="h-13 w-full rounded-lg border border-border bg-surface py-3 ps-12 pe-12 text-base text-foreground outline-none transition-colors placeholder:text-muted focus:border-primary"
|
||||
class="h-13 w-full rounded-lg border border-border bg-surface py-3 ps-12 pe-12 text-base text-foreground outline-none transition-colors placeholder:text-muted focus:border-primary-ink"
|
||||
/>
|
||||
<button
|
||||
id="tool-command-clear"
|
||||
|
||||
@@ -103,22 +103,22 @@ const subjects = [
|
||||
>
|
||||
<div>
|
||||
<label for="name" class="block text-sm font-medium">{t(locale, "contact.form.name")}</label>
|
||||
<input type="text" id="name" name="name" required class="mt-1.5 w-full rounded-lg border border-border bg-background px-4 py-2.5 text-sm transition-colors focus:border-primary focus:outline-none" />
|
||||
<input type="text" id="name" name="name" required class="mt-1.5 w-full rounded-lg border border-border bg-background px-4 py-2.5 text-sm transition-colors focus:border-primary-ink focus:outline-none" />
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label for="email" class="block text-sm font-medium">{t(locale, "contact.form.email")}</label>
|
||||
<input type="email" id="email" name="email" required class="mt-1.5 w-full rounded-lg border border-border bg-background px-4 py-2.5 text-sm transition-colors focus:border-primary focus:outline-none" />
|
||||
<input type="email" id="email" name="email" required class="mt-1.5 w-full rounded-lg border border-border bg-background px-4 py-2.5 text-sm transition-colors focus:border-primary-ink focus:outline-none" />
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label for="company" class="block text-sm font-medium">{t(locale, "contact.form.company")}</label>
|
||||
<input type="text" id="company" name="company" class="mt-1.5 w-full rounded-lg border border-border bg-background px-4 py-2.5 text-sm transition-colors focus:border-primary focus:outline-none" />
|
||||
<input type="text" id="company" name="company" class="mt-1.5 w-full rounded-lg border border-border bg-background px-4 py-2.5 text-sm transition-colors focus:border-primary-ink focus:outline-none" />
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label for="subject" class="block text-sm font-medium">{t(locale, "contact.form.subject")}</label>
|
||||
<select id="subject" name="subject" required class="mt-1.5 w-full rounded-lg border border-border bg-background px-4 py-2.5 text-sm transition-colors focus:border-primary focus:outline-none">
|
||||
<select id="subject" name="subject" required class="mt-1.5 w-full rounded-lg border border-border bg-background px-4 py-2.5 text-sm transition-colors focus:border-primary-ink focus:outline-none">
|
||||
<option value="" disabled selected>{t(locale, "contact.form.selectTopic")}</option>
|
||||
{subjects.map((s) => (
|
||||
<option value={s}>{s}</option>
|
||||
@@ -128,7 +128,7 @@ const subjects = [
|
||||
|
||||
<div>
|
||||
<label for="message" class="block text-sm font-medium">{t(locale, "contact.form.message")}</label>
|
||||
<textarea id="message" name="message" rows={5} required class="mt-1.5 w-full rounded-lg border border-border bg-background px-4 py-2.5 text-sm transition-colors focus:border-primary focus:outline-none resize-none"></textarea>
|
||||
<textarea id="message" name="message" rows={5} required class="mt-1.5 w-full rounded-lg border border-border bg-background px-4 py-2.5 text-sm transition-colors focus:border-primary-ink focus:outline-none resize-none"></textarea>
|
||||
</div>
|
||||
|
||||
<button type="submit" class="btn-primary w-full rounded-lg px-6 py-3 text-sm font-semibold">
|
||||
|
||||
@@ -163,7 +163,7 @@ const collectionJsonLd = {
|
||||
type="text"
|
||||
autocomplete="off"
|
||||
placeholder={searchPlaceholder}
|
||||
class="w-full rounded-xl border border-border bg-surface py-2.5 pe-4 ps-11 text-sm outline-none transition-colors placeholder:text-muted focus:border-primary"
|
||||
class="w-full rounded-xl border border-border bg-surface py-2.5 pe-4 ps-11 text-sm outline-none transition-colors placeholder:text-muted focus:border-primary-ink"
|
||||
/>
|
||||
</div>
|
||||
<div class="mt-3 flex flex-wrap gap-2">
|
||||
|
||||
@@ -351,6 +351,8 @@ code, pre, kbd {
|
||||
}
|
||||
.skip-link:focus {
|
||||
top: 0;
|
||||
outline: 2px solid var(--color-primary-ink-strong);
|
||||
outline-offset: 2px;
|
||||
}
|
||||
|
||||
/* ─── STEP CONNECTOR (How It Works) ─── */
|
||||
|
||||
Reference in New Issue
Block a user