Accessibility pass: ARIA roles, label associations, CSS class migrations

- Add role=dialog/aria-modal/aria-labelledby to all 12 modal overlays (JS + PHP)
- Add aria-label="Close" to all 14 modal close buttons
- Add full ARIA combobox pattern to @mention autocomplete (listbox, option, aria-selected, aria-expanded)
- Add for= attributes to admin filter form labels (AuditLog, UserActivity, ApiKeys)
- Remove dead closeOnAdvancedSearchBackdropClick() from advanced-search.js

CSS/JS style cleanup:
- Move .ascii-banner static styles from JS inline to CSS class; add .ascii-banner--glow
- Add .ascii-banner-cursor, .loading-overlay--hiding, .has-overlay, tr[data-clickable]
- Add .animate-fadein/.animate-fadeout/.comment--deleting to ticket.css
- Add .lt-toast--hiding to base.css; remove opacity/transition inline JS
- Remove redundant cursor:pointer JS (already in th{} CSS rule)
- Remove trailing space in lt-select class attributes

Bug fixes:
- base.js: boot overlay opacity inline style was overriding .fade-out class opacity via
  specificity (1000 vs 20), preventing the fade-out animation — removed
- ascii-banner.js: cursor used blink-caret (border-color only) instead of blink-cursor
  (opacity-based), so the █ cursor never actually blinked — fixed

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-20 20:29:58 -04:00
parent 11f75fd823
commit 7695c6134c
21 changed files with 929 additions and 610 deletions

View File

@@ -12,11 +12,11 @@ $nonce = SecurityHeadersMiddleware::getNonce();
<title>Create New Ticket</title>
<link rel="icon" type="image/png" href="<?php echo $GLOBALS['config']['ASSETS_URL']; ?>/images/favicon.png">
<link rel="stylesheet" href="/assets/css/base.css">
<link rel="stylesheet" href="<?php echo $GLOBALS['config']['ASSETS_URL']; ?>/css/dashboard.css?v=20260319d">
<link rel="stylesheet" href="<?php echo $GLOBALS['config']['ASSETS_URL']; ?>/css/ticket.css?v=20260319d">
<link rel="stylesheet" href="<?php echo $GLOBALS['config']['ASSETS_URL']; ?>/css/dashboard.css?v=20260320">
<link rel="stylesheet" href="<?php echo $GLOBALS['config']['ASSETS_URL']; ?>/css/ticket.css?v=20260320">
<script nonce="<?php echo $nonce; ?>" src="/assets/js/base.js"></script>
<script nonce="<?php echo $nonce; ?>" src="<?php echo $GLOBALS['config']['ASSETS_URL']; ?>/js/utils.js"></script>
<script nonce="<?php echo $nonce; ?>" src="<?php echo $GLOBALS['config']['ASSETS_URL']; ?>/js/dashboard.js?v=20260205"></script>
<script nonce="<?php echo $nonce; ?>" src="<?php echo $GLOBALS['config']['ASSETS_URL']; ?>/js/utils.js?v=20260320"></script>
<script nonce="<?php echo $nonce; ?>" src="<?php echo $GLOBALS['config']['ASSETS_URL']; ?>/js/dashboard.js?v=20260320"></script>
<script nonce="<?php echo $nonce; ?>">
// CSRF Token for AJAX requests
window.CSRF_TOKEN = '<?php echo CsrfMiddleware::getToken(); ?>';
@@ -48,7 +48,7 @@ $nonce = SecurityHeadersMiddleware::getNonce();
<div class="ascii-frame-inner">
<div class="ticket-header">
<h2>New Ticket Form</h2>
<p style="color: var(--terminal-green); font-family: var(--font-mono); font-size: 0.9rem; margin-top: 0.5rem;">
<p class="form-hint">
Complete the form below to create a new ticket
</p>
</div>
@@ -90,7 +90,7 @@ $nonce = SecurityHeadersMiddleware::getNonce();
<?php endforeach; ?>
<?php endif; ?>
</select>
<p style="color: var(--terminal-green); font-size: 0.85rem; margin-top: 0.5rem; font-family: var(--font-mono);">
<p class="form-hint">
Select a template to auto-fill form fields
</p>
</div>
@@ -109,8 +109,8 @@ $nonce = SecurityHeadersMiddleware::getNonce();
<input type="text" id="title" name="title" class="editable" required placeholder="Enter a descriptive title for this ticket">
</div>
<!-- Duplicate Warning Area -->
<div id="duplicateWarning" class="inline-warning" role="alert" aria-live="polite" aria-atomic="true" style="display: none; margin-top: 1rem;">
<div style="color: var(--terminal-amber); font-weight: bold; margin-bottom: 0.5rem;">
<div id="duplicateWarning" class="inline-warning" role="alert" aria-live="polite" aria-atomic="true" style="display: none;">
<div class="text-amber fw-bold duplicate-heading">
Possible Duplicates Found
</div>
<div id="duplicatesList" aria-live="polite"></div>
@@ -185,7 +185,7 @@ $nonce = SecurityHeadersMiddleware::getNonce();
<?php endforeach; ?>
<?php endif; ?>
</select>
<p style="color: var(--terminal-green); font-size: 0.85rem; margin-top: 0.5rem; font-family: var(--font-mono);">
<p class="form-hint">
Select a user to assign this ticket to
</p>
</div>
@@ -206,13 +206,13 @@ $nonce = SecurityHeadersMiddleware::getNonce();
<option value="internal">Internal - Specific groups only</option>
<option value="confidential">Confidential - Creator, assignee, admins only</option>
</select>
<p style="color: var(--terminal-green); font-size: 0.85rem; margin-top: 0.5rem; font-family: var(--font-mono);">
<p class="form-hint">
Controls who can view this ticket
</p>
</div>
<div id="visibilityGroupsContainer" class="detail-group" style="display: none; margin-top: 1rem;">
<div id="visibilityGroupsContainer" class="detail-group" style="display: none;">
<label>Allowed Groups</label>
<div class="visibility-groups-list" style="display: flex; flex-wrap: wrap; gap: 0.75rem; margin-top: 0.5rem;">
<div class="visibility-groups-list">
<?php
// Get all available groups
require_once __DIR__ . '/../models/UserModel.php';
@@ -220,16 +220,16 @@ $nonce = SecurityHeadersMiddleware::getNonce();
$allGroups = $userModel->getAllGroups();
foreach ($allGroups as $group):
?>
<label style="display: flex; align-items: center; gap: 0.5rem; cursor: pointer;">
<label class="group-checkbox-label">
<input type="checkbox" name="visibility_groups[]" value="<?php echo htmlspecialchars($group); ?>" class="visibility-group-checkbox">
<span class="group-badge"><?php echo htmlspecialchars($group); ?></span>
</label>
<?php endforeach; ?>
<?php if (empty($allGroups)): ?>
<span style="color: var(--text-muted);">No groups available</span>
<span class="text-muted">No groups available</span>
<?php endif; ?>
</div>
<p style="color: var(--terminal-amber); font-size: 0.85rem; margin-top: 0.5rem; font-family: var(--font-mono);">
<p class="form-hint-warning">
Select which groups can view this ticket
</p>
</div>
@@ -288,8 +288,7 @@ $nonce = SecurityHeadersMiddleware::getNonce();
});
function checkForDuplicates(title) {
fetch('/api/check_duplicates.php?title=' + encodeURIComponent(title))
.then(response => response.json())
lt.api.get('/api/check_duplicates.php?title=' + encodeURIComponent(title))
.then(data => {
const warningDiv = document.getElementById('duplicateWarning');
const listDiv = document.getElementById('duplicatesList');
@@ -352,6 +351,8 @@ $nonce = SecurityHeadersMiddleware::getNonce();
toggleVisibilityGroups();
}
});
if (window.lt) lt.keys.initDefaults();
</script>
</body>
</html>