Universal Design for Learning (UDL) โ
SpektraBot is built on the principles of Universal Design for Learning -- a framework that ensures the platform works for every user, regardless of ability, neurodivergence, or learning preference. This page explains what UDL means in SpektraBot and how it is implemented.
Executive Overview โ
What is UDL? โ
Universal Design for Learning is a research-backed framework that says people learn and interact in different ways. Instead of designing for the "average" user and then retrofitting accessibility, UDL designs for diversity from the start.
UDL has three core principles:
- Multiple means of representation -- Give people different ways to take in information
- Multiple means of engagement -- Give people different ways to stay motivated and involved
- Multiple means of expression -- Give people different ways to show what they know or ask for help
Why does it matter for SEND families? โ
Parents navigating the SEND system are often under extreme stress. Many are neurodivergent themselves, or have conditions that affect how they process information. A chatbot that only works one way -- long paragraphs of dense text -- will exclude the very people it's designed to help.
SpektraBot applies UDL at every layer:
| UDL Principle | How SpektraBot implements it |
|---|---|
| Multiple means of representation | Users can read plain English or detailed legal explanations. Font size, contrast, and message density are adjustable. Responses adapt their complexity to the question. |
| Multiple means of engagement | Conversations are paced to the user's needs. The system validates emotions before problem-solving. Users choose how deeply to explore a topic. |
| Multiple means of expression | Users can type freely, use quick-action suggestions, or upload documents. The system doesn't require specific phrasing to understand intent. |
User-facing accessibility settings โ
Every user can customise their experience through the Settings panel:
| Setting | Options | What it does |
|---|---|---|
| Font size | Small (14px), Medium (16px), Large (18px) | Scales all text across the interface |
| High contrast | On / Off | Increases visual contrast for users with low vision |
| Reduced motion | On / Off | Disables animations and transitions |
| Message density | Compact, Comfortable, Spacious | Adjusts spacing between chat messages |
| Timestamps | On / Off | Show or hide message timestamps |
| Markdown | On / Off | Render formatted text or plain text |
| Sound | On / Off | Audio notifications for new messages |
These settings are saved per user and persist across sessions and devices.
Technical Architecture โ
Database schema โ
User accessibility preferences are stored in the user_preferences table, defined in the Prisma schema:
model UserPreferences {
id String @id @default(uuid()) @db.Uuid
userId String @unique @map("user_id") @db.Uuid
// Accessibility (UDL)
fontSize FontSize @default(medium)
highContrast Boolean @default(false)
reducedMotion Boolean @default(false)
// Chat preferences
messageDensity MessageDensity @default(comfortable)
showTimestamps Boolean @default(true)
enableMarkdown Boolean @default(true)
soundEnabled Boolean @default(false)
// Privacy
chatHistoryEnabled Boolean @default(true)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
}
enum FontSize {
small // 0.875rem (14px)
medium // 1rem (16px)
large // 1.125rem (18px)
}
enum MessageDensity {
compact
comfortable
spacious
}API endpoints โ
| Endpoint | Method | Description |
|---|---|---|
/api/preferences | GET | Fetch current user preferences (creates defaults if none exist) |
/api/preferences | PATCH | Update specific preference fields |
/api/preferences/reset | POST | Reset all preferences to defaults |
Frontend implementation โ
Preferences are managed through a React Context provider (packages/web/src/lib/preferences-context.tsx) that wraps the entire application:
AuthProvider
โโ PreferencesProvider โ Loads preferences on login
โโ ChildProvider
โโ SocketProvider
โโ AppWhen preferences change, CSS custom properties are updated on the document root:
const FONT_SIZE_MAP = {
small: "0.875rem", // 14px
medium: "1rem", // 16px
large: "1.125rem", // 18px
};
// Applied to <html> element
root.style.setProperty("--font-size-base", FONT_SIZE_MAP[preferences.fontSize]);Reduced motion support โ
The system respects both the user's manual setting and the operating system's prefers-reduced-motion media query:
/* OS-level preference */
@media (prefers-reduced-motion: reduce) {
*, *::before, *::after {
animation-duration: 0.01ms !important;
transition-duration: 0.01ms !important;
}
}
/* Manual setting via preferences */
html[style*="--animation-duration"] .animate-fadeIn,
html[style*="--animation-duration"] .animate-bounce,
html[style*="--animation-duration"] .animate-pulse {
animation-duration: 0.01ms !important;
}Adaptive response complexity โ
The RAG pipeline adapts response length and complexity based on context and intent through a Response Mode system:
| Mode | Max words | When used |
|---|---|---|
| GATHER | 120 | Sparse context -- ask clarifying questions |
| STANDARD | 150 | Standard detailed response |
| DETAILED | 400 | High context, complex query |
| URGENT | 100 | Deadline or crisis situation |
| TASK | 1000 | Letter writing, structured output |
This implements UDL's "multiple means of representation" at the AI level -- the system automatically adjusts how much information it presents based on the conversation state, avoiding cognitive overload.
UDL in system prompts โ
The base system prompt (packages/api/src/prompts/modules/base_core.md) embeds UDL principles directly into the AI's behaviour:
Communication principles:
- Lead with plain language; add legal terms only when helpful
- Offer choices in how to proceed when multiple pathways exist
- Break complex processes into clear, numbered steps
- End with a clear, specific next step
- Accept that users may need time to process -- don't rush them
UDL provision guidance (when advising on educational provision):
- Multiple means of engagement: interest-led, movement-based, sensory-friendly
- Multiple means of representation: not just text-based learning
- Multiple means of expression: alternative ways to evidence progress
- Therapeutic and educational provision integrated, not siloed
UDL in the knowledge base โ
The knowledge base validation system (packages/api/src/knowledge-base/validation-prompt.ts) specifically accepts UDL-relevant educational content:
"Teaching strategies for SEN pupils (UDL, differentiation, sensory, communication, ASD, ADHD, dyslexia)"
This ensures the RAG pipeline has access to UDL-focused resources when generating advice about educational provision.
Settings UI โ
The Settings tab (packages/web/src/components/tabs/SettingsTab.tsx) organises preferences into four cards:
- Accessibility -- Font size, high contrast, reduced motion
- Chat Settings -- Message density, timestamps, markdown, sound
- Notifications -- Email preferences, reminders, digest
- Privacy -- Chat history retention
Each setting saves immediately on change via the updatePreferences() function, which PATCHes the API and updates the React context simultaneously.
Key files โ
| File | Purpose |
|---|---|
packages/api/prisma/schema.prisma | Preference database schema |
packages/api/src/preferences/routes.ts | REST API endpoints |
packages/api/src/preferences/service.ts | Preference CRUD logic |
packages/web/src/lib/preferences-context.tsx | React context provider |
packages/web/src/components/tabs/SettingsTab.tsx | Settings UI |
packages/web/src/app/globals.css | CSS custom properties and motion queries |
packages/api/src/chat/agentic-rag.ts | Response mode selection |
packages/api/src/prompts/modules/base_core.md | UDL communication principles |