accessibility stuff, printing, search

This commit is contained in:
2025-03-25 16:07:13 +11:00
parent e8e80eede9
commit c19c907812
3 changed files with 689 additions and 26 deletions

View File

@@ -13,45 +13,49 @@
</head> </head>
<body> <body>
<!-- Add skip to content link -->
<a href="#document-content" class="skip-to-content">Skip to content</a>
<div class="container"> <div class="container">
<div class="title-bar"> <div class="title-bar" role="banner">
<button class="menu-button" aria-label="Toggle Menu"> <button class="menu-button" aria-label="Toggle Menu" aria-expanded="false" aria-controls="left-sidebar">
<i class="fas fa-bars"></i> <i class="fas fa-bars" aria-hidden="true"></i>
</button> </button>
<div class="title-text"> <div class="title-text">
<img src="./img/logo.png" alt="Litruv" class="brand-logo"> <img src="./img/logo.png" alt="Litruv" class="brand-logo">
<span class="divider">/</span> <span class="divider" aria-hidden="true">/</span>
<span class="page-title">Documentation</span> <span class="page-title">Documentation</span>
</div> </div>
<span style="width: 24px;"></span> <span style="width: 24px;"></span>
</div> </div>
<div class="content-container"> <div class="content-container">
<nav class="sidebar left-sidebar"> <nav class="sidebar left-sidebar" id="left-sidebar" role="navigation" aria-label="Main Navigation">
<div class="search-container"> <div class="search-container">
<div class="search-box"> <div class="search-box" role="search">
<i class="fas fa-search"></i> <i class="fas fa-search" aria-hidden="true"></i>
<input type="text" id="search-input" placeholder="Search docs..."> <input type="text" id="search-input" placeholder="Search docs..." aria-label="Search documentation">
<i class="fas fa-times" id="clear-search"></i> <div class="keyboard-shortcut keyboard-shortcut-alt" aria-hidden="true">Alt+S</div>
<i class="fas fa-times" id="clear-search" aria-label="Clear search"></i>
</div> </div>
<div id="search-results"></div> <div id="search-results" role="region" aria-label="Search results" aria-live="polite"></div>
</div> </div>
<div id="file-index"></div> <div id="file-index" role="tree" aria-label="Documentation files"></div>
<div class="subtitle"> <div class="subtitle" aria-label="Author information">
<span class="name"></span> <span class="name"></span>
<span class="role"></span> <span class="role"></span>
</div> </div>
<div class="social-links"></div> <div class="social-links" aria-label="Social media links"></div>
<div class="github-link"> <div class="github-link">
<a href="https://github.com/litruv/docs" target="_blank" title="Docs Viewer GitHub"> <a href="https://github.com/litruv/docs" target="_blank" title="Docs Viewer GitHub" aria-label="GitHub repository for Docs Viewer">
<i class="fab fa-github"></i> Docs Viewer <i class="fab fa-github" aria-hidden="true"></i> Docs Viewer
</a> </a>
</div> </div>
</nav> </nav>
<main class="content"> <main class="content" role="main" aria-label="Document Content">
<div id="document-content"></div> <div id="document-content" tabindex="-1"></div>
</main> </main>
<nav class="sidebar right-sidebar"> <nav class="sidebar right-sidebar" role="navigation" aria-label="Table of Contents">
<div id="document-outline"></div> <div id="document-outline" role="tree" aria-label="Document outline"></div>
</nav> </nav>
</div> </div>
</div> </div>
@@ -61,5 +65,115 @@
hljs.highlightAll(); hljs.highlightAll();
</script> </script>
<script src="index.js"></script> <script src="index.js"></script>
<!-- Print title capture script -->
<script>
// Capture page title for printing
window.addEventListener('beforeprint', function() {
// Get the current page title
const pageTitle = document.querySelector('.title-text .page-title').textContent;
const brandLogo = document.querySelector('.brand-logo').cloneNode(true);
// Create print header with logo
const printHeader = document.createElement('div');
printHeader.className = 'print-header';
// Add the logo image
printHeader.appendChild(brandLogo);
// Add the divider and page title
const titleText = document.createElement('div');
titleText.className = 'print-title-text';
titleText.innerHTML = `<span class="divider">/</span> <span class="page-title">${pageTitle}</span>`;
printHeader.appendChild(titleText);
// Insert at the beginning of content
const content = document.getElementById('document-content');
if (content.firstChild) {
content.insertBefore(printHeader, content.firstChild);
} else {
content.appendChild(printHeader);
}
// Remove any existing print elements to avoid duplication
const existingTitle = document.querySelector('.print-title');
if (existingTitle) existingTitle.remove();
// Make sure the print header is accessible
brandLogo.setAttribute('alt', 'Litruv logo');
printHeader.setAttribute('aria-hidden', 'true'); // Hide from screen readers when printing
});
// Clean up after printing
window.addEventListener('afterprint', function() {
const printHeader = document.querySelector('.print-header');
if (printHeader) {
printHeader.remove();
}
});
</script>
<!-- Add accessibility enhancements script -->
<script>
// Enhance keyboard navigation
document.addEventListener('DOMContentLoaded', function() {
// Make folders and navigation keyboard accessible
function enhanceTreeKeyboardNavigation() {
const folders = document.querySelectorAll('.folder-header');
const links = document.querySelectorAll('#file-index a, #document-outline a');
folders.forEach(folder => {
// Add ARIA attributes
const folderDiv = folder.closest('.folder');
const isOpen = folderDiv.classList.contains('open');
folder.setAttribute('role', 'treeitem');
folder.setAttribute('aria-expanded', isOpen ? 'true' : 'false');
// Handle keyboard events
folder.addEventListener('keydown', function(e) {
if (e.key === 'Enter' || e.key === ' ') {
e.preventDefault();
folder.click();
folder.setAttribute('aria-expanded',
folderDiv.classList.contains('open') ? 'true' : 'false');
}
});
folder.setAttribute('tabindex', '0');
});
links.forEach(link => {
link.setAttribute('role', 'treeitem');
});
}
// Handle menu button accessibility
const menuButton = document.querySelector('.menu-button');
if (menuButton) {
menuButton.addEventListener('click', function() {
const expanded = document.querySelector('.left-sidebar').classList.contains('show');
menuButton.setAttribute('aria-expanded', expanded ? 'true' : 'false');
});
}
// If using a MutationObserver to watch for DOM changes, call enhanceTreeKeyboardNavigation
// after the navigation tree is populated
const observer = new MutationObserver(function(mutations) {
mutations.forEach(function(mutation) {
if (mutation.addedNodes.length) {
enhanceTreeKeyboardNavigation();
}
});
});
observer.observe(document.getElementById('file-index'), {
childList: true,
subtree: true
});
// Initially enhance any existing navigation
enhanceTreeKeyboardNavigation();
});
</script>
</body> </body>
</html> </html>

129
index.js
View File

@@ -193,8 +193,10 @@ class DOMService {
} }
setupMobileMenu() { setupMobileMenu() {
this.elements.menuButton.addEventListener('click', () => this.elements.menuButton.addEventListener('click', () => {
this.elements.leftSidebar.classList.toggle('show')); const isExpanded = this.elements.leftSidebar.classList.toggle('show');
this.elements.menuButton.setAttribute('aria-expanded', isExpanded ? 'true' : 'false');
});
this.elements.content.addEventListener('click', () => this.elements.content.addEventListener('click', () =>
this.elements.leftSidebar.classList.remove('show')); this.elements.leftSidebar.classList.remove('show'));
@@ -224,6 +226,9 @@ class DOMService {
const folderHeader = document.createElement('div'); const folderHeader = document.createElement('div');
folderHeader.className = 'folder-header'; folderHeader.className = 'folder-header';
folderHeader.setAttribute('role', 'treeitem');
folderHeader.setAttribute('aria-expanded', doc.defaultOpen !== false ? 'true' : 'false');
folderHeader.setAttribute('tabindex', '0');
const iconClass = doc.icon || `fas fa-folder${doc.defaultOpen !== false ? '-open' : ''}`; const iconClass = doc.icon || `fas fa-folder${doc.defaultOpen !== false ? '-open' : ''}`;
// Only add folder click handler if showfolderpage is not false // Only add folder click handler if showfolderpage is not false
@@ -235,12 +240,22 @@ class DOMService {
// Only setup the folder open/close functionality // Only setup the folder open/close functionality
folderHeader.addEventListener('click', () => { folderHeader.addEventListener('click', () => {
folderDiv.classList.toggle('open'); folderDiv.classList.toggle('open');
const isExpanded = folderDiv.classList.contains('open');
folderHeader.setAttribute('aria-expanded', isExpanded ? 'true' : 'false');
if (!doc.icon) { if (!doc.icon) {
const icon = folderHeader.querySelector('.folder-icon'); const icon = folderHeader.querySelector('.folder-icon');
icon.classList.toggle('fa-folder-closed'); icon.classList.toggle('fa-folder-closed');
icon.classList.toggle('fa-folder-open'); icon.classList.toggle('fa-folder-open');
} }
}); });
// Add keyboard accessibility
folderHeader.addEventListener('keydown', (e) => {
if (e.key === 'Enter' || e.key === ' ') {
e.preventDefault();
folderHeader.click();
}
});
} }
const folderContent = document.createElement('div'); const folderContent = document.createElement('div');
@@ -261,6 +276,7 @@ class DOMService {
link.textContent = doc.title || doc.path.split('/').pop().replace('.md', ''); link.textContent = doc.title || doc.path.split('/').pop().replace('.md', '');
link.dataset.path = doc.path; link.dataset.path = doc.path;
link.style.paddingLeft = `${(level * 0.6) + 0.8}rem`; // Add base padding of 0.8rem link.style.paddingLeft = `${(level * 0.6) + 0.8}rem`; // Add base padding of 0.8rem
link.setAttribute('role', 'treeitem');
link.onclick = (e) => { link.onclick = (e) => {
e.preventDefault(); e.preventDefault();
@@ -304,19 +320,19 @@ class DOMService {
const showFolderPage = doc.showfolderpage !== 'false'; const showFolderPage = doc.showfolderpage !== 'false';
return ` return `
<div class="folder-icons"> <div class="folder-icons">
<i class="${iconClass} folder-icon"></i> <i class="${iconClass} folder-icon" aria-hidden="true"></i>
</div> </div>
<span>${doc.title}</pan> <span>${doc.title}</span>
${showFolderPage ? ` ${showFolderPage ? `
<a href="?${doc.slug}" class="folder-link" title="View folder page"> <a href="?${doc.slug}" class="folder-link" title="View folder page" aria-label="View ${doc.title} folder page">
<i class="fas fa-file-alt"></i> <i class="fas fa-file-alt" aria-hidden="true"></i>
</a>` : ''}`; </a>` : ''}`;
} }
createFolderHeaderBasic(iconClass, doc) { createFolderHeaderBasic(iconClass, doc) {
return ` return `
<div class="folder-icons"> <div class="folder-icons">
<i class="${iconClass} folder-icon"></i> <i class="${iconClass} folder-icon" aria-hidden="true"></i>
</div> </div>
<span>${doc.title}</span>`; <span>${doc.title}</span>`;
} }
@@ -334,12 +350,26 @@ class DOMService {
} }
folderDiv.classList.toggle('open'); folderDiv.classList.toggle('open');
const isExpanded = folderDiv.classList.contains('open');
folderHeader.setAttribute('aria-expanded', isExpanded ? 'true' : 'false');
if (!doc.icon) { if (!doc.icon) {
const icon = folderHeader.querySelector('.folder-icon'); const icon = folderHeader.querySelector('.folder-icon');
icon.classList.toggle('fa-folder-closed'); icon.classList.toggle('fa-folder-closed');
icon.classList.toggle('fa-folder-open'); icon.classList.toggle('fa-folder-open');
} }
}); });
// Add keyboard support
folderHeader.addEventListener('keydown', (e) => {
if (e.key === 'Enter' || e.key === ' ') {
e.preventDefault();
if (e.target.closest('.folder-link')) {
e.target.closest('.folder-link').click();
} else {
folderHeader.click();
}
}
});
} }
scrollToElement(element) { scrollToElement(element) {
@@ -425,6 +455,8 @@ class DOMService {
this.elements.searchInput.value = ''; this.elements.searchInput.value = '';
this.elements.searchResults.innerHTML = ''; this.elements.searchResults.innerHTML = '';
this.elements.searchResults.style.display = 'none'; this.elements.searchResults.style.display = 'none';
// Announce to screen readers
this.elements.searchResults.setAttribute('aria-hidden', 'true');
}); });
} }
@@ -434,9 +466,18 @@ class DOMService {
if (results.length === 0 || !this.elements.searchInput.value) { if (results.length === 0 || !this.elements.searchInput.value) {
container.style.display = 'none'; container.style.display = 'none';
container.setAttribute('aria-hidden', 'true');
return; return;
} }
// Update for screen readers
container.setAttribute('aria-hidden', 'false');
if (results.length === 1) {
container.setAttribute('aria-label', '1 search result found');
} else {
container.setAttribute('aria-label', `${results.length} search results found`);
}
results.forEach(result => { results.forEach(result => {
const div = document.createElement('div'); const div = document.createElement('div');
div.className = 'search-result'; div.className = 'search-result';
@@ -686,6 +727,7 @@ class Documentation {
this.navigationService = new NavigationService(this.eventBus, this.documentService); this.navigationService = new NavigationService(this.eventBus, this.documentService);
this.setupEventListeners(); this.setupEventListeners();
this.setupKeyboardShortcuts();
} }
setupEventListeners() { setupEventListeners() {
@@ -714,6 +756,79 @@ class Documentation {
}); });
} }
setupKeyboardShortcuts() {
// Add keyboard shortcut for search (S key)
document.addEventListener('keydown', (e) => {
// Only trigger if user is not typing in an input, textarea, or contenteditable element
const isTyping = ['INPUT', 'TEXTAREA'].includes(document.activeElement.tagName) ||
document.activeElement.isContentEditable;
// Search shortcut (S key or Alt+S)
if (((e.key === 's' || e.key === 'S') && !e.ctrlKey && !e.metaKey &&
(!e.altKey || (e.altKey && (e.key === 's' || e.key === 'S')))) &&
!isTyping) {
e.preventDefault();
// Focus the search input
const searchInput = document.getElementById('search-input');
if (searchInput) {
searchInput.focus();
// If sidebar is closed on mobile, open it
const leftSidebar = document.querySelector('.left-sidebar');
const menuButton = document.querySelector('.menu-button');
if (window.innerWidth <= 1000 && leftSidebar &&
!leftSidebar.classList.contains('show')) {
leftSidebar.classList.add('show');
if (menuButton) {
menuButton.setAttribute('aria-expanded', 'true');
}
}
}
}
// Navigation with Alt+Up/Down to move between pages
if ((e.key === 'ArrowUp' || e.key === 'ArrowDown') && e.altKey && !isTyping) {
e.preventDefault();
// Get all links from the file index
const fileLinks = Array.from(document.querySelectorAll('#file-index a'));
if (fileLinks.length === 0) return;
// Find the current active link
const activeLink = document.querySelector('#file-index a.active');
if (!activeLink) return;
// Find the index of the active link
const activeIndex = fileLinks.indexOf(activeLink);
if (activeIndex === -1) return;
// Determine the target link based on direction
let targetLink;
if (e.key === 'ArrowDown') {
// Go to next link (or first if at the end)
targetLink = activeIndex < fileLinks.length - 1 ?
fileLinks[activeIndex + 1] :
fileLinks[0];
} else {
// Go to previous link (or last if at the beginning)
targetLink = activeIndex > 0 ?
fileLinks[activeIndex - 1] :
fileLinks[fileLinks.length - 1];
}
// Navigate to the target page
if (targetLink) {
// Simulate a click on the link
targetLink.click();
// Ensure the target link is visible in the sidebar
targetLink.scrollIntoView({ block: 'nearest' });
}
}
});
}
async initialize() { async initialize() {
try { try {
const response = await fetch('index.json'); const response = await fetch('index.json');

View File

@@ -90,6 +90,7 @@ body {
cursor: pointer; cursor: pointer;
opacity: 0.6; opacity: 0.6;
transition: opacity 0.2s; transition: opacity 0.2s;
margin-left: 0;
} }
.search-box .fa-times:hover { .search-box .fa-times:hover {
@@ -692,3 +693,436 @@ social-links a:hover {
0% { background-color: rgba(52, 152, 219, 0.2); } 0% { background-color: rgba(52, 152, 219, 0.2); }
100% { background-color: transparent; } 100% { background-color: transparent; }
} }
/* Add a skip link for keyboard navigation */
.skip-to-content {
position: absolute;
top: -40px;
left: 0;
padding: 8px;
z-index: 2000;
background: var(--ifm-color-primary);
color: white;
font-weight: bold;
transition: top 0.2s;
}
.skip-to-content:focus {
top: 0;
outline: 2px solid white;
}
/* Improve focus styles for better keyboard navigation */
/* Remove the conflicting focus style rules */
/* Remove these conflicting rules */
*:focus {
outline: none !important;
}
*:focus-visible {
outline: 2px solid var(--ifm-color-primary) !important;
outline-offset: 2px !important;
}
a:focus,
button:focus,
input:focus,
.folder-header:focus,
.clickable-header:focus {
outline: none !important;
}
a:focus-visible,
button:focus-visible,
input:focus-visible,
.folder-header:focus-visible,
.clickable-header:focus-visible {
outline: none !important;
}
/* Add clean focus style rules */
/* This allows keyboard focus to be visible but hides it for mouse clicks */
:focus {
outline: none !important;
}
/* Only show focus styles for keyboard navigation */
:focus-visible {
outline: 2px solid var(--ifm-color-primary) !important;
outline-offset: 2px !important;
}
/* Force focus visible off for mouse interaction */
:focus:not(:focus-visible) {
outline: none !important;
}
/* Ensure contrast for links and interactive elements */
.folder-header:hover {
background-color: rgba(255, 255, 255, 0.05);
}
/* Keep the skip link visible when it gets focus */
.skip-to-content:focus {
top: 0;
outline: 2px solid white !important;
}
/* Don't hide keyboard focus styles on mobile */
@media (max-width: 1000px) {
:focus-visible {
outline: 2px solid var(--ifm-color-primary) !important;
}
.menu-button {
display: flex !important;
}
.left-sidebar {
left: -100%;
width: min(var(--doc-sidebar-width), 80vw);
transition: left 0.3s ease;
box-shadow: none;
}
.left-sidebar.show {
left: 0;
box-shadow: 2px 0 8px rgba(0, 0, 0, 0.2);
}
.right-sidebar {
display: none;
}
.content {
margin-left: 0;
margin-right: 0;
padding: 1rem;
}
.markdown-content {
padding: 0 0.5rem;
}
#file-index {
padding-top: 0.75rem;
}
}
/* Make sure aria-hidden elements aren't focusable */
[aria-hidden="true"] {
pointer-events: none;
}
/* Don't hide focus-visible on mobile */
@media (max-width: 1000px) {
*:focus-visible {
outline: 2px solid var(--ifm-color-primary) !important;
}
.menu-button {
display: flex !important;
}
.left-sidebar {
left: -100%;
width: min(var(--doc-sidebar-width), 80vw);
transition: left 0.3s ease;
box-shadow: none;
}
.left-sidebar.show {
left: 0;
box-shadow: 2px 0 8px rgba(0, 0, 0, 0.2);
}
.right-sidebar {
display: none;
}
.content {
margin-left: 0;
margin-right: 0;
padding: 1rem;
}
.markdown-content {
padding: 0 0.5rem;
}
#file-index {
padding-top: 0.75rem;
}
}
/* Style the keyboard shortcut indicator */
.keyboard-shortcut {
display: flex;
align-items: center;
justify-content: center;
width: 18px;
height: 18px;
border: 1px solid var(--ifm-color-content-secondary);
border-radius: 3px;
font-size: 0.75rem;
margin-right: 0.5rem;
color: var(--ifm-color-content-secondary);
opacity: 0.7;
user-select: none;
}
/* Style the Alt+S keyboard shortcut */
.keyboard-shortcut-alt {
width: auto;
padding: 0 4px;
font-size: 0.7rem;
}
/* Hide keyboard shortcut on mobile */
@media (max-width: 768px) {
.keyboard-shortcut {
display: none;
}
}
/* Print styles... */
@media print {
.title-bar,
.left-sidebar,
.right-sidebar,
.menu-button,
.social-links,
.github-link,
.subtitle {
display: none !important;
}
.content {
margin: 0 !important;
padding: 0 !important;
max-width: 100% !important;
}
.content-container {
margin: 0 !important;
}
body {
background: white !important;
color: black !important;
font-size: 12pt !important;
line-height: 1.5 !important;
margin: 0.25in !important; /* Reduced margins */
}
/* Remove the logo and redundant breadcrumb display */
.content-container::before,
.content-container::after {
display: none !important;
}
/* Simple print header */
.print-header {
display: block !important;
margin-bottom: 15pt;
border-bottom: 1pt solid #ddd;
padding-bottom: 8pt;
}
.print-header .site-name {
font-weight: bold;
font-size: 14pt;
}
.print-header .page-title {
font-size: 12pt;
color: #555;
}
.markdown-content {
padding: 0 !important;
font-size: 11pt !important;
line-height: 1.4 !important;
max-width: none !important;
}
.markdown-content a {
color: #000 !important;
text-decoration: underline !important;
word-wrap: break-word !important;
}
.markdown-content a[href^="http"]:after {
content: " (" attr(href) ")";
font-size: 9pt;
color: #555;
}
.markdown-content pre,
.markdown-content code {
white-space: pre-wrap !important;
border: 1px solid #ddd !important;
page-break-inside: avoid !important;
background-color: #f5f5f5 !important;
color: #000 !important;
}
.markdown-content img {
max-width: 100% !important;
page-break-inside: avoid !important;
border: none !important;
box-shadow: none !important;
}
.markdown-content h1,
.markdown-content h2,
.markdown-content h3,
.markdown-content h4,
.markdown-content h5,
.markdown-content h6 {
page-break-after: avoid !important;
break-after: avoid !important;
color: #000 !important;
}
.markdown-content p,
.markdown-content ul,
.markdown-content ol,
.markdown-content table {
page-break-inside: avoid !important;
}
.markdown-content h1 {
font-size: 20pt !important;
margin: 20pt 0 15pt 0 !important;
}
.markdown-content h2 {
font-size: 16pt !important;
margin: 16pt 0 10pt 0 !important;
}
.markdown-content h3 {
font-size: 14pt !important;
margin: 14pt 0 8pt 0 !important;
}
.markdown-content p,
.markdown-content ul,
.markdown-content ol {
margin: 6pt 0 !important;
}
.markdown-content pre,
.markdown-content blockquote {
margin: 10pt 0 !important;
padding: 8pt 10pt !important;
border-left: 4pt solid #ddd !important;
background-color: #f8f8f8 !important;
}
.markdown-content table {
margin: 10pt 0 !important;
font-size: 10pt !important;
border-collapse: collapse !important;
width: 100% !important;
border: 1px solid #ddd !important;
}
.markdown-content td,
.markdown-content th {
padding: 6pt 8pt !important;
border: 1px solid #ddd !important;
background-color: #fff !important;
}
.markdown-content th {
background-color: #f0f0f0 !important;
font-weight: bold !important;
}
/* Fix clickable header styles for print */
.clickable-header:hover {
color: inherit !important;
}
/* Add page breaks before major sections */
.markdown-content h1 {
page-break-before: always !important;
}
/* First h1 shouldn't have a page break before it */
.markdown-content h1:first-child {
page-break-before: avoid !important;
}
/* Hide interactive elements */
.markdown-content video,
.markdown-content .header-anchor,
.markdown-content svg {
display: none !important;
}
/* Make URLs for links visible */
@page {
margin: 0.5in !important;
}
/* Simple print header with logo */
.print-header {
display: flex !important;
align-items: center;
margin-bottom: 15pt;
border-bottom: 1pt solid #ddd;
padding-bottom: 8pt;
}
/* Style the logo in print mode */
.print-header .brand-logo {
height: 30px;
width: auto;
display: block;
filter: brightness(0); /* Make logo black */
border-radius: 0 !important; /* Remove any border radius */
}
/* Style the title text section */
.print-header .print-title-text {
display: flex;
align-items: center;
}
.print-header .divider {
padding: 0 5px;
font-size: 14pt;
color: #555;
}
.print-header .page-title {
font-size: 14pt;
color: #333;
}
/* Remove the old print title elements */
.print-title,
.content-container::before,
.content-container::after {
display: none !important;
}
}
/* Add this rule to specifically remove the outline from the document content area when clicked */
#document-content:focus {
outline: none !important;
}
/* But keep it for keyboard navigation */
#document-content:focus-visible {
outline: 2px solid var(--ifm-color-primary) !important;
outline-offset: 2px !important;
}
/* Also make sure any other clickable elements in the document content don't get outlines */
#document-content *:focus:not(:focus-visible) {
outline: none !important;
}