fix(a11y): fix WCAG AA contrast and WCAG 2.5.3 failures from third report

- css/tailwind.css: upgrade nav/mobile-nav/theme-toggle text from
  surface-600 (fails 4.5:1) to surface-700 across .site-nav, .nav-dropdown-menu,
  .menu-toggle, .mobile-nav, .mobile-nav-toggle, .theme-toggle, .mobile-theme-toggle
- post.njk: fix AI disclosure details and 'Also on:' span to surface-700
- webmentions.njk: fix summary to surface-700; fix Send button from
  bg-accent-600 (3.18:1) to bg-accent-700 (4.95:1)
- h-card.njk: fix p-adr address and PGP key link to surface-700
- base.njk: fix mobile theme toggle aria-label per WCAG 2.5.3
- post-categories.njk: fix category pills text-accent-700 to text-accent-800
- post-navigation.njk: fix no-OG fallback Previous/Next labels to surface-700

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
svemagie
2026-03-14 16:13:06 +01:00
parent 856792ebbe
commit 7f4e8c93e2
7 changed files with 19 additions and 19 deletions
+2 -2
View File
@@ -47,7 +47,7 @@
<p class="p-job-title text-sm text-surface-600 dark:text-surface-400" itemprop="jobTitle">{{ authorTitle }}</p> <p class="p-job-title text-sm text-surface-600 dark:text-surface-400" itemprop="jobTitle">{{ authorTitle }}</p>
{% endif %} {% endif %}
{# Structured address #} {# Structured address #}
<p class="p-adr h-adr text-sm text-surface-600 dark:text-surface-400" itemprop="address" itemscope itemtype="http://schema.org/PostalAddress"> <p class="p-adr h-adr text-sm text-surface-700 dark:text-surface-300" itemprop="address" itemscope itemtype="http://schema.org/PostalAddress">
{% if authorLocality %} {% if authorLocality %}
<span class="p-locality" itemprop="addressLocality">{{ authorLocality }}</span>{% if authorCountry %}, {% endif %} <span class="p-locality" itemprop="addressLocality">{{ authorLocality }}</span>{% if authorCountry %}, {% endif %}
{% endif %} {% endif %}
@@ -83,7 +83,7 @@
</a> </a>
{% endif %} {% endif %}
{% if authorKeyUrl %} {% if authorKeyUrl %}
<a href="{{ authorKeyUrl }}" class="u-key text-surface-600 dark:text-surface-400 hover:underline" rel="pgpkey"> <a href="{{ authorKeyUrl }}" class="u-key text-surface-700 dark:text-surface-300 hover:underline" rel="pgpkey">
🔐 PGP Key 🔐 PGP Key
</a> </a>
{% endif %} {% endif %}
+2 -2
View File
@@ -39,7 +39,7 @@
</span> </span>
{% else %} {% else %}
<div class="p-4 sm:p-5"> <div class="p-4 sm:p-5">
<span class="text-[10px] sm:text-xs font-semibold uppercase tracking-wide text-surface-600 dark:text-surface-400 block mb-2">&larr; Previous</span> <span class="text-[10px] sm:text-xs font-semibold uppercase tracking-wide text-surface-700 dark:text-surface-300 block mb-2">&larr; Previous</span>
<span class="text-sm sm:text-base font-medium text-surface-900 dark:text-surface-100 group-hover:text-accent-700 dark:group-hover:text-accent-300 line-clamp-2 transition-colors"> <span class="text-sm sm:text-base font-medium text-surface-900 dark:text-surface-100 group-hover:text-accent-700 dark:group-hover:text-accent-300 line-clamp-2 transition-colors">
{{ _prevTitle }} {{ _prevTitle }}
</span> </span>
@@ -85,7 +85,7 @@
</span> </span>
{% else %} {% else %}
<div class="p-4 sm:p-5 text-right"> <div class="p-4 sm:p-5 text-right">
<span class="text-[10px] sm:text-xs font-semibold uppercase tracking-wide text-surface-600 dark:text-surface-400 block mb-2">Next &rarr;</span> <span class="text-[10px] sm:text-xs font-semibold uppercase tracking-wide text-surface-700 dark:text-surface-300 block mb-2">Next &rarr;</span>
<span class="text-sm sm:text-base font-medium text-surface-900 dark:text-surface-100 group-hover:text-accent-700 dark:group-hover:text-accent-300 line-clamp-2 transition-colors"> <span class="text-sm sm:text-base font-medium text-surface-900 dark:text-surface-100 group-hover:text-accent-700 dark:group-hover:text-accent-300 line-clamp-2 transition-colors">
{{ _nextTitle }} {{ _nextTitle }}
</span> </span>
+2 -2
View File
@@ -183,7 +183,7 @@
{# Webmention send form — collapsed by default #} {# Webmention send form — collapsed by default #}
<details class="mt-8"> <details class="mt-8">
<summary class="text-sm font-semibold text-surface-600 dark:text-surface-400 cursor-pointer hover:text-surface-700 dark:hover:text-surface-300 transition-colors list-none [&::-webkit-details-marker]:hidden flex items-center gap-1.5"> <summary class="text-sm font-semibold text-surface-700 dark:text-surface-300 cursor-pointer hover:text-surface-800 dark:hover:text-surface-200 transition-colors list-none [&::-webkit-details-marker]:hidden flex items-center gap-1.5">
<svg class="w-3.5 h-3.5 transition-transform [[open]>&]:rotate-90" fill="none" stroke="currentColor" viewBox="0 0 24 24" aria-hidden="true"> <svg class="w-3.5 h-3.5 transition-transform [[open]>&]:rotate-90" fill="none" stroke="currentColor" viewBox="0 0 24 24" aria-hidden="true">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5l7 7-7 7"/> <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5l7 7-7 7"/>
</svg> </svg>
@@ -206,7 +206,7 @@
> >
<button <button
type="submit" type="submit"
class="px-4 py-2 text-sm font-medium text-white bg-accent-600 hover:bg-accent-700 rounded transition-colors"> class="px-4 py-2 text-sm font-medium text-white bg-accent-700 hover:bg-accent-800 rounded transition-colors">
Send Send
</button> </button>
</form> </form>
@@ -5,12 +5,12 @@
<h3 class="widget-title">Categories</h3> <h3 class="widget-title">Categories</h3>
<div class="flex flex-wrap gap-2"> <div class="flex flex-wrap gap-2">
{% if category is string %} {% if category is string %}
<a href="/categories/{{ category | slugify }}/" class="p-category text-xs px-2 py-1 bg-accent-100 dark:bg-accent-900/30 text-accent-700 dark:text-accent-300 rounded-full hover:bg-accent-200 dark:hover:bg-accent-800 transition-colors"> <a href="/categories/{{ category | slugify }}/" class="p-category text-xs px-2 py-1 bg-accent-100 dark:bg-accent-900/30 text-accent-800 dark:text-accent-300 rounded-full hover:bg-accent-200 dark:hover:bg-accent-800 transition-colors">
{{ category }} {{ category }}
</a> </a>
{% else %} {% else %}
{% for cat in category %} {% for cat in category %}
<a href="/categories/{{ cat | slugify }}/" class="p-category text-xs px-2 py-1 bg-accent-100 dark:bg-accent-900/30 text-accent-700 dark:text-accent-300 rounded-full hover:bg-accent-200 dark:hover:bg-accent-800 transition-colors"> <a href="/categories/{{ cat | slugify }}/" class="p-category text-xs px-2 py-1 bg-accent-100 dark:bg-accent-900/30 text-accent-800 dark:text-accent-300 rounded-full hover:bg-accent-200 dark:hover:bg-accent-800 transition-colors">
{{ cat }} {{ cat }}
</a> </a>
{% endfor %} {% endfor %}
+1 -1
View File
@@ -268,7 +268,7 @@
Dashboard Dashboard
</a> </a>
{# Mobile theme toggle #} {# Mobile theme toggle #}
<button type="button" class="mobile-theme-toggle" aria-label="Toggle dark mode"> <button type="button" class="mobile-theme-toggle" aria-label="Theme: toggle dark mode">
<span class="theme-label">Theme</span> <span class="theme-label">Theme</span>
<span class="theme-icons"> <span class="theme-icons">
<svg class="sun-icon" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true"> <svg class="sun-icon" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true">
+3 -3
View File
@@ -78,8 +78,8 @@ withBlogSidebar: true
{# AI usage disclosure — articles and notes only #} {# AI usage disclosure — articles and notes only #}
{% if '/articles/' in page.url or '/notes/' in page.url %} {% if '/articles/' in page.url or '/notes/' in page.url %}
<details class="mt-4 text-xs text-surface-600 dark:text-surface-400"> <details class="mt-4 text-xs text-surface-700 dark:text-surface-300">
<summary class="cursor-pointer hover:text-surface-600 dark:hover:text-surface-300 list-none flex items-center gap-1.5 [&::-webkit-details-marker]:hidden"> <summary class="cursor-pointer hover:text-surface-700 dark:hover:text-surface-200 list-none flex items-center gap-1.5 [&::-webkit-details-marker]:hidden">
<svg class="w-3.5 h-3.5 flex-shrink-0" fill="none" stroke="currentColor" viewBox="0 0 24 24" aria-hidden="true"> <svg class="w-3.5 h-3.5 flex-shrink-0" fill="none" stroke="currentColor" viewBox="0 0 24 24" aria-hidden="true">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9.75 3.104v5.714a2.25 2.25 0 01-.659 1.591L5 14.5M9.75 3.104c-.251.023-.501.05-.75.082m.75-.082a24.301 24.301 0 014.5 0m0 0v5.714a2.25 2.25 0 00.659 1.591L19 14.5M14.25 3.104c.251.023.501.05.75.082M19 14.5l-2.47 2.47a2.25 2.25 0 01-1.59.659H9.06a2.25 2.25 0 01-1.591-.659L5 14.5m14 0V17a2 2 0 01-2 2H7a2 2 0 01-2-2v-2.5"/> <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9.75 3.104v5.714a2.25 2.25 0 01-.659 1.591L5 14.5M9.75 3.104c-.251.023-.501.05-.75.082m.75-.082a24.301 24.301 0 014.5 0m0 0v5.714a2.25 2.25 0 00.659 1.591L19 14.5M14.25 3.104c.251.023.501.05.75.082M19 14.5l-2.47 2.47a2.25 2.25 0 01-1.59.659H9.06a2.25 2.25 0 01-1.591-.659L5 14.5m14 0V17a2 2 0 01-2 2H7a2 2 0 01-2-2v-2.5"/>
</svg> </svg>
@@ -131,7 +131,7 @@ withBlogSidebar: true
{% if externalSyndication.length or selfHostedApUrl %} {% if externalSyndication.length or selfHostedApUrl %}
<footer class="post-footer mt-8 pt-6 border-t border-surface-200 dark:border-surface-700"> <footer class="post-footer mt-8 pt-6 border-t border-surface-200 dark:border-surface-700">
<div class="flex flex-wrap items-center gap-4"> <div class="flex flex-wrap items-center gap-4">
<span class="text-sm text-surface-600 dark:text-surface-400">Also on:</span> <span class="text-sm text-surface-700 dark:text-surface-300">Also on:</span>
<div class="flex flex-wrap gap-3"> <div class="flex flex-wrap gap-3">
{# Fediverse remote interaction button (self-hosted ActivityPub) #} {# Fediverse remote interaction button (self-hosted ActivityPub) #}
{% if selfHostedApUrl %} {% if selfHostedApUrl %}
+7 -7
View File
@@ -168,7 +168,7 @@
.site-nav > a, .site-nav > a,
.site-nav .nav-dropdown-trigger { .site-nav .nav-dropdown-trigger {
@apply text-surface-600 dark:text-surface-400 hover:text-surface-900 dark:hover:text-surface-100 no-underline transition-colors py-2; @apply text-surface-700 dark:text-surface-300 hover:text-surface-900 dark:hover:text-surface-100 no-underline transition-colors py-2;
} }
/* Navigation dropdown */ /* Navigation dropdown */
@@ -187,7 +187,7 @@
} }
.nav-dropdown-menu a { .nav-dropdown-menu a {
@apply block px-4 py-2.5 text-sm text-surface-600 dark:text-surface-400 hover:bg-surface-100 dark:hover:bg-surface-700 hover:text-surface-900 dark:hover:text-surface-100 no-underline; @apply block px-4 py-2.5 text-sm text-surface-700 dark:text-surface-300 hover:bg-surface-100 dark:hover:bg-surface-700 hover:text-surface-900 dark:hover:text-surface-100 no-underline;
} }
.nav-dropdown-divider { .nav-dropdown-divider {
@@ -196,7 +196,7 @@
/* Mobile menu toggle button */ /* Mobile menu toggle button */
.menu-toggle { .menu-toggle {
@apply md:hidden p-2 rounded-lg text-surface-600 dark:text-surface-400 hover:bg-surface-100 dark:hover:bg-surface-800 transition-colors; @apply md:hidden p-2 rounded-lg text-surface-700 dark:text-surface-300 hover:bg-surface-100 dark:hover:bg-surface-800 transition-colors;
} }
/* Mobile navigation dropdown */ /* Mobile navigation dropdown */
@@ -207,7 +207,7 @@
} }
.mobile-nav a { .mobile-nav a {
@apply block px-4 py-3 text-surface-600 dark:text-surface-400 hover:bg-surface-100 dark:hover:bg-surface-800 hover:text-surface-900 dark:hover:text-surface-100 no-underline transition-colors border-b border-surface-100 dark:border-surface-800 last:border-b-0; @apply block px-4 py-3 text-surface-700 dark:text-surface-300 hover:bg-surface-100 dark:hover:bg-surface-800 hover:text-surface-900 dark:hover:text-surface-100 no-underline transition-colors border-b border-surface-100 dark:border-surface-800 last:border-b-0;
} }
/* Mobile nav collapsible sections */ /* Mobile nav collapsible sections */
@@ -216,7 +216,7 @@
} }
.mobile-nav-toggle { .mobile-nav-toggle {
@apply flex items-center justify-between w-full px-4 py-3 text-surface-600 dark:text-surface-400 hover:bg-surface-100 dark:hover:bg-surface-800 hover:text-surface-900 dark:hover:text-surface-100 transition-colors bg-transparent border-none text-base text-left cursor-pointer; @apply flex items-center justify-between w-full px-4 py-3 text-surface-700 dark:text-surface-300 hover:bg-surface-100 dark:hover:bg-surface-800 hover:text-surface-900 dark:hover:text-surface-100 transition-colors bg-transparent border-none text-base text-left cursor-pointer;
} }
.mobile-nav-submenu { .mobile-nav-submenu {
@@ -233,7 +233,7 @@
/* Theme toggle button */ /* Theme toggle button */
.theme-toggle { .theme-toggle {
@apply p-2 rounded-lg text-surface-600 dark:text-surface-400 hover:bg-surface-100 dark:hover:bg-surface-800 transition-colors; @apply p-2 rounded-lg text-surface-700 dark:text-surface-300 hover:bg-surface-100 dark:hover:bg-surface-800 transition-colors;
} }
.theme-toggle .sun-icon { .theme-toggle .sun-icon {
@@ -254,7 +254,7 @@
/* Mobile theme toggle */ /* Mobile theme toggle */
.mobile-theme-toggle { .mobile-theme-toggle {
@apply flex items-center justify-between w-full px-4 py-3 text-surface-600 dark:text-surface-400 hover:bg-surface-100 dark:hover:bg-surface-800 hover:text-surface-900 dark:hover:text-surface-100 transition-colors bg-transparent border-none text-base text-left cursor-pointer border-t border-surface-200 dark:border-surface-700; @apply flex items-center justify-between w-full px-4 py-3 text-surface-700 dark:text-surface-300 hover:bg-surface-100 dark:hover:bg-surface-800 hover:text-surface-900 dark:hover:text-surface-100 transition-colors bg-transparent border-none text-base text-left cursor-pointer border-t border-surface-200 dark:border-surface-700;
} }
.mobile-theme-toggle .theme-label { .mobile-theme-toggle .theme-label {