From 59732f37066f3805dc610960fcc4a6d09ff9ef63 Mon Sep 17 00:00:00 2001 From: Nurfog Date: Wed, 25 Feb 2026 16:09:54 -0300 Subject: [PATCH] feat: improve accessibility with semantic HTML, ARIA attributes, and visible focus states across components. --- web/experience/src/app/globals.css | 10 +++- .../components/blocks/AudioResponsePlayer.tsx | 49 ++++++++++++------- web/studio/src/app/globals.css | 10 +++- .../src/components/BrandingSettings.tsx | 32 +++++++----- web/studio/src/components/Combobox.tsx | 39 +++++++++++---- .../src/components/CourseEditorLayout.tsx | 32 ++++++------ web/studio/src/components/Navbar.tsx | 15 +++--- 7 files changed, 123 insertions(+), 64 deletions(-) diff --git a/web/experience/src/app/globals.css b/web/experience/src/app/globals.css index b63fdb2..eeb4216 100644 --- a/web/experience/src/app/globals.css +++ b/web/experience/src/app/globals.css @@ -13,8 +13,8 @@ --accent-primary: var(--primary-color); --accent-secondary: var(--secondary-color); - --glass-bg: rgba(255, 255, 255, 0.03); - --glass-border: rgba(255, 255, 255, 0.08); + --glass-bg: rgba(255, 255, 255, 0.05); /* Increased slightly for contrast */ + --glass-border: rgba(255, 255, 255, 0.1); --glass-blur: blur(16px); } @@ -32,6 +32,12 @@ body { border: 1px solid var(--glass-border); } +/* Ensure focus states are visible for keyboard navigation */ +:focus-visible { + outline: 2px solid var(--accent-primary); + outline-offset: 4px; +} + .glass-card { @apply glass rounded-2xl p-4 md:p-6 transition-all duration-300; } diff --git a/web/experience/src/components/blocks/AudioResponsePlayer.tsx b/web/experience/src/components/blocks/AudioResponsePlayer.tsx index dbc50da..6235d40 100644 --- a/web/experience/src/components/blocks/AudioResponsePlayer.tsx +++ b/web/experience/src/components/blocks/AudioResponsePlayer.tsx @@ -183,7 +183,7 @@ export default function AudioResponsePlayer({
-

{prompt}

+

{prompt}

{keywords.length > 0 && !submitted && (
Expected topics: @@ -205,16 +205,23 @@ export default function AudioResponsePlayer({ )} {isRecording && (
-
-
+
+
@@ -234,16 +242,18 @@ export default function AudioResponsePlayer({
@@ -258,11 +268,11 @@ export default function AudioResponsePlayer({
)} - {/* Submit Button */} {audioBlob && transcript && ( @@ -273,12 +283,15 @@ export default function AudioResponsePlayer({ {/* Evaluation Results */} {submitted && evaluation && (
-
= 70 - ? 'bg-green-500/10 border-green-500' - : evaluation.score >= 40 - ? 'bg-yellow-500/10 border-yellow-500' - : 'bg-red-500/10 border-red-500' - }`}> +
= 70 + ? 'bg-green-500/10 border-green-500' + : evaluation.score >= 40 + ? 'bg-yellow-500/10 border-yellow-500' + : 'bg-red-500/10 border-red-500' + }`} + aria-live="assertive" + >
Your Score {evaluation.score}% diff --git a/web/studio/src/app/globals.css b/web/studio/src/app/globals.css index 8eb0acc..6f4b70c 100644 --- a/web/studio/src/app/globals.css +++ b/web/studio/src/app/globals.css @@ -13,11 +13,17 @@ /* blue-500 */ --accent-secondary: #6366f1; /* indigo-500 */ - --glass-bg: rgba(255, 255, 255, 0.03); - --glass-border: rgba(255, 255, 255, 0.08); + --glass-bg: rgba(255, 255, 255, 0.05); + --glass-border: rgba(255, 255, 255, 0.1); --glass-blur: blur(16px); } +/* Ensure focus states are visible for keyboard navigation */ +:focus-visible { + outline: 2px solid var(--accent-primary); + outline-offset: 4px; +} + body { color: rgb(var(--foreground-rgb)); background: var(--background-start-rgb); diff --git a/web/studio/src/components/BrandingSettings.tsx b/web/studio/src/components/BrandingSettings.tsx index 3d4ef3a..c09cb6e 100644 --- a/web/studio/src/components/BrandingSettings.tsx +++ b/web/studio/src/components/BrandingSettings.tsx @@ -79,7 +79,7 @@ export default function BrandingSettings() { {/* Logo Section */}
- + Logo
{org.logo_url ? ( - + Favicon
{org.favicon_url ? (
@@ -143,56 +143,64 @@ export default function BrandingSettings() {
-
-

- 🌈 Brand Colors -

-
+
+ + Brand Colors + +
{/* Primary Color */}
- +
setFormData({ ...formData, primary_color: e.target.value })} + aria-label="Primary color picker" className="w-12 h-12 rounded-lg cursor-pointer bg-transparent border-none p-0" />
setFormData({ ...formData, primary_color: e.target.value })} className="w-full bg-black/20 border border-white/10 rounded-lg px-4 py-2 text-white font-mono uppercase" + aria-describedby="primary-color-desc" />
-

Used for main buttons, active states, and highlights.

+

Used for main buttons, active states, and highlights.

{/* Secondary Color */}
- +
setFormData({ ...formData, secondary_color: e.target.value })} + aria-label="Secondary color picker" className="w-12 h-12 rounded-lg cursor-pointer bg-transparent border-none p-0" />
setFormData({ ...formData, secondary_color: e.target.value })} className="w-full bg-black/20 border border-white/10 rounded-lg px-4 py-2 text-white font-mono uppercase" + aria-describedby="secondary-color-desc" />
-

Used for accents and gradients.

+

Used for accents and gradients.

-
+
{isOpen && (
- +