Browse Source

fix dark and light-view contrast for the whole app, to meet accesibility standards

remove unused navigation bars
fixed hover effects
master
silberengel 3 months ago
parent
commit
db9cf1c279
  1. 154
      src/app.css
  2. 8
      src/app.html
  3. 12
      src/lib/a/nav/ANavbar.svelte
  4. 48
      src/lib/components/Navigation.svelte
  5. 10
      src/lib/components/publications/Publication.svelte
  6. 5
      src/lib/components/util/CardActions.svelte
  7. 13
      src/lib/stores/themeStore.ts
  8. 28
      src/styles/a/cards.css
  9. 2
      src/styles/base.css
  10. 12
      src/styles/notifications.css
  11. 2
      src/styles/publications.css
  12. 20
      src/styles/visualize.css
  13. 11
      src/theme-tokens.css

154
src/app.css

@ -202,7 +202,7 @@ @@ -202,7 +202,7 @@
@apply text-base font-semibold;
}
/* Heading links - primary-600 (light) / primary-400 (dark) for hover */
/* Heading links - primary-600 (light, more golden) / primary-300 (dark) for hover */
h1 a,
h2 a,
h3 a,
@ -216,7 +216,7 @@ @@ -216,7 +216,7 @@
h5.h-leather a,
h6.h-leather a {
@apply text-gray-900 dark:text-gray-100 hover:text-primary-600
dark:hover:text-primary-400;
dark:hover:text-primary-300;
}
/* === LEATHER COMPONENTS === */
@ -242,8 +242,8 @@ @@ -242,8 +242,8 @@
}
div[role="tooltip"] button.btn-leather {
@apply hover:text-primary-600 dark:hover:text-primary-400
hover:border-primary-600 dark:hover:border-primary-400 hover:bg-gray-200
@apply hover:text-primary-700 dark:hover:text-primary-300
hover:border-primary-700 dark:hover:border-primary-300 hover:bg-gray-200
dark:hover:bg-gray-700;
}
@ -301,7 +301,7 @@ @@ -301,7 +301,7 @@
div.modal-leather > div > h4 a,
div.modal-leather > div > h5 a,
div.modal-leather > div > h6 a {
@apply hover:text-primary-600 dark:hover:text-primary-400;
@apply hover:text-primary-700 dark:hover:text-primary-300;
}
/* Navbar */
@ -314,17 +314,70 @@ @@ -314,17 +314,70 @@
}
nav.navbar-leather svg {
@apply fill-gray-900 hover:fill-primary-600 dark:fill-gray-100
dark:hover:fill-primary-400;
@apply fill-gray-900 hover:fill-primary-700 dark:fill-gray-100
dark:hover:fill-primary-300;
}
/* NavBrand hover - all text highlights together */
#navi a:hover h1,
#navi a:hover p {
@apply !text-primary-600 dark:!text-primary-400;
@apply !text-primary-600 dark:!text-primary-300;
transition: color 0.2s ease-in-out;
}
/* Navbar menu items hover effect - ALL items get same background hover */
#navi ul li.navbar-menu-item,
#navi ul li:has(.navbar-menu-item),
#navi li.navbar-menu-item {
@apply rounded px-2 py-1 transition-colors;
}
#navi ul li.navbar-menu-item:hover,
#navi ul li:has(.navbar-menu-item):hover,
#navi li.navbar-menu-item:hover,
#navi ul li.navbar-menu-item:has(button:hover),
#navi ul li.navbar-menu-item:has(div:hover),
#navi ul li.navbar-menu-item:has(span:hover),
#navi ul li.navbar-menu-item:has(a:hover),
#navi ul li.navbar-menu-item:has(img:hover),
#navi ul li.navbar-menu-item:has(svg:hover),
#navi ul li.navbar-menu-item:has([class*="Avatar"]:hover) {
@apply !bg-primary-100;
}
.dark #navi ul li.navbar-menu-item:hover,
.dark #navi ul li:has(.navbar-menu-item):hover,
.dark #navi li.navbar-menu-item:hover,
.dark #navi ul li.navbar-menu-item:has(button:hover),
.dark #navi ul li.navbar-menu-item:has(div:hover),
.dark #navi ul li.navbar-menu-item:has(span:hover),
.dark #navi ul li.navbar-menu-item:has(a:hover),
.dark #navi ul li.navbar-menu-item:has(img:hover),
.dark #navi ul li.navbar-menu-item:has(svg:hover),
.dark #navi ul li.navbar-menu-item:has([class*="Avatar"]:hover) {
@apply !bg-primary-800;
}
/* Explore text color - matches chevron in dark mode */
#navi ul li.navbar-menu-item:first-of-type {
@apply text-primary-800 dark:text-white cursor-pointer;
}
/* Remove ALL backgrounds from ALL child elements - use universal selector with max specificity */
#navi ul li.navbar-menu-item *,
#navi ul li.navbar-menu-item *:hover,
#navi ul li.navbar-menu-item *:focus,
#navi ul li.navbar-menu-item *:active,
#navi ul li.navbar-menu-item:hover *,
#navi ul li.navbar-menu-item:hover *:hover,
#navi ul li.navbar-menu-item:hover *:focus,
#navi ul li.navbar-menu-item:hover *:active {
background-color: transparent !important;
background: transparent !important;
background-image: none !important;
box-shadow: none !important;
}
nav.navbar-leather h1,
nav.navbar-leather h2,
nav.navbar-leather h3,
@ -340,7 +393,7 @@ @@ -340,7 +393,7 @@
nav.navbar-leather h4 a,
nav.navbar-leather h5 a,
nav.navbar-leather h6 a {
@apply hover:text-primary-600 dark:hover:text-primary-400;
@apply hover:text-primary-700 dark:hover:text-primary-300;
}
div.textarea-leather {
@ -430,23 +483,23 @@ @@ -430,23 +483,23 @@
/* Lists */
.ol-leather li a,
.ul-leather li a {
@apply text-gray-900 dark:text-gray-100 hover:text-primary-600
dark:hover:text-primary-400;
@apply text-gray-900 dark:text-gray-100 hover:text-primary-700
dark:hover:text-primary-300;
}
/* Links - consistent hover colors */
/* Links - consistent hover colors - improved contrast */
.link {
@apply underline cursor-pointer hover:text-primary-600
dark:hover:text-primary-400;
@apply underline cursor-pointer hover:text-primary-700
dark:hover:text-primary-300;
}
.npub-badge {
@apply inline-flex space-x-1 items-center text-primary-600
dark:text-primary-500 hover:underline me-2 px-2 py-0.5 rounded-sm border
border-primary-600 dark:border-primary-500;
@apply inline-flex space-x-1 items-center text-primary-700
dark:text-primary-300 hover:underline me-2 px-2 py-0.5 rounded-sm border
border-primary-700 dark:border-primary-300;
svg {
@apply fill-primary-600 dark:fill-primary-500;
@apply fill-primary-700 dark:fill-primary-300;
}
}
@ -455,6 +508,19 @@ @@ -455,6 +508,19 @@
}
}
/* Force remove backgrounds from DarkMode button - outside layer for max priority */
#navi ul li.navbar-menu-item:nth-child(2) *,
#navi ul li.navbar-menu-item:nth-child(2) *:hover,
#navi ul li.navbar-menu-item:nth-child(2) *:focus,
#navi ul li.navbar-menu-item:nth-child(2) *:active,
#navi ul li.navbar-menu-item:nth-child(2):hover *,
#navi ul li.navbar-menu-item:nth-child(2):hover *:hover {
background-color: transparent !important;
background: transparent !important;
background-image: none !important;
box-shadow: none !important;
}
@layer components {
nav a {
text-decoration-line: none !important;
@ -464,6 +530,23 @@ @@ -464,6 +530,23 @@
@apply block mx-auto my-4;
}
/* Fix white wrapper behind buttons on publication content in light mode */
main.publication div.flex.gap-2,
main.publication div.flex.justify-between {
@apply bg-transparent;
}
/* Override Flowbite light button white background in light mode to be more subtle */
main.publication :global(button.bg-gray-100),
main.publication :global(button.bg-gray-50) {
@apply !bg-primary-100 !border-primary-200 !text-primary-800;
}
main.publication :global(button.bg-gray-100:hover),
main.publication :global(button.bg-gray-50:hover) {
@apply !bg-primary-200 !border-primary-300;
}
/* Legend */
.leather-legend {
@apply relative m-4 sm:m-0 sm:absolute sm:top-1 sm:left-1 flex-shrink-0 p-2
@ -488,7 +571,7 @@ @@ -488,7 +571,7 @@
}
.leather-legend button {
@apply dark:text-white;
@apply text-gray-900 dark:text-gray-100;
}
.publication-leather {
@ -527,10 +610,10 @@ @@ -527,10 +610,10 @@
}
}
/* All links - consistent hover behavior */
/* All links - consistent hover behavior - improved contrast */
a {
@apply underline cursor-pointer hover:text-primary-600
dark:hover:text-primary-400;
@apply underline cursor-pointer hover:text-primary-700
dark:hover:text-primary-300;
}
.imageblock {
@ -567,10 +650,14 @@ @@ -567,10 +650,14 @@
}
}
/* Footnotes */
/* Footnotes - improved contrast */
.footnote-ref {
text-decoration: none;
color: var(--color-primary-500);
color: var(--color-primary-700);
}
.dark .footnote-ref {
color: var(--color-primary-300);
}
.footnotes {
@ -600,12 +687,21 @@ @@ -600,12 +687,21 @@
.footnote-backref {
text-decoration: none;
margin-left: 0.5rem;
color: var(--color-primary-500);
color: var(--color-primary-700);
}
.dark .footnote-backref {
color: var(--color-primary-300);
}
.note-leather .footnote-ref,
.note-leather .footnote-backref {
color: var(--color-primary-500);
color: var(--color-primary-700);
}
.dark .note-leather .footnote-ref,
.dark .note-leather .footnote-backref {
color: var(--color-primary-300);
}
/* Scrollable content */
@ -678,10 +774,10 @@ @@ -678,10 +774,10 @@
@apply focus:border-primary-600 dark:focus:border-primary-400;
}
/* Table of Contents highlighting */
/* Table of Contents highlighting - improved contrast */
.toc-highlight {
@apply bg-primary-300 dark:bg-primary-700 border-s-4 border-primary-600
rounded dark:border-primary-400 font-medium;
@apply bg-primary-300 dark:bg-primary-700 border-s-4 border-primary-700
rounded dark:border-primary-300 font-medium text-gray-900 dark:text-gray-100;
transition: all 0.2s ease-in-out;
}

8
src/app.html

@ -8,8 +8,12 @@ @@ -8,8 +8,12 @@
<!-- Apply saved theme ASAP to avoid flash -->
<script>
try {
const t = localStorage.getItem("theme");
if (t) document.documentElement.dataset.theme = t;
const t = localStorage.getItem("alexandria/theme") || "light";
document.documentElement.dataset.theme = t;
// Add .dark class for non-light themes
if (t !== "light") {
document.documentElement.classList.add("dark");
}
} catch (_) {
/* no-op */
}

12
src/lib/a/nav/ANavbar.svelte

@ -121,11 +121,10 @@ @@ -121,11 +121,10 @@
</div>
</NavBrand>
<div class="flex md:order-2">
<Profile />
<NavHamburger />
</div>
<NavUl class="order-1 ml-auto items-center" classes={{ ul: "items-center" }}>
<NavLi class="cursor-pointer">
<NavLi class="navbar-menu-item">
Explore<ChevronDownOutline
class="text-primary-800 ms-2 inline h-6 w-6 dark:text-white"
/>
@ -134,7 +133,7 @@ @@ -134,7 +133,7 @@
{#snippet children({ item })}
<a
href={item.href}
class="block h-full rounded-lg p-3 hover:bg-gray-50 dark:hover:bg-gray-700"
class="block h-full rounded-lg p-3 hover:bg-gray-50 dark:hover:bg-primary-800 transition-colors"
>
<div class="font-semibold dark:text-white">{item.name}</div>
<span class="text-sm font-light text-gray-500 dark:text-gray-400"
@ -143,6 +142,11 @@ @@ -143,6 +142,11 @@
</a>
{/snippet}
</MegaMenu>
<DarkMode />
<NavLi class="navbar-menu-item">
<DarkMode />
</NavLi>
<NavLi class="navbar-menu-item">
<Profile />
</NavLi>
</NavUl>
</Navbar>

48
src/lib/components/Navigation.svelte

@ -1,48 +0,0 @@ @@ -1,48 +0,0 @@
<script lang="ts">
import {
DarkMode,
Navbar,
NavLi,
NavUl,
NavHamburger,
NavBrand,
} from "flowbite-svelte";
import Profile from "./util/Profile.svelte";
import { userStore } from "$lib/stores/userStore";
let { class: className = "" } = $props();
let userState = $derived($userStore);
</script>
<Navbar class={`Navbar navbar-leather navbar-main ${className}`}>
<div class="flex flex-grow justify-between">
<NavBrand href="/">
<div class="flex flex-col">
<h1 class="text-2xl font-bold">Alexandria</h1>
<p class="text-xs font-semibold tracking-wide max-sm:max-w-[11rem]">
READ THE ORIGINAL. MAKE CONNECTIONS. CULTIVATE KNOWLEDGE.
</p>
</div>
</NavBrand>
</div>
<div class="flex md:order-2">
<Profile />
<NavHamburger class="btn-leather" />
</div>
<NavUl class="ul-leather">
<NavLi href="/">Publications</NavLi>
<NavLi href="/new/compose">Compose</NavLi>
<NavLi href="/visualize">Visualize</NavLi>
<NavLi href="/start">Getting Started</NavLi>
<NavLi href="/events">Events</NavLi>
{#if userState.signedIn}
<NavLi href="/my-notes">My Notes</NavLi>
{/if}
<NavLi href="/about">About</NavLi>
<NavLi href="/contact">Contact</NavLi>
<NavLi>
<DarkMode class="btn-leather p-0" />
</NavLi>
</NavUl>
</Navbar>

10
src/lib/components/publications/Publication.svelte

@ -505,7 +505,7 @@ @@ -505,7 +505,7 @@
<!-- Main header content - centered -->
<div class="max-w-4xl mx-auto px-4">
<div
class="card-leather bg-highlight dark:bg-primary-800 p-4 mb-4 rounded-lg border"
class="card-leather bg-highlight dark:bg-primary-900 p-4 mb-4 rounded-lg border"
>
<Details
event={indexEvent}
@ -543,8 +543,8 @@ @@ -543,8 +543,8 @@
</div>
<!-- Action buttons row -->
<div class="flex justify-between gap-2 mb-4">
<div class="flex gap-2">
<div class="flex justify-between gap-2 mb-4 bg-transparent">
<div class="flex gap-2 bg-transparent">
<Button
color="light"
size="sm"
@ -554,7 +554,7 @@ @@ -554,7 +554,7 @@
</Button>
<HighlightButton bind:isActive={highlightModeActive} />
</div>
<div class="flex gap-2">
<div class="flex gap-2 bg-transparent">
<Button color="light" size="sm" onclick={toggleComments}>
{#if commentsVisible}
<EyeSlashOutline class="w-4 h-4 mr-2" />
@ -670,7 +670,7 @@ @@ -670,7 +670,7 @@
: 'mx-auto md:mx-auto max-w-3xl'} ${isInnerActive() ? 'hidden md:flex' : ''}`}
>
<div
class="card-leather bg-highlight dark:bg-primary-800 p-4 mb-4 rounded-lg border"
class="card-leather bg-highlight dark:bg-primary-900 p-4 mb-4 rounded-lg border"
>
<Details event={indexEvent} onDelete={handleDeletePublication} />
</div>

5
src/lib/components/util/CardActions.svelte

@ -408,7 +408,7 @@ @@ -408,7 +408,7 @@
</script>
<div
class="group bg-highlight dark:bg-primary-1000 rounded"
class="group bg-transparent rounded"
role="group"
onmouseenter={openPopover}
>
@ -416,8 +416,7 @@ @@ -416,8 +416,7 @@
<Button
type="button"
id="dots-{event.id}"
class=" hover:bg-primary-50 dark:text-highlight dark:hover:bg-primary-800 p-1 dots"
color="primary"
class="!bg-transparent hover:!bg-primary-100 dark:hover:!bg-primary-800 text-primary-600 dark:text-gray-300 hover:text-primary-700 dark:hover:text-gray-200 p-1 dots !border-0 !shadow-none"
data-popover-target="popover-actions"
>
<DotsVerticalOutline class="h-6 w-6" />

13
src/lib/stores/themeStore.ts

@ -10,8 +10,17 @@ export const theme = writable(initial); @@ -10,8 +10,17 @@ export const theme = writable(initial);
theme.subscribe((v) => {
if (typeof document !== "undefined") {
document.documentElement.dataset.theme = String(v);
localStorage.setItem(KEY, String(v));
const themeValue = String(v);
document.documentElement.dataset.theme = themeValue;
localStorage.setItem(KEY, themeValue);
// Add .dark class for non-light themes (ocean, forrest are dark themes)
// Remove .dark class for light theme
if (themeValue === "light") {
document.documentElement.classList.remove("dark");
} else {
document.documentElement.classList.add("dark");
}
}
});

28
src/styles/a/cards.css

@ -18,12 +18,12 @@ @@ -18,12 +18,12 @@
.card-leather h5,
.card-leather h6 {
@apply text-gray-900 hover:text-primary-600 dark:text-gray-100
dark:hover:text-primary-400;
dark:hover:text-primary-300;
}
.card-leather .font-thin {
@apply text-gray-900 hover:text-primary-600 dark:text-gray-100
dark:hover:text-primary-400;
@apply text-gray-900 hover:text-primary-700 dark:text-gray-100
dark:hover:text-primary-300;
}
/* Main card leather (used in profile previews) */
@ -61,12 +61,12 @@ @@ -61,12 +61,12 @@
.ArticleBox h5,
.ArticleBox h6 {
@apply text-gray-900 hover:text-primary-600 dark:text-gray-100
dark:hover:text-primary-400;
dark:hover:text-primary-300;
}
.ArticleBox .font-thin {
@apply text-gray-900 hover:text-primary-600 dark:text-gray-100
dark:hover:text-primary-400;
@apply text-gray-900 hover:text-primary-700 dark:text-gray-100
dark:hover:text-primary-300;
}
/* Article box image transitions */
@ -155,24 +155,24 @@ @@ -155,24 +155,24 @@
flex items-center gap-2 flex-wrap;
}
/* Card content text styles */
/* Card content text styles - improved contrast */
.card-summary {
@apply text-sm text-primary-900 dark:text-primary-200 line-clamp-2;
@apply text-sm text-primary-900 dark:text-primary-100 line-clamp-2;
}
.card-content {
@apply text-sm text-gray-800 dark:text-gray-200 line-clamp-3 break-words
@apply text-sm text-gray-900 dark:text-gray-100 line-clamp-3 break-words
mb-4;
}
.card-about {
@apply text-sm text-gray-700 dark:text-gray-300 line-clamp-3;
@apply text-sm text-gray-800 dark:text-gray-200 line-clamp-3;
}
/* Deferral link styling */
/* Deferral link styling - improved contrast */
.deferral-link {
@apply underline text-primary-700 dark:text-primary-400
hover:text-primary-600 dark:hover:text-primary-400 break-all
@apply underline text-primary-700 dark:text-primary-300
hover:text-primary-800 dark:hover:text-primary-200 break-all
cursor-pointer;
}
@ -182,7 +182,7 @@ @@ -182,7 +182,7 @@
.tags span {
@apply bg-primary-50 text-primary-800 text-sm font-medium me-2 px-2.5 py-0.5
rounded-sm dark:bg-primary-900 dark:text-primary-200;
rounded-sm dark:bg-primary-900 dark:text-primary-100;
}
/* ========================================

2
src/styles/base.css

@ -2,6 +2,6 @@ @@ -2,6 +2,6 @@
@layer components {
body {
@apply bg-primary-0 dark:bg-primary-1000;
@apply bg-primary-0 dark:bg-primary-1000 text-gray-900 dark:text-gray-100;
}
}

12
src/styles/notifications.css

@ -50,15 +50,15 @@ @@ -50,15 +50,15 @@
background: linear-gradient(135deg, #4b5563 0%, #374151 100%);
}
/* Filter button states */
/* Filter button states - improved contrast */
.filter-button-active {
background-color: rgb(107 114 128);
color: rgb(243 244 246);
background-color: rgb(75 85 99);
color: rgb(255 255 255);
}
.dark .filter-button-active {
background-color: rgb(107 114 128);
color: rgb(243 244 246);
color: rgb(255 255 255);
}
/* Reply button hover states */
@ -181,11 +181,11 @@ @@ -181,11 +181,11 @@
}
.mode-toggle-button.inactive {
color: rgb(55 65 81);
color: rgb(31 41 55);
}
.dark .mode-toggle-button.inactive {
color: rgb(156 163 175);
color: rgb(209 213 219);
}
.mode-toggle-button.inactive:hover {

2
src/styles/publications.css

@ -5,7 +5,7 @@ @@ -5,7 +5,7 @@
}
.publication-leather p a {
@apply underline hover:text-primary-600 dark:hover:text-primary-400;
@apply underline hover:text-primary-700 dark:hover:text-primary-300;
}
.publication-leather section p {

20
src/styles/visualize.css

@ -1,7 +1,7 @@ @@ -1,7 +1,7 @@
@layer components {
/* Legend styles - specific to visualization */
/* Legend styles - specific to visualization - improved contrast */
.legend-list {
@apply list-disc mt-2 space-y-2 text-gray-800 dark:text-gray-300;
@apply list-disc mt-2 space-y-2 text-gray-900 dark:text-gray-200;
}
.legend-item {
@ -70,7 +70,7 @@ @@ -70,7 +70,7 @@
}
.network-debug {
@apply mt-4 text-sm text-gray-500;
@apply mt-4 text-sm text-gray-700 dark:text-gray-300;
}
/* Zoom controls */
@ -82,11 +82,11 @@ @@ -82,11 +82,11 @@
@apply bg-white;
}
/* Tooltip styles - specific to visualization tooltips */
/* Tooltip styles - specific to visualization tooltips - improved contrast */
.tooltip-close-btn {
@apply absolute top-2 right-2 bg-gray-200 hover:bg-gray-300 dark:bg-gray-700
dark:hover:bg-gray-600 rounded-full p-1 text-gray-500 hover:text-gray-700
dark:text-gray-400 dark:hover:text-gray-200;
dark:hover:bg-gray-600 rounded-full p-1 text-gray-700 hover:text-gray-900
dark:text-gray-300 dark:hover:text-gray-100;
}
.tooltip-content {
@ -98,12 +98,12 @@ @@ -98,12 +98,12 @@
}
.tooltip-title-link {
@apply text-gray-800 hover:text-blue-600 dark:text-gray-200
dark:hover:text-blue-400;
@apply text-gray-900 hover:text-blue-700 dark:text-gray-100
dark:hover:text-blue-300;
}
.tooltip-metadata {
@apply text-gray-600 dark:text-gray-400 text-sm;
@apply text-gray-700 dark:text-gray-300 text-sm;
}
.tooltip-summary {
@ -117,7 +117,7 @@ @@ -117,7 +117,7 @@
}
.tooltip-help-text {
@apply mt-2 text-xs text-gray-500 dark:text-gray-400 italic;
@apply mt-2 text-xs text-gray-600 dark:text-gray-300 italic;
}
/* Star network visualization styles */

11
src/theme-tokens.css

@ -15,6 +15,13 @@ @@ -15,6 +15,13 @@
--brand-primary-1000: #15110d;
}
/* Dark mode tweaks for default theme - improve contrast for text on dark backgrounds */
:root.dark {
/* Brighten mid-tones for better contrast when used as text */
--brand-primary-300: #d4a574;
--brand-primary-200: #e0b890;
}
/* Example alternative theme: ocean */
:root[data-theme="ocean"] {
--brand-primary-0: #ecf8ff;
@ -37,6 +44,8 @@ @@ -37,6 +44,8 @@
/* nudge the mid tones brighter for contrast */
--brand-primary-400: #7ccdfc;
--brand-primary-500: #38bdf8;
--brand-primary-300: #a5d8f5;
--brand-primary-200: #bae6fd;
}
/* Example alternative theme: forrest */
@ -61,4 +70,6 @@ @@ -61,4 +70,6 @@
/* nudge the mid tones brighter for contrast */
--brand-primary-400: #7fc97f;
--brand-primary-500: #4caf50;
--brand-primary-300: #9fda9f;
--brand-primary-200: #b8e6b8;
}

Loading…
Cancel
Save