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">
☰
</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>
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>
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>
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>
default
% layout 'default';
% title 'Dashboard';
%= include '_content'
index.ep
% layout 'default';
% title 'Dashboard';
%= include '_content'
templates/
layouts/
default.html.ep
_header.html.ep
_sidebar.html.ep
_content.html.ep
index.html.ep
<!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>
<!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>