LIAM DAHL UX Research & Product Optimization
Accessible PDF Reader

Accessible PDF Reader – Detaillierte Projektübersicht

Zurück zur Case Study

Accessible PDF Reader

Eine Web-App, die PDFs per Frage beantwortet – mit Barrierefreiheit als Fundament.

PDF hochladen, eine Frage zum Dokument stellen, die Antwort bei Bedarf vorlesen lassen. Konzipiert von der schwierigsten Nutzung her gedacht – blinde Screenreader-Nutzer – und durchgehend barrierefrei umgesetzt.


Auf einen Blick

RolleKonzept · Architektur · Frontend · Accessibility
Zeitraum2025
KontextUni Projekt in einer sechser Gruppe.
MethodenScreenreader-Test (NVDA), End-to-End-Test mit Test-PDF
ToolsPython · FastAPI · OpenAI (gpt-4.1-nano) · pypdf · HTML/CSS/JS · Figma · Render · GitHub
ErgebnisLauffähige, barrierefreie App – deployt, End-to-End getestet, für RAG vorbereitet
LinksLive Demo · GitHub · Case Study

Meine drei wichtigsten Beiträge

  1. Barrierefreiheit von der blinden Nutzung her gedacht
    • Fokus-Führung, Live-Regionen nach Dringlichkeit, bewusst degradiertes Vorlesen
  2. Eine bewusst entkoppelte Architektur: fünf Module, jede Datei mit einer Aufgabe, plus eine klar definierte Naht für späteres RAG.
  3. Ein UI-Redesign in zwei Richtungen (Formular vs. Konversation), inklusive dokumentierter Zustände und eines Accessibility-Annotations-Layers.

01 Kontext Definition

Wer nutzt das – und wozu?

Primäre Zielgruppe sind blinde und sehbehinderte Menschen, die ein Dokument nicht durchlesen, sondern gezielt befragen wollen. Die Leitentscheidung: Das Erlebnis entsteht in Semantik, Ansagen und Fokus – nicht in der Optik. Sehende und sehschwache Nutzer werden als zweite Schicht mitbedient.

Im Scope

  • Ein Dokument hochladen, befragen, Antwort vorlesen lassen
  • Vollständige Tastatur- und Screenreader-Bedienung

Bewusst ausgeschlossen (Prototyp-Scope, keine Versäumnisse)

  • Persistenz, Nutzerkonten, Mehrbenutzer-Zustand
  • Mehrere Dokumente / gespeicherte Verläufe
  • RAG (vorbereitet, aber bewusst noch nicht gebaut)

02 Nutzungskontextanalyse

Nutzergruppe, Persona und Aufgaben

Persona

[Platzhalter: Name, Alter, Rolle] Technik-Niveau: [Platzhalter]

[Platzhalter: Kurzbeschreibung – Situation, Ziel, Frust. Z. B. „nutzt einen Screenreader, will die Kernaussage eines PDFs erfassen, ohne es Seite für Seite durchzuhören.”]

Aufgabenmodell – Hauptaufgabe

BenutzergruppeBlinde / sehbehinderte Nutzer
AufgabeEine konkrete Frage zu einem PDF beantwortet bekommen
VorbedingungEin PDF liegt vor, Screenreader aktiv
Teilaufgaben1) PDF hochladen
2) Ladebestätigung wahrnehmen
3) Frage stellen
4) Antwort hören
5) bei Bedarf vorlesen lassen / neue Frage
NachbedingungNutzer hat eine dokumentbasierte Antwort erhalten

03 Anforderungsermittlung

Aus dem Nutzungskontext wurden prüfbare Anforderungen abgeleitet – mit Schwerpunkt Barrierefreiheit.

IDAnforderung
A1Jeder Zustandswechsel (geladen, wartet, Antwort, Fehler) muss für Screenreader hörbar angesagt werden.
A2Trifft die Antwort ein, muss der Fokus dorthin geführt werden.
A3Fehler müssen bestimmt (assertiv), Statusmeldungen höflich angesagt werden.
A4Die App muss vollständig per Tastatur bedienbar sein, mit sichtbarem Fokus.
A5Farbe darf nie alleiniger Bedeutungsträger sein (Symbol + Wort).
A6Kontraste ≥ 4,5:1; nutzbar bei 200 % Zoom und ab 320 px Breite.
A7Die KI darf ausschließlich auf Basis des Dokuments antworten und Fehlendes offen benennen.
F1PDF hochladen (max. 20 MB), Text extrahieren, Frage beantworten.

04 Informationsarchitektur

Aufgaben und Module statt Screens

Die Anwendung ist bewusst entkoppelt – fünf Module, jede Datei mit genau einer Aufgabe.

ModulAufgabe
main.pyFastAPI-Routes, HTTP, verbindet die Module
pdf.pyPDF-Bytes → reiner Text (pypdf)
context.pyKontext-Aufbereitung – Naht für späteres RAG
ai.pyOpenAI gekapselt, vollständige Fehlerbehandlung
config.pyEinstellungen aus .env, getippt

Die zentrale Entwurfsentscheidung – die context.py-Naht: Die gesamte App greift nur über context.get_context(frage, pdf_text) auf den Kontext zu. Heute liefert die Funktion den Volltext (bei Bedarf gekürzt). Ein späterer RAG-Umbau (Embeddings + Vektorsuche) berührt nur diese eine Funktion – die Signatur bleibt gleich, der Rest merkt nichts.

Das Dokument wird bewusst nur im Arbeitsspeicher gehalten (ein Dokument, keine Persistenz).


05 Interaktionsdesign

Zwei Richtungen, eine Entscheidung

  • Variante A (Formular): drei gestapelte Schritt-Karten (Upload → Frage → Antwort).
  • Variante B (Konversation) – gewählt: Dokument-Status oben als fester Kontext, Frage/Antwort als Verlauf, Eingabe unten wie ein Chat. Begründung: passt zum mentalen Modell „ich frage ein Dokument”, erhält eine Antwort-Historie.

Zustands-Fluss

Leer ──Upload──► Geladen ──Frage──► Wartet ──► Antwort
                                        └─────► Fehler ──Erneut──► Wartet

Ändern ──► Bestätigungs-Dialog ──Laden──► Verlauf leeren ──► Geladen
                                 └─Abbrechen/Esc──► zurück

Die nicht-sichtbaren Entscheidungen (Fokus-Führung, Live-Region-Dringlichkeit, Dialog-Fokusfalle) sind in einem eigenen Accessibility-Annotations-Layer dokumentiert.


06 Interface Design

Ruhiges, funktionales Design-System

  • Farben: warmer Grundton, dunkelgrüner Akzent (#1B5E3F), alle Kontraste WCAG-geprüft (≥ 4,5:1, meist ≥ 7:1). Dark Mode designt.
  • Abstände: 4er-System (4 / 8 / 16 / 24 / 32). Radius: 8 / 12.
  • Typografie: Inter (Atkinson Hyperlegible als barrierefreie Alternative geprüft).
  • Alle Werte als Design-Tokens angelegt und im Code als CSS Custom Properties gespiegelt – Design-System und Code sprechen dieselbe Sprache.

![[Screenpdf.png]]


07 Frontend

Plain HTML/CSS/JS – bewusst ohne Framework

Der Kern (Barrierefreiheit) lebt in semantischem HTML, ARIA, Live-Regionen und Fokus-Steuerung – kein CSS-Framework liefert davon etwas. Umgesetzt:

  • Semantisches HTML, Landmarks, Skip-Link, <label> an jedem Feld, sichtbare Fokusringe
  • Live-Regionen: Verlauf höflich (role="log"), Fehler bestimmt (role="alert"); „Antwort wird erstellt…” hält die KI-Latenz auf, „Senden” ist solange gesperrt
  • Antwort = Hinspringen: Fokus wandert in die Antwort, keine zusätzliche Live-Ansage
  • Vorlesen bewusst degradiert: nur manueller Start, nie Auto-Play (Web Speech API)
  • PDF wechseln nur mit Bestätigungsdialog (Fokus-Falle, Esc, Fokus-Rücksprung)
  • fetch statt Reload; Touch-Ziele ≥ 44 px; Reflow bis 320 px / 200 % Zoom; prefers-reduced-motion

08 Test & Betrieb

End-to-End mit einer Test-PDF geprüft

4/4Testfälle bestanden
5entkoppelte Module
100 %Antworten dokumentbasiert
0Halluzinationen im Test

Geprüft wurde auf vier Dinge: korrekte Fakten, korrekte Details, sauberes Abweisen einer Frage ohne Antwort im Dokument, und deutsches Vorlesen per Web Speech API. Zusätzlich ein Screenreader-Durchlauf mit NVDA.

Deployt auf Render (Web Service, uvicorn app.main:app --host 0.0.0.0 --port $PORT, API-Key als Env-Variable). Kostenschutz: OpenAI Auto-Recharge OFF.


09 Dokumentation & Präsentation

  • Case Study auf der Portfolio-Seite
  • Diese Projektübersicht + README im Repo
  • [Platzhalter: Präsentation / weitere Artefakte, falls vorhanden]

Ergebnis & Reflexion

Was entstanden ist

  • Eine lauffähige, barrierefreie App – hochladen, befragen, vorlesen
  • Sauber entkoppelte Architektur, End-to-End getestet und deployt
  • Ein barrierefreies UI-Redesign inkl. dokumentierter Zustände und Annotationen

Was ich gelernt habe

  • [Platzhalter: 1–2 ehrliche Erkenntnisse, z. B. „Fokus-Management ist der eigentliche Kern von Screenreader-UX, nicht ARIA-Labels allein.”]

Ausblick

  • RAG über die vorbereitete context.py-Naht – ohne den Rest der App anzufassen
  • [Platzhalter: weitere Schritte, z. B. mehrere Dokumente / Verläufe]

Anhang

Diese Seite ist eine verdichtete Übersicht. [Platzhalter: Verweis auf ausführliche Prozessdokumentation, falls vorhanden.]