diff --git a/css/style.css b/css/style.css index 55a4c33..6949648 100644 --- a/css/style.css +++ b/css/style.css @@ -21,7 +21,9 @@ --accent-warm-bg: #faf3eb; --text: #2c2c2c; --text-secondary: #555555; - --text-muted: #8a8a8a; + /* 3.42:1 on the page and 3.14:1 on the warm panel. It is the ink of every + header stat, the results count and the filter note. */ + --text-muted: #6b6b6b; --border: #e0ddd7; --border-light: #eae7e1; --divider: #d4d0c8; @@ -34,8 +36,11 @@ --radius-lg: 12px; --evidence-strong: #3d7a5f; - --evidence-moderate: #c17825; - --evidence-emerging: #8a8a8a; + --evidence-moderate: #9d5f17; + --evidence-emerging: #6b6b6b; + --evidence-strong-bg: #e8f5ee; + --evidence-moderate-bg: #fef3e4; + --evidence-emerging-bg: #f0f0f0; --topic-financial: #8b6914; --topic-financial-bg: #f9f3e3; @@ -306,9 +311,9 @@ h1, h2, h3, h4, h5, h6 { /* Chip with count */ .chip .chip-count { display: inline-block; margin-left: 3px; - font-size: 0.62rem; opacity: 0.65; font-weight: 600; + font-size: 0.62rem; font-weight: 600; color: var(--text-muted); } -.chip.active .chip-count { opacity: 0.85; } +.chip.active .chip-count { color: inherit; } .sort-select { width: 100%; padding: 6px 8px; font-size: 0.78rem; @@ -516,9 +521,9 @@ h1, h2, h3, h4, h5, h6 { font-size: 0.65rem; font-weight: 600; padding: 2px 6px; border-radius: var(--radius-sm); white-space: nowrap; } -.card-evidence.strong { background: #e8f5ee; color: var(--evidence-strong); } -.card-evidence.moderate { background: #fef3e4; color: var(--evidence-moderate); } -.card-evidence.emerging { background: #f0f0f0; color: var(--evidence-emerging); } +.card-evidence.strong { background: var(--evidence-strong-bg); color: var(--evidence-strong); } +.card-evidence.moderate { background: var(--evidence-moderate-bg); color: var(--evidence-moderate); } +.card-evidence.emerging { background: var(--evidence-emerging-bg); color: var(--evidence-emerging); } /* No results */ .no-results { text-align: center; padding: var(--sp-16) var(--sp-6); grid-column: 1 / -1; } @@ -1090,7 +1095,9 @@ h1, h2, h3, h4, h5, h6 { --accent-warm-bg: #2a1f12; --text: #e6edf3; --text-secondary: #b0b8c1; - --text-muted: #7d8590; + /* 4.34:1 on --bg-warm and 4.22:1 on the chip fill. It is the ink of every + header stat and every chip count, so it is a number a reader came for. */ + --text-muted: #8b949e; --border: #30363d; --border-light: #21262d; --divider: #30363d; @@ -1099,6 +1106,31 @@ h1, h2, h3, h4, h5, h6 { --shadow-lg: 0 4px 20px rgba(0,0,0,0.6); --shadow-card: 0 1px 4px rgba(0,0,0,0.4), 0 0 0 1px rgba(255,255,255,0.04); + /* The dark block redefined only the ten fills and left the ten inks at + their light values, so every topic chip was dark ink on a dark fill: + --topic-economic #4a4a4a on #1c1c1c is 1.92:1, --topic-governance 2.03, + --topic-infrastructure 2.19, --topic-agriculture 2.70. Darkening a fill + and keeping its ink preserves the hue and destroys the contrast, which is + why all ten failed and none of them looked obviously wrong. Each ink below + is the same hue lifted until it clears 5:1 on its own fill. */ + --evidence-strong: #6FC08F; + --evidence-moderate: #D9A055; + --evidence-emerging: #9EA5AD; + --evidence-strong-bg: #12251b; + --evidence-moderate-bg: #2a1f0d; + --evidence-emerging-bg: #1c1c1c; + + --topic-financial: #D3B45F; + --topic-health: #C77575; + --topic-education: #6A9DC8; + --topic-social: #A57CC0; + --topic-agriculture: #80B280; + --topic-economic: #999999; + --topic-environment: #6FC3B3; + --topic-governance: #9F81BB; + --topic-infrastructure: #B87A9A; + --topic-gender: #B57D9A; + --topic-financial-bg: #2a2008; --topic-health-bg: #2a1414; --topic-education-bg: #0f1d2e; diff --git a/index.html b/index.html index 4ea3d9e..99dc001 100644 --- a/index.html +++ b/index.html @@ -171,7 +171,7 @@ Sort
- @@ -241,7 +241,7 @@

Evidence-Based Development Research Library

-
+
diff --git a/js/dyslexia-font.js b/js/dyslexia-font.js index b312619..7cb8a8a 100644 --- a/js/dyslexia-font.js +++ b/js/dyslexia-font.js @@ -36,6 +36,7 @@ * --dys-idle-border default currentColor * --dys-idle-opacity default .72 * --dys-font label typeface (default system-ui) + * --dys-min-size minimum touch target (default 44px) * --dys-surface/--dys-fg ground and ink for the fixed corner variant */ (function () { @@ -119,14 +120,28 @@ // fighting this rule on specificity. Point --dys-accent at the site's own // accent token and dark mode follows for free, because a var() is resolved // where it is used, not where it is declared. + // 44px, not 32. This button is a reading aid, so the people most likely + // to reach for it are the ones a small target costs most; WCAG 2.2's + // Target Size (Minimum), 2.5.8, puts the floor at 24px and the older + // 2.5.5 at 44. It was 36x32 on every site using this script. Override + // with --dys-min-size if a host genuinely needs it smaller. + '#dys-font-btn{display:inline-flex;align-items:center;justify-content:center;gap:6px;' - + 'min-width:36px;height:32px;padding:0 10px;cursor:pointer;' + + 'min-width:var(--dys-min-size,44px);min-height:var(--dys-min-size,44px);padding:0 12px;cursor:pointer;' + 'border-radius:var(--dys-radius,8px);' + 'border:var(--dys-border-width,1px) solid var(--dys-idle-border,currentColor);' + 'background:transparent;color:inherit;' + 'font:700 13px/1 var(--dys-font,system-ui,sans-serif);' - + 'letter-spacing:.02em;opacity:var(--dys-idle-opacity,.72)}' - + '#dys-font-btn:hover,#dys-font-btn:focus-visible{opacity:1}' + // Idle opacity defaults to 1, not .72. The paragraph below argues that + // leaving the ink alone is the one version that cannot go wrong, because + // it is the ink the site already chose for that bar -- and then took 28% + // off it, which undoes exactly that guarantee. Measured on + // pinpointventures, --color-text #4b5563 is 6.41:1 on the header and the + // composite at .72 is #7d858f, 3.73:1. A control that exists so people who + // find text hard to read can read it should not be the dimmest thing on + // the page. The idle/on distinction rides on the border and the wash, which + // it already did. --dys-idle-opacity is still there for a site whose bar + // has the headroom to spend. + + 'letter-spacing:.02em;opacity:var(--dys-idle-opacity,1)}' // "On" is the site's accent as outline and a wash of itself, with the // label left at whatever ink the bar around it already uses. Two earlier // shapes were worse. A filled button needs an ink that clears 4.5:1 @@ -172,6 +187,18 @@ return el; } + // Where in the slot the button lands. Default is the end of the row, which is + // where it has always gone. A site that wants it somewhere else names an + // element to sit in front of: data-dyslexia-before="#docsLink" on the slot. + // Opt-in on purpose -- this file is shared across nine pages and a change to + // the default would move the button on all of them. + function place(h, b) { + var sel = h.getAttribute && h.getAttribute('data-dyslexia-before'); + var ref = sel ? h.querySelector(sel) : null; + if (ref && ref.parentElement === h) h.insertBefore(b, ref); + else h.appendChild(b); + } + function init() { if (document.getElementById('dys-font-btn')) return; var st = document.createElement('style'); @@ -201,7 +228,7 @@ sync(); var h = host(); - if (h) { h.appendChild(b); return; } + if (h) { place(h, b); return; } // No home yet. Two of these sites build their masthead from JavaScript after // this runs, so a slot that does not exist at DOMContentLoaded may exist a @@ -215,7 +242,7 @@ var late = host(); if (!late || late.contains(b)) return; b.className = ''; - late.appendChild(b); + place(late, b); mo.disconnect(); }); mo.observe(document.body, { childList: true, subtree: true });