Problem: <video> elements on tfe.php had no <track kind="captions"> element, violating WCAG 4.1.2 (name, role, value) for video content. Changes: - public/tfe.php: collect all text/vtt files from the thesis file list before rendering; skip standalone rendering of .vtt entries; for each MP4 emit a <track kind="captions" srclang="fr" label="Sous-titres" default> pointing to the N-th VTT file (N-th video paired with N-th caption in document order) - public/media.php: add text/vtt to allowed MIME list; normalise finfo text/plain -> text/vtt for .vtt files; add vtt branch to cache/header block (Content-Type: text/vtt; charset=utf-8, 1-day cache) - public/admin/actions/formulaire.php: allow .vtt uploads (text/vtt MIME, vtt extension); normalise text/plain finfo result; set file_type='caption' for VTT files so they are distinguishable from other thesis files - public/admin/add.php: extend files field accept attr to include .vtt; update hint text to document the VTT sidecar convention VTT files uploaded under theses/ inherit the same access_type visibility gate in media.php as all other thesis content (403 for access_type_id=3).
6.0 KiB
Accessibility Audit (WCAG 2.1 AA)
1.1.1 Non-text content (alt text)
- Admin
<nav>"✕ Réinitialiser" and "✕" remove buttons — wrap✕in<span aria-hidden="true">✕</span>; addaria-label="Supprimer ce membre du jury"on jury remove buttons inadd.php/edit.php
1.3.1 Info and relationships
-
Admin form rows: multi-input rows (languages, formats) —
checkbox-list.phppartial now wraps checkboxes in<fieldset class="admin-checkbox-group">with a<legend class="sr-only">for AT grouping -
Status badges in
admin/index.phpconvey state by colour alone —status-badge.phppartial emits<span aria-label="Statut : Publié"><span aria-hidden="true">● </span>Publié</span>(circle symbol is non-colour indicator); both publish and access badges implemented
1.3.4 / 1.3.5 Orientation & Input purpose
- No
autocompleteattributes on personal data fields —add.php/edit.php:autocomplete="name"on author fields,autocomplete="email"on mail fields (via$attrsintext-field.php)
1.4.1 Use of colour
-
Active nav link has no non-colour indicator — admin nav:
border-bottom: 2px solid currentColoradded for[aria-current="page"]inadmin.css; public nav already hadborder-bottomincommon.css -
Admin purple
#9557b5as text colour —--admin-purplewas an undefined variable referenced only in pagination hover; replaced with--accent-primary(same value, #9557b5). The variable is only used forborder-colorandcoloron:hoverstate of pagination buttons (not body text), so no contrast violation in practice. Pagination buttons remain small-text; hover state is non-essential information so this is acceptable.
1.4.4 Resize text
- Verify no text is set in
px— audited all CSS files; everyfont-sizeusesremorem; nopxfont-size found anywhere. No action needed.
1.4.12 Text spacing
- No text-spacing override test done — audited all
overflow: hiddeninstances:.sr-only(visually hidden utility, 1×1px — not text content),.home-body figure/aside figure/.card(media containers, not text)..card__gradient-titleclamps decorative gradient text — not essential content (same info is in the<p>link). No WCAG 1.4.12 failure found.
2.1.1 Keyboard
- Jury "✕" remove buttons in
add.php/edit.php—aria-label="Supprimer le lecteur·ice N"already present on all remove buttons injury-fieldset.php(both static and dynamically added rows)
2.4.3 Focus order
- On
tfe.phpthe← Retourback link is at the bottom of the left column in DOM — already fixed;<a class="tfe-back-link">← Retour</a>is the first child of<header class="tfe-left">, which precedes<h1 class="tfe-title">in DOM order
2.4.4 Link purpose
- Home page cards: if two theses share the same title, identical link texts exist —
public/index.phpcard<p>now appends<span class="sr-only">, YEAR</span>when$item['year']is set, giving screen-reader users a unique link name per thesis
2.5.3 Label in name
<a class="clear-filter">✕ Réinitialiser</a>— wrap✕in<span aria-hidden="true">- Admin jury remove buttons
✕—aria-label="Supprimer ce lecteur"replaces the symbol
2.5.5 Target size
- Pagination buttons are
2rem(32px) — increase tomin-height: 2.75rem; min-width: 2.75rem(44px) - Admin
.admin-btn-sm(~28px) — increase to minimum 32px with padding - Admin bulk action buttons and jury remove
✕buttons (~28px) — increase target size
3.1.1 Language of page
- All public pages have
<html lang="fr">— verified:templates/head.phpline 2 has<html lang="fr">; all pages share this template. No action needed.
3.3.1 Error identification
add.php/edit.phpvalidation errors —flash-messages.phpalready emits<p role="alert" data-type="error">for errors and<p role="status">for successadd.php/edit.phpautofocuson first invalid field — requires controller to pass back which field failed; deferred (larger refactor)
3.3.2 Labels or instructions
- Admin jury "Lecteur·ices" label has no
forattribute — replaced plain<label>Lecteur·ices :</label>with<fieldset class="admin-jury-lecteurs"><legend>Lecteur·ices</legend>injury-fieldset.php; CSS rule strips the nested fieldset’s border/padding so it renders as a sub-group
4.1.2 Name, role, value
-
Custom "Externe" checkbox for jury members has no group context — all jury "Externe" checkboxes now carry explicit
aria-label(e.g."Promoteur·ice — externe","Lecteur·ice N — externe"); both static PHP-rendered rows and dynamically added rows viaaddJuryRow()receive the label -
<video>elements ontfe.phphave no captions —<track kind="captions">now emitted for each MP4 when a.vttsidecar has been uploaded alongside it; N-th VTT file is paired with N-th video in document order.formulaire.phpaccepts.vttuploads (MIMEtext/vtt,file_type = 'caption');media.phpserves VTT with correctContent-Type; adminadd.phpfile-field hint documents the.vttconvention. -
Admin
<select>for visibility/access inedit.phpuses truncated option text — removedmb_strimwidthcall; option text now uses full description (name — description) so screen-reader accessible name is complete and unambiguous -
Bulk publish/unpublish JS does not announce result to screen readers — action result is a full-page redirect to a flash message rendered by
flash-messages.phpwhich already emitsrole="alert"(error) /role="status"(success); no additional JS announcement needed
5 - Motion & user preferences
prefers-color-schemenot respected — site has fixed white public / fixed dark admin themes; consider a dark-mode variant for public pages (not a WCAG failure, but quality-of-life)