diff --git a/.gitignore b/.gitignore index 777bb9a..d5729ec 100644 --- a/.gitignore +++ b/.gitignore @@ -36,3 +36,4 @@ Thumbs.db build/ dist/ *.swp +package-lock.json diff --git a/index.html b/index.html index e31ffba..5e6407b 100644 --- a/index.html +++ b/index.html @@ -68,5 +68,6 @@

The Real
+ diff --git a/public/fonts/OpenDyslexic-OFL.txt b/public/fonts/OpenDyslexic-OFL.txt new file mode 100644 index 0000000..0a1d034 --- /dev/null +++ b/public/fonts/OpenDyslexic-OFL.txt @@ -0,0 +1,94 @@ +Copyright (c) 2019-07-29, Abbie Gonzalez (https://abbiecod.es|support@abbiecod.es), +with Reserved Font Name OpenDyslexic. +Copyright (c) 12/2012 - 2019 +This Font Software is licensed under the SIL Open Font License, Version 1.1. +This license is copied below, and is also available with a FAQ at: +http://scripts.sil.org/OFL + + +----------------------------------------------------------- +SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 +----------------------------------------------------------- + +PREAMBLE +The goals of the Open Font License (OFL) are to stimulate worldwide +development of collaborative font projects, to support the font creation +efforts of academic and linguistic communities, and to provide a free and +open framework in which fonts may be shared and improved in partnership +with others. + +The OFL allows the licensed fonts to be used, studied, modified and +redistributed freely as long as they are not sold by themselves. The +fonts, including any derivative works, can be bundled, embedded, +redistributed and/or sold with any software provided that any reserved +names are not used by derivative works. The fonts and derivatives, +however, cannot be released under any other type of license. The +requirement for fonts to remain under this license does not apply +to any document created using the fonts or their derivatives. + +DEFINITIONS +"Font Software" refers to the set of files released by the Copyright +Holder(s) under this license and clearly marked as such. This may +include source files, build scripts and documentation. + +"Reserved Font Name" refers to any names specified as such after the +copyright statement(s). + +"Original Version" refers to the collection of Font Software components as +distributed by the Copyright Holder(s). + +"Modified Version" refers to any derivative made by adding to, deleting, +or substituting -- in part or in whole -- any of the components of the +Original Version, by changing formats or by porting the Font Software to a +new environment. + +"Author" refers to any designer, engineer, programmer, technical +writer or other person who contributed to the Font Software. + +PERMISSION & CONDITIONS +Permission is hereby granted, free of charge, to any person obtaining +a copy of the Font Software, to use, study, copy, merge, embed, modify, +redistribute, and sell modified and unmodified copies of the Font +Software, subject to the following conditions: + +1) Neither the Font Software nor any of its individual components, +in Original or Modified Versions, may be sold by itself. + +2) Original or Modified Versions of the Font Software may be bundled, +redistributed and/or sold with any software, provided that each copy +contains the above copyright notice and this license. These can be +included either as stand-alone text files, human-readable headers or +in the appropriate machine-readable metadata fields within text or +binary files as long as those fields can be easily viewed by the user. + +3) No Modified Version of the Font Software may use the Reserved Font +Name(s) unless explicit written permission is granted by the corresponding +Copyright Holder. This restriction only applies to the primary font name as +presented to the users. + +4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font +Software shall not be used to promote, endorse or advertise any +Modified Version, except to acknowledge the contribution(s) of the +Copyright Holder(s) and the Author(s) or with their explicit written +permission. + +5) The Font Software, modified or unmodified, in part or in whole, +must be distributed entirely under this license, and must not be +distributed under any other license. The requirement for fonts to +remain under this license does not apply to any document created +using the Font Software. + +TERMINATION +This license becomes null and void if any of the above conditions are +not met. + +DISCLAIMER +THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT +OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE +COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM +OTHER DEALINGS IN THE FONT SOFTWARE. diff --git a/public/fonts/opendyslexic-400-italic.woff2 b/public/fonts/opendyslexic-400-italic.woff2 new file mode 100644 index 0000000..00c1908 Binary files /dev/null and b/public/fonts/opendyslexic-400-italic.woff2 differ diff --git a/public/fonts/opendyslexic-400.woff2 b/public/fonts/opendyslexic-400.woff2 new file mode 100644 index 0000000..47e26d8 Binary files /dev/null and b/public/fonts/opendyslexic-400.woff2 differ diff --git a/public/fonts/opendyslexic-700-italic.woff2 b/public/fonts/opendyslexic-700-italic.woff2 new file mode 100644 index 0000000..aa7bcde Binary files /dev/null and b/public/fonts/opendyslexic-700-italic.woff2 differ diff --git a/public/fonts/opendyslexic-700.woff2 b/public/fonts/opendyslexic-700.woff2 new file mode 100644 index 0000000..2f04ad1 Binary files /dev/null and b/public/fonts/opendyslexic-700.woff2 differ diff --git a/public/js/dyslexia-font.js b/public/js/dyslexia-font.js new file mode 100644 index 0000000..b312619 --- /dev/null +++ b/public/js/dyslexia-font.js @@ -0,0 +1,227 @@ +/* Dyslexia-friendly reading font — self-contained, no dependencies. + * + * Drop-in: + * Fonts: /fonts/opendyslexic-{400,700}[-italic].woff2 + * Override the directory with data-fonts="/assets/fonts/" on the tag. + * + * OpenDyslexic by Abbie Gonzalez (font version 0.920, packaged as + * @fontsource/opendyslexic 5.3.0 -- that 5.3.0 is the npm package, not the + * typeface), SIL Open Font License 1.1 (licence text + * ships beside the woff2 files). Latin only: the face has no Indic glyphs, so + * text in Devanagari, Bengali, Tamil, Telugu, Gujarati, Odia or Kannada falls + * through to the stack below it and is unaffected by the switch. + * + * Nothing downloads until a reader turns it on. A browser fetches a @font-face + * only once a rule using that family matches a rendered element, and the only + * such rules here sit under html.dyslexic-font. + * + * The spacing is the half with the better evidence. Zorzi et al. (PNAS 109(28), + * 2012) found extra letter spacing raised reading speed and halved errors in + * Italian and French children with dyslexia, with no training and no change of + * typeface; the British Dyslexia Association style guide asks for 1.5 line + * spacing, wider word spacing and ragged-right text. The typeface trials are + * weaker (Kuster et al., Annals of Dyslexia, 2018, found Dyslexie gave no + * benefit over Arial), so the font is offered and the spacing is applied. + * + * Where the button goes: an element carrying data-dyslexia-slot, else a theme + * control if the site has one, else a small fixed button in the bottom-left + * corner. Give a site's nav bar data-dyslexia-slot and the button joins it. + * + * How it looks: set these on the script tag (data-accent, data-radius, ...) or + * in the site's own stylesheet, pointing them at the site's tokens so they + * track its themes. + * --dys-accent colour of the button when the switch is on + * --dys-radius corner radius (default 8px; 0 for a square house style) + * --dys-border-width default 1px + * --dys-idle-border default currentColor + * --dys-idle-opacity default .72 + * --dys-font label typeface (default system-ui) + * --dys-surface/--dys-fg ground and ink for the fixed corner variant + */ +(function () { + 'use strict'; + if (window.__dyslexiaFont) return; + window.__dyslexiaFont = true; + + var KEY = 'reading-font'; + var CLS = 'dyslexic-font'; + var root = document.documentElement; + // Resolved against this script's own URL, not the site root: several of these + // sites are served from a project subpath (varnasr.github.io//), where an + // absolute /fonts/ points at the wrong host directory. Put the script in + // /js/ (or assets/js/) and the fonts in the sibling fonts/ directory and + // this is right at any page depth, on a subpath or an apex domain alike. + var self = document.currentScript; + var DIR = (self && self.getAttribute('data-fonts')) + || (self && self.src && new URL('../fonts/', self.src).href) + || '/fonts/'; + + function on() { try { return localStorage.getItem(KEY) === 'opendyslexic'; } catch (e) { return false; } } + + // Applied here, at parse time, rather than on DOMContentLoaded: a reader who + // has chosen the font should not watch each page render in the default one. + if (on()) root.classList.add(CLS); + + // Per-site look, read off the script tag: + // data-accent="var(--accent)" data-radius="0" data-font="'JetBrains Mono',monospace" + // A site with a stylesheet can set the same custom properties there instead; + // these attributes exist because several of these sites carry their CSS + // inline, per page, with no shared file to put a rule in. Pointing the + // attribute at the site's own token rather than a literal colour is what + // makes the button follow that site into dark mode: a var() resolves where it + // is used, so whatever --accent means on the page is what the button gets. + function opt(name) { + var v = self && self.getAttribute('data-' + name); + if (!v) return ''; + // These values are written straight into a stylesheet, so nothing that could + // close a declaration or open a rule is allowed through. Colours, lengths, + // font stacks and var() references all survive this; a semicolon, a brace, + // an @rule or a backslash escape does not. + if (v.length > 120 || /[;{}@\\<>]/.test(v)) return ''; + return v; + } + + function face(weight, style, file) { + return '@font-face{font-family:"OpenDyslexic";font-weight:' + weight + ';font-style:' + style + + ';font-display:swap;src:url("' + DIR + file + '") format("woff2")}'; + } + + function styles() { + var vars = ''; + [['accent', '--dys-accent'], ['radius', '--dys-radius'], ['font', '--dys-font'], + ['border-width', '--dys-border-width'], ['idle-border', '--dys-idle-border'], + ['idle-opacity', '--dys-idle-opacity'], ['surface', '--dys-surface'], ['fg', '--dys-fg'] + ].forEach(function (pair) { + var v = opt(pair[0]); + if (v) vars += pair[1] + ':' + v + ';'; + }); + // Scoped to the button, not :root, so a site's own token namespace is left + // alone. The site's stylesheet can still set these on :root and they will + // inherit in; anything given on the tag wins, being on the element itself. + var scoped = vars ? '#dys-font-btn{' + vars + '}' : ''; + + return face(400, 'normal', 'opendyslexic-400.woff2') + + face(700, 'normal', 'opendyslexic-700.woff2') + + face(400, 'italic', 'opendyslexic-400-italic.woff2') + + face(700, 'italic', 'opendyslexic-700-italic.woff2') + + 'html.' + CLS + ',html.' + CLS + ' *{font-family:"OpenDyslexic",Verdana,Tahoma,sans-serif!important}' + // Code and data keep their monospace: column alignment is the point of it. + + 'html.' + CLS + ' code,html.' + CLS + ' pre,html.' + CLS + ' kbd,html.' + CLS + ' samp{' + + 'font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace!important}' + // Spacing, scoped to running text so controls keep their measured layout. + + 'html.' + CLS + ' p,html.' + CLS + ' li,html.' + CLS + ' dd,html.' + CLS + ' dt,' + + 'html.' + CLS + ' blockquote,html.' + CLS + ' figcaption,html.' + CLS + ' td,html.' + CLS + ' th{' + + 'line-height:1.7!important;letter-spacing:.04em!important;word-spacing:.16em!important}' + + 'html.' + CLS + ' p,html.' + CLS + ' li,html.' + CLS + ' blockquote{text-align:left!important}' + // The control itself. Every value a site is likely to care about is a + // custom property with a neutral fallback, so a site themes the button by + // setting --dys-accent (and friends) in its own stylesheet rather than + // 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. + + '#dys-font-btn{display:inline-flex;align-items:center;justify-content:center;gap:6px;' + + 'min-width:36px;height:32px;padding:0 10px;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}' + // "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 + // against whatever the accent happens to be, and these sites swap their + // accent between themes (someperspective goes from #b4530e to #fb923c, + // where white is fine on the first and fails on the second). Putting the + // accent in the label instead moves the problem rather than solving it: + // measured across the sites, Democracy by Design's --blue came out at + // 3.34:1 and How India Lives' #0EA5E9 at 2.77:1 in light mode. Leaving + // the ink alone is the one version that cannot go wrong, because it is + // the ink the site already chose for that bar. State does not rest on + // colour anyway: when the switch is on the label is set in OpenDyslexic, + // and aria-pressed carries it for anyone who cannot see either. + + '#dys-font-btn[aria-pressed="true"]{opacity:1;' + + 'border-color:var(--dys-accent,#0EA5E9);' + + 'background:color-mix(in srgb,var(--dys-accent,#0EA5E9) 16%,transparent)}' + + '#dys-font-btn.dys-fixed{position:fixed;left:16px;bottom:16px;z-index:9990;' + + 'background:var(--dys-surface,Canvas);color:var(--dys-fg,CanvasText);' + + 'box-shadow:0 2px 10px rgba(0,0,0,.18);opacity:.92}' + // Declared after the plain fixed background so a browser without + // color-mix drops this line and keeps a solid one rather than going + // transparent over the page. + + '#dys-font-btn.dys-fixed[aria-pressed="true"]{' + + 'background:color-mix(in srgb,var(--dys-accent,#0EA5E9) 16%,var(--dys-surface,Canvas))}' + + scoped; + } + + // Deliberately short. An earlier version fell back to the page
, which + // put the button at the left edge of a hero banner on three of these sites -- + // present, and reading as debris. A site either names a home for it with + // data-dyslexia-slot, or has a theme control to sit beside, or gets the fixed + // corner button, which at least lands somewhere predictable. + function host() { + var el = document.querySelector('[data-dyslexia-slot]'); + if (el) return el; + el = document.querySelector('.theme-selector,.theme-toggle,.theme-switch,' + + '.theme-btn-group,.theme-toggle-group,.themebar'); + if (!el) return null; + // On several of these sites .theme-toggle is the