header
<!-- ================== NAVBAR ================== --> <header> <nav class="navbar navbar-expand-md navbar-dark bg-dark fixed-top"> <div class="container-fluid"> <a class="navbar-brand" href="#">Company</a> <button class="btn btn-outline-light d-lg-none me-2" type="butto +n" data-bs-toggle="offcanvas" data-bs-target="#mobileSidebar"> &#9776; </button> <button class="navbar-toggler" type="button" data-bs-toggle="col +lapse" data-bs-target="#navbarCollapse"> <span class="navbar-toggler-icon"></span> </button> <div class="collapse navbar-collapse" id="navbarCollapse"> <ul class="navbar-nav me-auto mb-2 mb-md-0"> <li class="nav-item"><a class="nav-link active" href="#">Hom +e</a></li> <li class="nav-item"><a class="nav-link" href="#">Link</a></ +li> <li class="nav-item"><a class="nav-link disabled">Disabled</ +a></li> </ul> <div class="d-flex align-items-center"> <!-- THEME SWITCHER --> <div class="dropdown me-3"> <button class="btn btn-secondary d-flex align-items-center +" id="themeSwitcher" type="button" data-bs-toggle="dropdown"> <svg class="bi my-1 theme-icon" width="1em" height="1em" +> <use href="#circle-half"></use> </svg> <span class="visually-hidden">Toggle theme</span> </button> <ul class="dropdown-menu dropdown-menu-end shadow" aria-la +belledby="themeSwitcher"> <li><button class="dropdown-item d-flex align-items-cent +er" data-theme="light"><svg class="bi me-2" width="1em" height="1em"> +<use href="#sun-fill"></use></svg> Light</button></li> <li><button class="dropdown-item d-flex align-items-cent +er" data-theme="dark"><svg class="bi me-2" width="1em" height="1em">< +use href="#moon-stars-fill"></use></svg> Dark</button></li> <li><button class="dropdown-item d-flex align-items-cent +er" data-theme="auto"><svg class="bi me-2" width="1em" height="1em">< +use href="#circle-half"></use></svg> Auto</button></li> <li><button class="dropdown-item d-flex align-items-cent +er" data-theme="lightblue"><svg class="bi me-2" width="1em" height="1 +em"><use href="#circle-half"></use></svg> Light Blue</button></li> <li><button class="dropdown-item d-flex align-items-cent +er" data-theme="highcontrast"><svg class="bi me-2" width="1em" height +="1em"><use href="#circle-half"></use></svg> High Contrast</button></ +li> </ul> </div> <!-- SEARCH --> <form class="d-flex" role="search"> <input class="form-control me-2" type="search" placeholder +="Search"> <button class="btn btn-outline-success" type="submit">Sear +ch</button> </form> </div> </div> </div> </nav> </header>
[download]
sidebar
<!-- ================== DESKTOP SIDEBAR ================== --> <nav class="sidebar bg-body-tertiary border-end sidebar-desktop d-none + d-lg-block"> <ul class="nav flex-column"> <li class="nav-item"><a class="nav-link active" href="#">Dashboard +</a></li> <li class="nav-item"><a class="nav-link" href="#">Orders</a></li> <li class="nav-item"><a class="nav-link" href="#">Products</a></li +> <li class="nav-item"><a class="nav-link" href="#">Customers</a></l +i> </ul> </nav> <!-- MOBILE OFFCANVAS SIDEBAR --> <div class="offcanvas offcanvas-start d-lg-none" tabindex="-1" id="mob +ileSidebar"> <div class="offcanvas-header"> <h5 class="offcanvas-title">Menu</h5> <button type="button" class="btn-close" data-bs-dismiss="offcanvas +"></button> </div> <div class="offcanvas-body"> <ul class="nav flex-column"> <li class="nav-item"><a class="nav-link active" href="#">Dashboa +rd</a></li> <li class="nav-item"><a class="nav-link" href="#">Orders</a></li +> <li class="nav-item"><a class="nav-link" href="#">Products</a></ +li> <li class="nav-item"><a class="nav-link" href="#">Customers</a>< +/li> </ul> </div> </div>
[download]
body content
<main> <div class="bg-body-tertiary p-5 rounded"> <h1><%= stash('title') || 'Main Content' %></h1> <p class="lead"> Responsive dashboard with Light, Dark, Auto, Light Blue, and Hig +h Contrast themes. </p> </div> </main>
[download]
layout
<!doctype html> <html lang="en"> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title><%= title %></title> <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bo +otstrap.min.css" rel="stylesheet"> <style> <%== $css %> <!-- optionally move the CSS into a variable if neede +d --> </style> </head> <body> %= include '_header' %= include '_sidebar' <main class="pt-4"> <%= content %> </main> <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bo +otstrap.bundle.min.js"></script> <!-- Your theme-switcher JS --> <%== $js %> <!-- ICON SYMBOLS --> <%== $icons %> </body> </html>
[download]
default
% layout 'default'; % title 'Dashboard'; %= include '_content'
[download]
index.ep
% layout 'default'; % title 'Dashboard'; %= include '_content'
[download]
templates/ layouts/ default.html.ep _header.html.ep _sidebar.html.ep _content.html.ep index.html.ep
[download]
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>Search Screen</title> <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootst +rap.min.css" rel="stylesheet" > </head> <body class="bg-light"> <div class="container py-4"> <h3 class="mb-4">Document Search</h3> <form class="card p-4 shadow-sm bg-white"> <!-- ROW 1 — DATE MOVED UP --> <div class="row g-3"> <!-- Date --> <div class="col-md-4"> <label class="form-label" for="createdFrom">Date</label> <input id="createdFrom" type="date" class="form-control"> </div> <!-- End Date (hidden initially) --> <div class="col-md-4" id="endDateCol" style="display: none;"> <label class="form-label" for="createdTo">End Date</label> <input id="createdTo" type="date" class="form-control"> </div> <!-- Before/After Selector (hidden initially) --> <div class="col-md-4" id="beforeAfterContainer" style="display:n +one;"> <label class="form-label" for="dateOption">Option</label> <select id="dateOption" class="form-select"> <option value="">(none)</option> <option value="before">Before</option> <option value="after">After</option> </select> </div> </div> <!-- ROW 2 — Toggles for Date --> <div class="row mt-3 g-3"> <div class="col-md-4"> <div class="form-check form-switch"> <input class="form-check-input" type="checkbox" id="toggleEn +dDate"> <label class="form-check-label" for="toggleEndDate">Use end +date</label> </div> </div> <div class="col-md-4"> <div class="form-check form-switch"> <input class="form-check-input" type="checkbox" id="toggleBe +foreAfter"> <label class="form-check-label" for="toggleBeforeAfter">Use +before/after</label> </div> </div> </div> <!-- ROW 3 — Document Number + Document Type + (SUB TYPE MOVED DOW +N) --> <div class="row g-3 mt-4"> <div class="col-md-4"> <label class="form-label" for="docNumber">Document Number</lab +el> <input id="docNumber" class="form-control" type="text" placeho +lder="Enter number"> </div> <div class="col-md-4"> <label class="form-label" for="docType">Document Type</label> <select id="docType" class="form-select"> <option selected disabled>Choose...</option> <option>Report</option> <option>Invoice</option> <option>Contract</option> <option>Memo</option> </select> </div> <!-- SUB TYPE MOVED HERE --> <div class="col-md-4"> <label class="form-label" for="docSubType">Document Sub-Type</ +label> <select id="docSubType" class="form-select"> <option selected disabled>Choose...</option> <option>Internal</option> <option>External</option> <option>Confidential</option> </select> </div> </div> <!-- ROW 4 --> <div class="row g-3 mt-1"> <div class="col-md-8"> <label class="form-label" for="title">Title</label> <input id="title" class="form-control" type="text" placeholder +="Enter title keywords"> </div> <div class="col-md-4"> <label class="form-label" for="author">Author</label> <input id="author" class="form-control" type="text" placeholde +r="Author name"> </div> </div> <!-- Buttons --> <div class="mt-4 d-flex justify-content-end gap-2"> <button type="reset" class="btn btn-outline-secondary">Clear</bu +tton> <button type="submit" class="btn btn-primary">Search</button> </div> </form> </div> <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/boot +strap.bundle.min.js"></script> <script> // ---- DATE BEHAVIOR LOGIC ---- const toggleEndDate = document.getElementById("toggleEndDate"); const toggleBeforeAfter = document.getElementById("toggleBeforeAfter") +; const endDateCol = document.getElementById("endDateCol"); const beforeAfterContainer = document.getElementById("beforeAfterConta +iner"); // Toggle: Use End Date toggleEndDate.addEventListener("change", () => { if (toggleEndDate.checked) { toggleBeforeAfter.checked = false; beforeAfterContainer.style.display = "none"; endDateCol.style.display = "block"; } else { endDateCol.style.display = "none"; } }); // Toggle: Use Before/After toggleBeforeAfter.addEventListener("change", () => { if (toggleBeforeAfter.checked) { toggleEndDate.checked = false; endDateCol.style.display = "none"; beforeAfterContainer.style.display = "block"; } else { beforeAfterContainer.style.display = "none"; } }); </script> </body> </html>
[download]
<!doctype html> <html lang="en"> <head> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1" +/> <title>Dyslexic Mode Bootstrap Demo</title> <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bo +otstrap.min.css" rel="stylesheet" /> <style> /* Load local OpenDyslexic font */ @font-face { font-family: 'OpenDyslexic'; src: url('fonts/OpenDyslexic.woff') format('woff'); font-weight: normal; font-style: normal; } /* Dyslexia modes: font and text styling */ html.dyslexia, html.dyslexia-dark { font-family: 'OpenDyslexic', sans-serif !important; letter-spacing: 0.12em; word-spacing: 0.16em; line-height: 1.5; } /* Extend font to form and UI components */ html.dyslexia input, html.dyslexia textarea, html.dyslexia select, html.dyslexia button, html.dyslexia .form-control, html.dyslexia .dropdown-menu, html.dyslexia .dropdown-toggle, html.dyslexia-dark input, html.dyslexia-dark textarea, html.dyslexia-dark select, html.dyslexia-dark button, html.dyslexia-dark .form-control, html.dyslexia-dark .dropdown-menu, html.dyslexia-dark .dropdown-toggle { font-family: 'OpenDyslexic', sans-serif !important; } /* Light background for dyslexia mode */ html.dyslexia { background-color: #ffffff; color: #212529; } /* Dark theme for dyslexia mode */ html.dyslexia-dark { background-color: #121212; color: #f1f1f1; } html.dyslexia-dark .navbar { background-color: #1f1f1f !important; } html.dyslexia-dark .navbar .nav-link, html.dyslexia-dark .navbar-brand { color: #f1f1f1 !important; } html.dyslexia-dark .dropdown-menu { background-color: #2c2c2c; color: #f1f1f1; border-color: #444; } html.dyslexia-dark .dropdown-item { color: #f1f1f1; } html.dyslexia-dark .dropdown-item:hover { background-color: #3a3a3a; color: #ffffff; } html.dyslexia-dark .modal-content { background-color: #2a2a2a; color: #f1f1f1; } html.dyslexia-dark .alert { background-color: #2c2c2c; border-color: #444; color: #f1f1f1; } </style> </head> <body> <nav class="navbar navbar-expand-lg bg-body-tertiary"> <div class="container-fluid"> <a class="navbar-brand" href="#">Demo</a> <button class="navbar-toggler" type="button" data-bs-toggle="col +lapse" data-bs-target="#navbarContent"> <span class="navbar-toggler-icon"></span> </button> <div class="collapse navbar-collapse" id="navbarContent"> <ul class="navbar-nav me-auto mb-2 mb-lg-0"> <li class="nav-item"><a class="nav-link active" href="#">Hom +e</a></li> <li class="nav-item dropdown"> <a class="nav-link dropdown-toggle" href="#" role="button" + data-bs-toggle="dropdown">Menu</a> <ul class="dropdown-menu"> <li><a class="dropdown-item" href="#">Action</a></li> <li><a class="dropdown-item" href="#">Another action</a> +</li> </ul> </li> </ul> <!-- Right aligned: theme dropdown then search --> <div class="d-flex align-items-center ms-auto"> <div class="dropdown me-3"> <button class="btn btn-outline-secondary dropdown-toggle" +id="mode-selector" data-bs-toggle="dropdown"> Mode: <span id="current-mode">Auto</span> </button> <ul class="dropdown-menu dropdown-menu-end"> <li><button class="dropdown-item" data-mode="light">Ligh +t</button></li> <li><button class="dropdown-item" data-mode="dark">Dark< +/button></li> <li><button class="dropdown-item" data-mode="auto">Auto< +/button></li> <li><hr class="dropdown-divider" /></li> <li><button class="dropdown-item" data-mode="dyslexia">D +yslexic</button></li> <li><button class="dropdown-item" data-mode="dyslexia-da +rk">Dyslexic Dark</button></li> </ul> </div> <form class="d-flex ms-3" role="search"> <input class="form-control me-2" type="search" placeholder +="Search..." /> <button class="btn btn-outline-success" type="submit">Sear +ch</button> </form> </div> </div> </div> </nav> <main class="container py-5"> <h1>Welcome</h1> <p>This page supports dyslexic-friendly light and dark modes using + the local OpenDyslexic font.</p> <div class="alert alert-warning" role="alert"> This is a dyslexic-friendly alert box. </div> <button class="btn btn-primary" data-bs-toggle="modal" data-bs-tar +get="#exampleModal"> Launch Modal </button> </main> <!-- Modal --> <div class="modal fade" id="exampleModal" tabindex="-1" aria-labelle +dby="exampleModalLabel" aria-hidden="true"> <div class="modal-dialog"> <div class="modal-content"> <div class="modal-header"> <h5 class="modal-title" id="exampleModalLabel">Modal Title</ +h5> <button type="button" class="btn-close" data-bs-dismiss="mod +al" aria-label="Close"></button> </div> <div class="modal-body"> This modal also uses the OpenDyslexic font in all supported +modes. </div> <div class="modal-footer"> <button type="button" class="btn btn-secondary" data-bs-dism +iss="modal">Close</button> <button type="button" class="btn btn-primary">Save changes</ +button> </div> </div> </div> </div> <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bo +otstrap.bundle.min.js"></script> <script> (() => { const current = document.getElementById('current-mode'); const storageKey = 'preferredMode'; const setModeLabel = (mode, sysMode = '') => { if (mode === 'auto') { current.textContent = 'Auto (' + sysMode.charAt(0).toUpperCa +se() + sysMode.slice(1) + ')'; } else if (mode === 'dyslexia-dark') { current.textContent = 'Dyslexic Dark'; } else { current.textContent = mode.charAt(0).toUpperCase() + mode.sl +ice(1); } }; const applyMode = (mode, manual = true) => { const html = document.documentElement; html.classList.remove('dyslexia', 'dyslexia-dark'); html.removeAttribute('data-bs-theme'); if (mode === 'dyslexia') { html.classList.add('dyslexia'); setModeLabel('dyslexia'); } else if (mode === 'dyslexia-dark') { html.classList.add('dyslexia-dark'); setModeLabel('dyslexia-dark'); } else if (mode === 'dark' || mode === 'light') { html.setAttribute('data-bs-theme', mode); setModeLabel(mode); } else if (mode === 'auto') { const sysMode = window.matchMedia('(prefers-color-scheme: da +rk)').matches ? 'dark' : 'light'; html.setAttribute('data-bs-theme', sysMode); setModeLabel('auto', sysMode); } if (manual) localStorage.setItem(storageKey, mode); }; const savedMode = localStorage.getItem(storageKey) || 'auto'; applyMode(savedMode, false); document.querySelectorAll('[data-mode]').forEach((btn) => { btn.addEventListener('click', () => { const mode = btn.getAttribute('data-mode'); applyMode(mode); }); }); window.matchMedia('(prefers-color-scheme: dark)').addEventListen +er('change', (e) => { const saved = localStorage.getItem(storageKey); if (saved === 'auto') { const newMode = e.matches ? 'dark' : 'light'; document.documentElement.setAttribute('data-bs-theme', newMo +de); setModeLabel('auto', newMode); } }); })(); </script> </body> </html>
[download]