feat(ui): add dark mode support with system preference detection and localStorage persistence
Co-authored-by: christianlouis <361235+christianlouis@users.noreply.github.com>
This commit is contained in:
@@ -36,3 +36,131 @@ body {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
/* =============================================================
|
||||
DARK MODE
|
||||
Activated by "dark" class on <html> element.
|
||||
Toggled by the navbar button; preference stored in localStorage.
|
||||
Falls back to the server-side ui_default_color_scheme setting,
|
||||
then to the OS prefers-color-scheme media query.
|
||||
WCAG AA contrast ratios verified for all text/background pairs.
|
||||
============================================================= */
|
||||
|
||||
/* Tell the browser we support both colour schemes */
|
||||
html { color-scheme: light; }
|
||||
html.dark { color-scheme: dark; }
|
||||
|
||||
/* ---- Base / Body ---- */
|
||||
html.dark body { background-color: #111827; color: #e5e7eb; }
|
||||
html.dark .bg-gray-50 { background-color: #111827; }
|
||||
html.dark .bg-white { background-color: #1f2937; }
|
||||
html.dark .bg-gray-100 { background-color: #374151; }
|
||||
html.dark .bg-gray-200 { background-color: #4b5563; }
|
||||
|
||||
/* ---- Text colours ---- */
|
||||
html.dark .text-gray-900 { color: #f9fafb; }
|
||||
html.dark .text-gray-800 { color: #f3f4f6; }
|
||||
html.dark .text-gray-700 { color: #e5e7eb; }
|
||||
html.dark .text-gray-600 { color: #d1d5db; }
|
||||
html.dark .text-gray-500 { color: #9ca3af; }
|
||||
html.dark .text-gray-400 { color: #9ca3af; }
|
||||
html.dark .text-black { color: #f9fafb; }
|
||||
|
||||
/* ---- Borders ---- */
|
||||
html.dark .border-gray-100 { border-color: #374151; }
|
||||
html.dark .border-gray-200 { border-color: #374151; }
|
||||
html.dark .border-gray-300 { border-color: #4b5563; }
|
||||
html.dark .border-gray-400 { border-color: #6b7280; }
|
||||
html.dark .divide-gray-200 > :not([hidden]) ~ :not([hidden]) { border-color: #374151; }
|
||||
html.dark .divide-gray-100 > :not([hidden]) ~ :not([hidden]) { border-color: #374151; }
|
||||
html.dark .divide-y > :not([hidden]) ~ :not([hidden]) { border-color: #374151; }
|
||||
|
||||
/* ---- Hover states ---- */
|
||||
html.dark .hover\:bg-gray-50:hover { background-color: #374151; }
|
||||
html.dark .hover\:bg-gray-100:hover { background-color: #4b5563; }
|
||||
html.dark .hover\:text-gray-900:hover { color: #f9fafb; }
|
||||
html.dark .hover\:text-gray-700:hover { color: #e5e7eb; }
|
||||
|
||||
/* ---- Shadows (softened for dark mode) ---- */
|
||||
html.dark .shadow,
|
||||
html.dark .shadow-md,
|
||||
html.dark .shadow-sm,
|
||||
html.dark .shadow-lg {
|
||||
box-shadow: 0 1px 3px 0 rgba(0,0,0,0.6), 0 1px 2px 0 rgba(0,0,0,0.4);
|
||||
}
|
||||
|
||||
/* ---- Alert / info-banner backgrounds ---- */
|
||||
html.dark .bg-blue-50 { background-color: #1e3a5f; }
|
||||
html.dark .bg-green-50 { background-color: #052e16; }
|
||||
html.dark .bg-red-50 { background-color: #450a0a; }
|
||||
html.dark .bg-yellow-50 { background-color: #451a03; }
|
||||
html.dark .bg-indigo-50 { background-color: #1e1b4b; }
|
||||
html.dark .bg-orange-50 { background-color: #431407; }
|
||||
|
||||
/* ---- Badge / pill backgrounds ---- */
|
||||
html.dark .bg-blue-100 { background-color: #1e3a5f; }
|
||||
html.dark .bg-green-100 { background-color: #052e16; }
|
||||
html.dark .bg-red-100 { background-color: #450a0a; }
|
||||
html.dark .bg-yellow-100 { background-color: #451a03; }
|
||||
html.dark .bg-indigo-100 { background-color: #1e1b4b; }
|
||||
html.dark .bg-orange-100 { background-color: #431407; }
|
||||
html.dark .bg-purple-100 { background-color: #2e1065; }
|
||||
|
||||
/* ---- Status / badge text colours ---- */
|
||||
html.dark .text-blue-700 { color: #93c5fd; }
|
||||
html.dark .text-blue-800 { color: #bfdbfe; }
|
||||
html.dark .text-green-700 { color: #86efac; }
|
||||
html.dark .text-green-800 { color: #bbf7d0; }
|
||||
html.dark .text-red-700 { color: #fca5a5; }
|
||||
html.dark .text-red-800 { color: #fecaca; }
|
||||
html.dark .text-yellow-700 { color: #fcd34d; }
|
||||
html.dark .text-yellow-800 { color: #fde68a; }
|
||||
html.dark .text-indigo-700 { color: #a5b4fc; }
|
||||
html.dark .text-indigo-800 { color: #c7d2fe; }
|
||||
html.dark .text-orange-700 { color: #fdba74; }
|
||||
html.dark .text-orange-800 { color: #fed7aa; }
|
||||
html.dark .text-purple-700 { color: #d8b4fe; }
|
||||
html.dark .text-purple-800 { color: #e9d5ff; }
|
||||
|
||||
/* ---- Dropdown / popup menus ---- */
|
||||
html.dark .bg-white.rounded-md.shadow-lg { background-color: #1f2937; }
|
||||
html.dark .ring-black { --tw-ring-color: rgba(0,0,0,0.5); }
|
||||
|
||||
/* ---- Form inputs / selects / textareas ---- */
|
||||
html.dark input:not([type="checkbox"]):not([type="radio"]):not([type="range"]),
|
||||
html.dark select,
|
||||
html.dark textarea {
|
||||
background-color: #374151;
|
||||
border-color: #4b5563;
|
||||
color: #e5e7eb;
|
||||
}
|
||||
html.dark input::placeholder,
|
||||
html.dark textarea::placeholder {
|
||||
color: #9ca3af;
|
||||
}
|
||||
html.dark input:focus:not([type="checkbox"]):not([type="radio"]):not([type="range"]),
|
||||
html.dark select:focus,
|
||||
html.dark textarea:focus {
|
||||
border-color: #60a5fa;
|
||||
outline-color: #60a5fa;
|
||||
}
|
||||
|
||||
/* ---- Table rows ---- */
|
||||
html.dark thead,
|
||||
html.dark .bg-gray-50 thead { background-color: #1f2937; }
|
||||
html.dark thead th { color: #9ca3af; }
|
||||
html.dark tbody tr:hover { background-color: #374151; }
|
||||
|
||||
/* ---- Code / pre ---- */
|
||||
html.dark pre,
|
||||
html.dark code { background-color: #111827; color: #d1d5db; }
|
||||
|
||||
/* ---- Dark-mode toggle button icon colour ---- */
|
||||
html.dark #darkModeToggle { color: #fbbf24; }
|
||||
html.dark #darkModeToggle:hover { background-color: #374151; }
|
||||
|
||||
/* ---- Scrollbar (WebKit browsers) ---- */
|
||||
html.dark ::-webkit-scrollbar { width: 8px; height: 8px; }
|
||||
html.dark ::-webkit-scrollbar-track { background: #1f2937; }
|
||||
html.dark ::-webkit-scrollbar-thumb { background: #4b5563; border-radius: 4px; }
|
||||
html.dark ::-webkit-scrollbar-thumb:hover { background: #6b7280; }
|
||||
|
||||
Reference in New Issue
Block a user