diff --git a/src/frontend/src/features/home/components/IntroSlider.tsx b/src/frontend/src/features/home/components/IntroSlider.tsx index 114aec77..a01413fa 100644 --- a/src/frontend/src/features/home/components/IntroSlider.tsx +++ b/src/frontend/src/features/home/components/IntroSlider.tsx @@ -2,7 +2,7 @@ import { styled } from '@/styled-system/jsx' import { css } from '@/styled-system/css' import { Button } from '@/primitives' import { RiArrowLeftSLine, RiArrowRightSLine } from '@remixicon/react' -import { useState } from 'react' +import { useRef, useState } from 'react' import { useTranslation } from 'react-i18next' const Heading = styled('h2', { @@ -162,12 +162,37 @@ const SLIDES: Slide[] = [ export const IntroSlider = () => { const [slideIndex, setSlideIndex] = useState(0) + const prevButtonRef = useRef(null) + const nextButtonRef = useRef(null) + const focusTargetRef = useRef<'prev' | 'next' | null>(null) const { t } = useTranslation('home', { keyPrefix: 'introSlider' }) const NUMBER_SLIDES = SLIDES.length + const prevSlideIndex = slideIndex - 1 + const nextSlideIndex = slideIndex + 1 + + const previousAriaLabel = + slideIndex > 0 + ? t('previous.withPosition', { + target: prevSlideIndex + 1, + total: NUMBER_SLIDES, + }) + : t('previous.label') + const nextAriaLabel = + slideIndex < NUMBER_SLIDES - 1 + ? t('next.withPosition', { + target: nextSlideIndex + 1, + total: NUMBER_SLIDES, + }) + : t('next.label') + return ( - +
{
) diff --git a/src/frontend/src/locales/de/home.json b/src/frontend/src/locales/de/home.json index e1d7ab8a..20199fba 100644 --- a/src/frontend/src/locales/de/home.json +++ b/src/frontend/src/locales/de/home.json @@ -31,12 +31,14 @@ }, "introSlider": { "previous": { - "label": "Zurück", - "tooltip": "Zurück" + "label": "Vorherige Folie", + "withPosition": "Vorherige Folie anzeigen ({{target}} von {{total}})", + "tooltip": "Vorherige Folie" }, "next": { - "label": "Weiter", - "tooltip": "Weiter" + "label": "Nächste Folie", + "withPosition": "Nächste Folie anzeigen ({{target}} von {{total}})", + "tooltip": "Nächste Folie" }, "beta": { "text": "An der Beta teilnehmen", @@ -53,6 +55,8 @@ "slide3": { "title": "Verwandeln Sie Ihre Meetings mit KI", "body": "Erhalten Sie präzise und verwertbare Transkripte zur Steigerung Ihrer Produktivität. Funktion in der Beta – jetzt testen!" - } + }, + "carouselLabel": "Einführungs-Diashow", + "slidePosition": "Folie {{current}} von {{total}}" } -} +} \ No newline at end of file diff --git a/src/frontend/src/locales/en/home.json b/src/frontend/src/locales/en/home.json index 78976c11..511fa890 100644 --- a/src/frontend/src/locales/en/home.json +++ b/src/frontend/src/locales/en/home.json @@ -31,12 +31,14 @@ }, "introSlider": { "previous": { - "label": "previous", - "tooltip": "previous" + "label": "Previous slide", + "withPosition": "Go to previous slide ({{target}} of {{total}})", + "tooltip": "Previous slide" }, "next": { - "label": "next", - "tooltip": "next" + "label": "Next slide", + "withPosition": "Go to next slide ({{target}} of {{total}})", + "tooltip": "Next slide" }, "beta": { "text": "Join the beta", @@ -53,6 +55,8 @@ "slide3": { "title": "Transform your meetings with AI", "body": "Get accurate and actionable transcripts to boost your productivity. Feature in beta—try it now!" - } + }, + "carouselLabel": "Introduction slideshow", + "slidePosition": "Slide {{current}} of {{total}}" } -} +} \ No newline at end of file diff --git a/src/frontend/src/locales/fr/home.json b/src/frontend/src/locales/fr/home.json index 0c2c2abb..de897476 100644 --- a/src/frontend/src/locales/fr/home.json +++ b/src/frontend/src/locales/fr/home.json @@ -30,14 +30,18 @@ } }, "introSlider": { + "carouselLabel": "Diaporama de présentation", "previous": { - "label": "précédent", - "tooltip": "précédent" + "label": "Diapositive précédente", + "withPosition": "Afficher la diapositive précédente ({{target}} sur {{total}})", + "tooltip": "Diapositive précédente" }, "next": { - "label": "suivant", - "tooltip": "suivant" + "label": "Diapositive suivante", + "withPosition": "Afficher la diapositive suivante ({{target}} sur {{total}})", + "tooltip": "Diapositive suivante" }, + "slidePosition": "Diapositive {{current}} sur {{total}}", "beta": { "text": "Essayer la beta", "tooltip": "Accéder au formulaire" diff --git a/src/frontend/src/locales/nl/home.json b/src/frontend/src/locales/nl/home.json index 54e11625..ef5013c4 100644 --- a/src/frontend/src/locales/nl/home.json +++ b/src/frontend/src/locales/nl/home.json @@ -31,12 +31,14 @@ }, "introSlider": { "previous": { - "label": "vorige", - "tooltip": "vorige" + "label": "Vorige dia", + "withPosition": "Vorige dia tonen ({{target}} van {{total}})", + "tooltip": "Vorige dia" }, "next": { - "label": "volgende", - "tooltip": "volgende" + "label": "Volgende dia", + "withPosition": "Volgende dia tonen ({{target}} van {{total}})", + "tooltip": "Volgende dia" }, "beta": { "text": "Word lid van de bèta", @@ -53,6 +55,8 @@ "slide3": { "title": "Transformeer uw vergaderingen met AI", "body": "Krijg nauwkeurige en bruikbare transcripties om uw productiviteit te stimuleren. Deze mogelijkheid is in bèta, probeer het nu!" - } + }, + "carouselLabel": "Introductie-diavoorstelling", + "slidePosition": "Dia {{current}} van {{total}}" } -} +} \ No newline at end of file diff --git a/src/frontend/src/styles/index.css b/src/frontend/src/styles/index.css index 2aabeb8d..14da58f1 100644 --- a/src/frontend/src/styles/index.css +++ b/src/frontend/src/styles/index.css @@ -30,6 +30,13 @@ body, outline-offset: 1px; } +/* Fallback for NVDA / screen readers: ensure focus ring on :focus when + focus-visible detection fails (e.g. carousel nav buttons) */ +.carousel-nav-button:focus { + outline: 2px solid var(--colors-focus-ring) !important; + outline-offset: 1px; +} + @media (prefers-reduced-motion: reduce) { * { animation: none !important;