Files
michaelschiemer/resources/css/admin/07-utilities/_accessibility.css
Michael Schiemer fc3d7e6357 feat(Production): Complete production deployment infrastructure
- Add comprehensive health check system with multiple endpoints
- Add Prometheus metrics endpoint
- Add production logging configurations (5 strategies)
- Add complete deployment documentation suite:
  * QUICKSTART.md - 30-minute deployment guide
  * DEPLOYMENT_CHECKLIST.md - Printable verification checklist
  * DEPLOYMENT_WORKFLOW.md - Complete deployment lifecycle
  * PRODUCTION_DEPLOYMENT.md - Comprehensive technical reference
  * production-logging.md - Logging configuration guide
  * ANSIBLE_DEPLOYMENT.md - Infrastructure as Code automation
  * README.md - Navigation hub
  * DEPLOYMENT_SUMMARY.md - Executive summary
- Add deployment scripts and automation
- Add DEPLOYMENT_PLAN.md - Concrete plan for immediate deployment
- Update README with production-ready features

All production infrastructure is now complete and ready for deployment.
2025-10-25 19:18:37 +02:00

334 lines
8.3 KiB
CSS
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* Accessibility Utilities - Admin Interface
*
* WCAG 2.1 AA Compliance:
* - Enhanced focus indicators (minimum 2px outline, 3:1 contrast)
* - Skip links and screen reader utilities
* - Reduced motion preferences
* - Keyboard navigation enhancements
*/
@layer admin-utilities {
/**
* Focus Visible Enhancement (WCAG 2.1 Level AA)
*
* Requirement: 2.4.7 Focus Visible - All focusable elements
* must have a visible focus indicator with min 3:1 contrast ratio.
*/
:focus-visible {
outline: var(--admin-focus-ring-width, 2px) solid var(--admin-focus-ring);
outline-offset: var(--admin-focus-ring-offset, 2px);
border-radius: var(--admin-radius-sm);
}
/**
* Skip to Content Link (WCAG 2.4.1)
*
* Requirement: Bypass Blocks - Provide a mechanism to bypass
* repeated navigation blocks.
*/
.admin-skip-link {
position: absolute;
top: -9999px;
left: -9999px;
z-index: var(--admin-z-toast);
padding: var(--admin-spacing-md) var(--admin-spacing-lg);
background-color: var(--admin-accent-primary);
color: white;
text-decoration: none;
font-weight: var(--admin-font-weight-semibold);
border-radius: var(--admin-radius-md);
box-shadow: var(--admin-shadow-lg);
&:focus {
top: var(--admin-spacing-md);
left: var(--admin-spacing-md);
}
}
/**
* Screen Reader Only
*
* Visually hidden but accessible to screen readers.
*/
.sr-only,
.admin-sr-only,
.visually-hidden {
position: absolute;
width: 1px;
height: 1px;
padding: 0;
margin: -1px;
overflow: hidden;
clip: rect(0, 0, 0, 0);
white-space: nowrap;
border-width: 0;
}
/**
* Focus Visible for Not Screen Reader Only
*
* Show element when focused (for skip links).
*/
.sr-only-focusable:focus,
.sr-only-focusable:active {
position: static;
width: auto;
height: auto;
overflow: visible;
clip: auto;
white-space: normal;
}
/**
* Reduced Motion (WCAG 2.3.3)
*
* Respect user's motion preferences.
*/
@media (prefers-reduced-motion: reduce) {
*,
*::before,
*::after {
animation-duration: 0.01ms !important;
animation-iteration-count: 1 !important;
transition-duration: 0.01ms !important;
scroll-behavior: auto !important;
}
}
/**
* Focus Within Enhancement
*
* Show focus state for container when child is focused.
*/
.admin-nav__item:focus-within {
position: relative;
&::before {
content: '';
position: absolute;
left: -2px;
right: -2px;
top: -2px;
bottom: -2px;
border: 2px solid var(--admin-focus-ring);
border-radius: var(--admin-radius-md);
pointer-events: none;
}
}
/**
* Keyboard Navigation Indicator
*
* Show clear visual feedback for keyboard users.
*/
body.user-is-tabbing *:focus {
outline: 3px solid var(--admin-accent-info);
outline-offset: 3px;
}
/**
* High Contrast Mode Support
*
* Ensure borders are visible in Windows High Contrast Mode.
*/
@media (prefers-contrast: high) {
.admin-card,
.admin-sidebar,
.admin-header {
border: 2px solid currentColor;
}
button,
.admin-action-btn,
.admin-nav__link {
border: 2px solid currentColor !important;
}
}
/**
* Touch Target Size (WCAG 2.5.5 Level AAA, but good practice)
*
* Minimum 44x44px touch targets for mobile.
*/
@media (pointer: coarse) {
button,
a,
input[type="checkbox"],
input[type="radio"],
.admin-action-btn,
.admin-nav__link {
min-width: 44px;
min-height: 44px;
}
}
/**
* Accessible Color Contrast Helpers
*
* WCAG AA requires:
* - Normal text: 4.5:1 contrast ratio
* - Large text (18pt+): 3:1 contrast ratio
* - UI components: 3:1 contrast ratio
*/
.text-contrast-aa {
/* Ensures minimum 4.5:1 contrast */
color: var(--admin-content-text);
}
.text-contrast-large {
/* Large text can use lower contrast */
font-size: 1.125rem;
color: var(--admin-content-text);
opacity: 0.9;
}
/**
* Error Identification (WCAG 3.3.1)
*
* Errors must be communicated with more than just color.
*/
.admin-error,
.admin-form-error {
color: var(--admin-accent-error);
&::before {
content: '⚠ ';
font-weight: bold;
margin-right: 0.25rem;
}
}
[aria-invalid="true"] {
border-color: var(--admin-accent-error) !important;
border-width: 2px !important;
/* Error icon */
background-image: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="%23dc2626" stroke-width="2"><circle cx="12" cy="12" r="10"/><line x1="12" y1="8" x2="12" y2="12"/><line x1="12" y1="16" x2="12.01" y2="16"/></svg>');
background-repeat: no-repeat;
background-position: right 0.75rem center;
background-size: 1.25rem;
padding-right: 2.5rem;
}
/**
* Success/Warning States with Icons
*
* Not relying solely on color for state communication.
*/
.admin-success::before {
content: '✓ ';
font-weight: bold;
color: var(--admin-accent-success);
margin-right: 0.25rem;
}
.admin-warning::before {
content: '⚠ ';
font-weight: bold;
color: var(--admin-accent-warning);
margin-right: 0.25rem;
}
.admin-info::before {
content: ' ';
font-weight: bold;
color: var(--admin-accent-info);
margin-right: 0.25rem;
}
/**
* Accessible Button States
*/
button:disabled,
[aria-disabled="true"] {
opacity: 0.5;
cursor: not-allowed;
position: relative;
/* Pattern to indicate disabled state (not just opacity) */
&::after {
content: '';
position: absolute;
inset: 0;
background-image: repeating-linear-gradient(
45deg,
transparent,
transparent 5px,
oklch(0% 0 0 / 0.05) 5px,
oklch(0% 0 0 / 0.05) 10px
);
pointer-events: none;
}
}
/**
* Live Region Announcements
*
* For dynamic content updates.
*/
.admin-live-region {
position: absolute;
left: -10000px;
width: 1px;
height: 1px;
overflow: hidden;
}
[aria-live="polite"],
[aria-live="assertive"] {
/* Screen reader will announce these */
}
/**
* Accessible Table Improvements
*/
table {
caption {
font-weight: var(--admin-font-weight-semibold);
text-align: left;
padding: var(--admin-spacing-md);
background-color: var(--admin-bg-secondary);
}
th {
font-weight: var(--admin-font-weight-semibold);
text-align: left;
}
/* Zebra striping for better readability */
tbody tr:nth-child(even) {
background-color: var(--admin-bg-secondary);
}
}
/**
* Print Styles (Accessibility includes print)
*/
@media print {
.admin-sidebar,
.admin-header__actions,
.admin-mobile-overlay,
.admin-sidebar__mobile-toggle {
display: none !important;
}
.admin-content {
max-width: 100% !important;
padding: 0 !important;
}
a[href]::after {
content: " (" attr(href) ")";
font-size: 0.875em;
color: var(--admin-content-text);
}
/* Don't show internal links */
a[href^="#"]::after,
a[href^="javascript:"]::after {
content: "";
}
}
}