feat: improve accessibility and update color scheme based on PageSpeed insights
All checks were successful
CI / update (push) Successful in 1m13s

- Add aria-labels to icon-only links (add button, edit button, logo, nav toggle)
- Add main landmark element for better page structure
- Fix heading hierarchy on recipe pages (h1 → h2 → h3 progression)
- Add role="status" to loading placeholders to allow aria-label usage
- Update link colors from red to blue for better contrast in both light and dark modes
- Change hover colors from orange/red to light blue across all interactive elements
- Reduce font size of section labels (Season, Keywords) while maintaining semantic structure

These changes address PageSpeed accessibility recommendations including low-contrast text,
missing accessible names, prohibited ARIA attributes, missing landmarks, and improper
heading order.
This commit is contained in:
2026-01-05 16:14:35 +01:00
parent 4a8e6c6600
commit cc978e73b4
13 changed files with 77 additions and 38 deletions

View File

@@ -1,5 +1,6 @@
<script lang='ts'>
export let href
export let ariaLabel: string | undefined = undefined
import "$lib/css/nordtheme.css"
import "$lib/css/action_button.css"
</script>
@@ -78,6 +79,6 @@ box-shadow: 0em 0em 0.5em 0.5em rgba(0,0,0,0.2);
}
}
</style>
<a class="container action_button" {href}>
<a class="container action_button" {href} aria-label={ariaLabel}>
<slot></slot>
</a>

View File

@@ -3,6 +3,6 @@ import ActionButton from "./ActionButton.svelte";
export let href: string;
</script>
<ActionButton {href}>
<ActionButton {href} ariaLabel="Add new recipe">
<svg class=icon_svg xmlns="http://www.w3.org/2000/svg" height="1em" viewBox="0 0 448 512"><!--! Font Awesome Free 6.4.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2023 Fonticons, Inc. --><path d="M256 80c0-17.7-14.3-32-32-32s-32 14.3-32 32V224H48c-17.7 0-32 14.3-32 32s14.3 32 32 32H192V432c0 17.7 14.3 32 32 32s32-14.3 32-32V288H400c17.7 0 32-14.3 32-32s-14.3-32-32-32H256V80z"/></svg>
</ActionButton>

View File

@@ -190,7 +190,7 @@ const img_name = $derived(
.tag:focus-visible
{
transform: scale(1.04, 1.04);
background-color: var(--orange);
background-color: var(--nord8);
box-shadow: 0.2em 0.2em 0.2em 0.1em rgba(0, 0, 0, 0.3);
}
.tag:focus{

View File

@@ -267,7 +267,7 @@ input::placeholder{
.card .tag:focus-within
{
transform: scale(1.04, 1.04);
background-color: var(--orange);
background-color: var(--nord8);
box-shadow: 0.2em 0.2em 0.2em 0.1em rgba(0, 0, 0, 0.3);
}

View File

@@ -2,6 +2,6 @@
import ActionButton from "./ActionButton.svelte";
export let href
</script>
<ActionButton {href}>
<ActionButton {href} ariaLabel="Edit recipe">
<svg class=icon_svg xmlns="http://www.w3.org/2000/svg" height="1em" viewBox="0 0 512 512"><!--! Font Awesome Free 6.4.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2023 Fonticons, Inc. --><path d="M410.3 231l11.3-11.3-33.9-33.9-62.1-62.1L291.7 89.8l-11.3 11.3-22.6 22.6L58.6 322.9c-10.4 10.4-18 23.3-22.2 37.4L1 480.7c-2.5 8.4-.2 17.5 6.1 23.7s15.3 8.5 23.7 6.1l120.3-35.4c14.1-4.2 27-11.8 37.4-22.2L387.7 253.7 410.3 231zM160 399.4l-9.1 22.7c-4 3.1-8.5 5.4-13.3 6.9L59.4 452l23-78.1c1.4-4.9 3.8-9.4 6.9-13.3l22.7-9.1v32c0 8.8 7.2 16 16 16h32zM362.7 18.7L348.3 33.2 325.7 55.8 314.3 67.1l33.9 33.9 62.1 62.1 33.9 33.9 11.3-11.3 22.6-22.6 14.5-14.5c25-25 25-65.5 0-90.5L453.3 18.7c-25-25-65.5-25-90.5 0zm-47.4 168l-144 144c-6.2 6.2-16.4 6.2-22.6 0s-6.2-16.4 0-22.6l144-144c6.2-6.2 16.4-6.2 22.6 0s6.2 16.4 0 22.6z"/></svg>
</ActionButton>

View File

@@ -131,7 +131,7 @@ nav[hidden]{
:global(.entry:focus-visible)
{
cursor: pointer;
color: var(--red);
color: var(--nord8);
}
:global(.site_header) {
padding-block: 1.5rem;
@@ -151,7 +151,7 @@ nav[hidden]{
position: absolute;
bottom: 1.2rem;
height: 2px;
background-color: var(--red);
background-color: var(--nord8);
transition: left 300ms ease-out, width 300ms ease-out;
pointer-events: none;
}
@@ -300,7 +300,7 @@ footer{
}
:global(.nav_site .site_header a.active) {
text-decoration: underline;
text-decoration-color: var(--red);
text-decoration-color: var(--nord8);
text-decoration-thickness: 2px;
text-underline-offset: 0.3rem;
}
@@ -310,14 +310,14 @@ footer{
<div>
<span class=button_wrapper_shadow></span>
<div class=button_wrapper>
<a href="/"><Symbol></Symbol></a>
<a href="/" aria-label="Home"><Symbol></Symbol></a>
<div class="right-buttons">
{@render language_selector_mobile?.()}
<button class=nav_button onclick={() => {toggle_sidebar()}}><svg xmlns="http://www.w3.org/2000/svg" height="0.5em" viewBox="0 0 448 512"><!--! Font Awesome Free 6.4.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2023 Fonticons, Inc. --><path d="M0 96C0 78.3 14.3 64 32 64H416c17.7 0 32 14.3 32 32s-14.3 32-32 32H32C14.3 128 0 113.7 0 96zM0 256c0-17.7 14.3-32 32-32H416c17.7 0 32 14.3 32 32s-14.3 32-32 32H32c-17.7 0-32-14.3-32-32zM448 416c0 17.7-14.3 32-32 32H32c-17.7 0-32-14.3-32-32s14.3-32 32-32H416c17.7 0 32 14.3 32 32z"/></svg></button>
<button class=nav_button onclick={() => {toggle_sidebar()}} aria-label="Toggle navigation menu"><svg xmlns="http://www.w3.org/2000/svg" height="0.5em" viewBox="0 0 448 512"><!--! Font Awesome Free 6.4.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2023 Fonticons, Inc. --><path d="M0 96C0 78.3 14.3 64 32 64H416c17.7 0 32 14.3 32 32s-14.3 32-32 32H32C14.3 128 0 113.7 0 96zM0 256c0-17.7 14.3-32 32-32H416c17.7 0 32 14.3 32 32s-14.3 32-32 32H32c-17.7 0-32-14.3-32-32zM448 416c0 17.7-14.3 32-32 32H32c-17.7 0-32-14.3-32-32s14.3-32 32-32H416c17.7 0 32 14.3 32 32z"/></svg></button>
</div>
</div>
<nav hidden class=nav_site>
<a class=entry href="/"><Symbol></Symbol></a>
<a class=entry href="/" aria-label="Home"><Symbol></Symbol></a>
<div class="links-wrapper">
{@render links?.()}
<div class="active-underline" class:no-transition={disableTransition} style="left: {underlineLeft}px; width: {underlineWidth}px;"></div>
@@ -330,7 +330,9 @@ footer{
</div>
</nav>
<main>
{@render children?.()}
</main>
</div>
<footer>

View File

@@ -315,7 +315,7 @@ font-family: sans-serif;
}
.multipliers :is(button, div):is(:hover, :focus-within){
scale: 1.2;
background-color: var(--orange);
background-color: var(--nord8);
box-shadow: 0px 0px 0.5em 0.1em rgba(0,0,0, 0.3);
}
.selected{
@@ -402,21 +402,33 @@ span
.custom-multiplier:hover,
.custom-multiplier:focus-within {
scale: 1.2;
background-color: var(--orange);
background-color: var(--nord8);
box-shadow: 0px 0px 0.5em 0.1em rgba(0,0,0, 0.3);
}
/* Base recipe reference link styling */
h3 a {
color: var(--nord11);
color: var(--nord10);
text-decoration: underline;
text-decoration-color: var(--nord11);
text-decoration-color: var(--nord10);
}
h3 a:hover {
color: var(--nord11);
color: var(--nord9);
text-decoration: underline;
text-decoration-color: var(--nord11);
text-decoration-color: var(--nord9);
}
@media (prefers-color-scheme: dark) {
h3 a {
color: var(--nord8);
text-decoration-color: var(--nord8);
}
h3 a:hover {
color: var(--nord7);
text-decoration-color: var(--nord7);
}
}
</style>
{#if data.ingredients}

View File

@@ -147,50 +147,62 @@ ol li::marker{
}
}
h4{
h3{
margin-block: 0;
}
/* Base recipe reference link styling */
h3 a {
color: var(--nord11);
color: var(--nord10);
text-decoration: underline;
text-decoration-color: var(--nord11);
text-decoration-color: var(--nord10);
}
h3 a:hover {
color: var(--nord11);
color: var(--nord9);
text-decoration: underline;
text-decoration-color: var(--nord11);
text-decoration-color: var(--nord9);
}
@media (prefers-color-scheme: dark) {
h3 a {
color: var(--nord8);
text-decoration-color: var(--nord8);
}
h3 a:hover {
color: var(--nord7);
text-decoration-color: var(--nord7);
}
}
</style>
<div class=instructions>
<div class=additional_info>
{#if data.preparation}
<div><h4>{labels.preparation}</h4>{data.preparation}</div>
<div><h3>{labels.preparation}</h3>{data.preparation}</div>
{/if}
{#if data.fermentation}
{#if data.fermentation.bulk}
<div><h4>{labels.bulkFermentation}</h4>{data.fermentation.bulk}</div>
<div><h3>{labels.bulkFermentation}</h3>{data.fermentation.bulk}</div>
{/if}
{#if data.fermentation.final}
<div><h4>{labels.finalProof}</h4> {data.fermentation.final}</div>
<div><h3>{labels.finalProof}</h3> {data.fermentation.final}</div>
{/if}
{/if}
{#if data.baking.temperature}
<div><h4>{labels.baking}</h4> {data.baking.length} {labels.at} {data.baking.temperature} °C {data.baking.mode}</div>
<div><h3>{labels.baking}</h3> {data.baking.length} {labels.at} {data.baking.temperature} °C {data.baking.mode}</div>
{/if}
{#if data.cooking}
<div><h4>{labels.cooking}</h4>{data.cooking}</div>
<div><h3>{labels.cooking}</h3>{data.cooking}</div>
{/if}
{#if data.total_time}
<div><h4>{labels.onThePlate}</h4>{data.total_time}</div>
<div><h3>{labels.onThePlate}</h3>{data.total_time}</div>
{/if}
</div>

View File

@@ -58,6 +58,7 @@
<div
bind:this={containerRef}
style="height: {estimatedHeight}px; min-height: {estimatedHeight}px;"
role="status"
aria-label="Loading {title}"
>
<!-- Empty placeholder - IntersectionObserver will trigger when this enters viewport -->

View File

@@ -12,7 +12,7 @@
svg:hover,
svg:focus-visible
{
--icon_fill: var(--red);
--icon_fill: var(--nord8);
}
svg g.leaf path,
.fill

View File

@@ -29,13 +29,19 @@
}
a:not(:visited){
color: var(--red);
color: var(--blue);
}
a:visited{
color: var(--purple);
}
@media (prefers-color-scheme: dark) {
a:not(:visited){
color: var(--nord8);
}
}
*{
box-sizing: border-box;
font-family: Helvetica, Arial, "Noto Sans", sans-serif