@abreen/tada 1.16.0 → 1.16.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -0
- package/bin/validators.ts +2 -0
- package/build/generate-fonts.ts +17 -0
- package/build/site-variables.ts +2 -0
- package/build/types.d.ts +2 -0
- package/build/utils/render.ts +24 -8
- package/build/watch/assets.ts +3 -3
- package/package.json +1 -1
- package/schema/site.schema.json +10 -0
- package/src/appearance-picker/index.ts +65 -19
- package/src/appearance-picker/style.scss +13 -2
- package/src/header/_base.scss +4 -0
- package/src/header/style.scss +8 -0
- package/templates/_appearance-picker.html +4 -4
- package/templates/_top.html +29 -5
package/README.md
CHANGED
|
@@ -219,6 +219,8 @@ titlePostfix: " - CS 0"
|
|
|
219
219
|
symbol: CS 0
|
|
220
220
|
themeColor: hsl(351 70% 40%)
|
|
221
221
|
tintAmount: 0
|
|
222
|
+
defaultFont: serif
|
|
223
|
+
defaultContrast: high
|
|
222
224
|
features:
|
|
223
225
|
search: true
|
|
224
226
|
favicon: true
|
|
@@ -245,6 +247,8 @@ vars:
|
|
|
245
247
|
| `themeColor` | Theme color for the site (e.g., `"tomato"`, `"#c04040"`, `"hsl(195 70% 40%)"`) |
|
|
246
248
|
| `tintHue` | *Optional*, hue (0-360) for background and foreground tinting (default `20`) |
|
|
247
249
|
| `tintAmount` | *Optional*, percentage (0-100) of tint to apply (default `100`) |
|
|
250
|
+
| `defaultFont` | *Optional*, initial font pairing: `sans` or `serif` (default `sans`) |
|
|
251
|
+
| `defaultContrast` | *Optional*, initial neutral-palette contrast: `standard` or `high` (default `standard`) |
|
|
248
252
|
| `faviconSymbol` | *Optional*, the text to use instead of `symbol` in the favicon |
|
|
249
253
|
| `features.search` | Enable search UI and Pagefind index generation |
|
|
250
254
|
| `features.favicon` | Enable automatically generated favicons |
|
package/bin/validators.ts
CHANGED
package/build/generate-fonts.ts
CHANGED
|
@@ -6,6 +6,23 @@ import { makeLogger } from './log';
|
|
|
6
6
|
const log = makeLogger(import.meta.url);
|
|
7
7
|
const FONTS_DIR = path.join(getPackageDir(), 'fonts');
|
|
8
8
|
|
|
9
|
+
export const DEFAULT_FONT_PRELOAD_FILES = {
|
|
10
|
+
sans: [
|
|
11
|
+
'inter/InterVariable.woff2',
|
|
12
|
+
'google-sans-code/GoogleSansCodeVariable.woff2',
|
|
13
|
+
],
|
|
14
|
+
serif: [
|
|
15
|
+
'source-serif-4/SourceSerif4-VariableFont_opsz,wght.woff2',
|
|
16
|
+
'libertinus-mono/LibertinusMono-Regular.woff2',
|
|
17
|
+
],
|
|
18
|
+
} as const;
|
|
19
|
+
|
|
20
|
+
export function getDefaultFontPreloadFiles(
|
|
21
|
+
defaultFont: 'sans' | 'serif' | undefined,
|
|
22
|
+
): readonly string[] {
|
|
23
|
+
return DEFAULT_FONT_PRELOAD_FILES[defaultFont ?? 'sans'];
|
|
24
|
+
}
|
|
25
|
+
|
|
9
26
|
export function copyFonts(distDir: string): void {
|
|
10
27
|
log.info`Copying fonts`;
|
|
11
28
|
|
package/build/site-variables.ts
CHANGED
package/build/types.d.ts
CHANGED
|
@@ -16,6 +16,8 @@ export interface SiteVariables {
|
|
|
16
16
|
faviconFontWeight?: number;
|
|
17
17
|
internalDomains?: string[];
|
|
18
18
|
defaultTimeZone: string;
|
|
19
|
+
defaultFont?: 'sans' | 'serif';
|
|
20
|
+
defaultContrast?: 'standard' | 'high';
|
|
19
21
|
features: FeatureConfig;
|
|
20
22
|
extensionToShikiLanguage?: Record<
|
|
21
23
|
string,
|
package/build/utils/render.ts
CHANGED
|
@@ -7,6 +7,7 @@ import { makeLogger } from '../log';
|
|
|
7
7
|
import { B } from '../colors';
|
|
8
8
|
import createTemplateGlobals from '../template-globals';
|
|
9
9
|
import { getExtensionToShikiLanguage } from '../site-variables';
|
|
10
|
+
import { getDefaultFontPreloadFiles } from '../generate-fonts';
|
|
10
11
|
import { config } from '../templates';
|
|
11
12
|
import { render } from '../templates';
|
|
12
13
|
import {
|
|
@@ -157,6 +158,7 @@ export function injectAssetTags(
|
|
|
157
158
|
html: string,
|
|
158
159
|
assetFiles: string[],
|
|
159
160
|
distDir: string,
|
|
161
|
+
siteVariables: SiteVariables,
|
|
160
162
|
): string {
|
|
161
163
|
const jsAssets = assetFiles.filter(f => f.endsWith('.js'));
|
|
162
164
|
const cssAssets = assetFiles.filter(f => f.endsWith('.css'));
|
|
@@ -182,10 +184,7 @@ export function injectAssetTags(
|
|
|
182
184
|
)
|
|
183
185
|
.join('');
|
|
184
186
|
|
|
185
|
-
const fontPreloadTags =
|
|
186
|
-
'inter/InterVariable.woff2',
|
|
187
|
-
'google-sans-code/GoogleSansCodeVariable.woff2',
|
|
188
|
-
]
|
|
187
|
+
const fontPreloadTags = getDefaultFontPreloadFiles(siteVariables.defaultFont)
|
|
189
188
|
.filter(f => fs.existsSync(path.join(distDir, f)))
|
|
190
189
|
.map(
|
|
191
190
|
f =>
|
|
@@ -210,12 +209,14 @@ export function preparePageTemplateHtml({
|
|
|
210
209
|
templateHtml,
|
|
211
210
|
assetFiles,
|
|
212
211
|
distDir,
|
|
212
|
+
siteVariables,
|
|
213
213
|
}: {
|
|
214
214
|
templateHtml: string;
|
|
215
215
|
assetFiles: string[];
|
|
216
216
|
distDir: string;
|
|
217
|
+
siteVariables: SiteVariables;
|
|
217
218
|
}): string {
|
|
218
|
-
let html = injectAssetTags(templateHtml, assetFiles, distDir);
|
|
219
|
+
let html = injectAssetTags(templateHtml, assetFiles, distDir, siteVariables);
|
|
219
220
|
if (templateHtml.includes('class="katex"')) {
|
|
220
221
|
html = injectKatexStylesheet(html);
|
|
221
222
|
}
|
|
@@ -289,7 +290,12 @@ export function renderPlainTextPageAsset({
|
|
|
289
290
|
) as string;
|
|
290
291
|
const finalized = finalizeHtmlPage({
|
|
291
292
|
filePath,
|
|
292
|
-
html: preparePageTemplateHtml({
|
|
293
|
+
html: preparePageTemplateHtml({
|
|
294
|
+
templateHtml,
|
|
295
|
+
assetFiles,
|
|
296
|
+
distDir,
|
|
297
|
+
siteVariables,
|
|
298
|
+
}),
|
|
293
299
|
siteVariables,
|
|
294
300
|
sourceUrlPath,
|
|
295
301
|
validInternalTargets,
|
|
@@ -362,7 +368,12 @@ export function renderCodePageAsset({
|
|
|
362
368
|
const templateHtml = render('code.html', templateParameters) as string;
|
|
363
369
|
const finalized = finalizeHtmlPage({
|
|
364
370
|
filePath,
|
|
365
|
-
html: preparePageTemplateHtml({
|
|
371
|
+
html: preparePageTemplateHtml({
|
|
372
|
+
templateHtml,
|
|
373
|
+
assetFiles,
|
|
374
|
+
distDir,
|
|
375
|
+
siteVariables,
|
|
376
|
+
}),
|
|
366
377
|
siteVariables,
|
|
367
378
|
sourceUrlPath,
|
|
368
379
|
validInternalTargets,
|
|
@@ -700,7 +711,12 @@ export function renderLiterateJavaPageAsset({
|
|
|
700
711
|
const templateHtml = render('literate.html', templateParameters) as string;
|
|
701
712
|
const finalized = finalizeHtmlPage({
|
|
702
713
|
filePath,
|
|
703
|
-
html: preparePageTemplateHtml({
|
|
714
|
+
html: preparePageTemplateHtml({
|
|
715
|
+
templateHtml,
|
|
716
|
+
assetFiles,
|
|
717
|
+
distDir,
|
|
718
|
+
siteVariables,
|
|
719
|
+
}),
|
|
704
720
|
siteVariables,
|
|
705
721
|
sourceUrlPath,
|
|
706
722
|
validInternalTargets,
|
package/build/watch/assets.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import fs from 'fs';
|
|
2
2
|
import path from 'path';
|
|
3
3
|
import { bundle, getBundleNaming } from '../bundle';
|
|
4
|
-
import { copyFonts } from '../generate-fonts';
|
|
4
|
+
import { copyFonts, DEFAULT_FONT_PRELOAD_FILES } from '../generate-fonts';
|
|
5
5
|
import { copyKatexAssets } from '../generate-katex-assets';
|
|
6
6
|
import { generateFavicons } from '../generate-favicon';
|
|
7
7
|
import { generateWebAppManifest } from '../generate-web-app-manifest';
|
|
@@ -72,8 +72,8 @@ export function copyExistingBuildAssets(
|
|
|
72
72
|
): void {
|
|
73
73
|
const relPaths = [
|
|
74
74
|
...assetFiles,
|
|
75
|
-
|
|
76
|
-
|
|
75
|
+
...DEFAULT_FONT_PRELOAD_FILES.sans,
|
|
76
|
+
...DEFAULT_FONT_PRELOAD_FILES.serif,
|
|
77
77
|
];
|
|
78
78
|
|
|
79
79
|
for (const relPath of relPaths) {
|
package/package.json
CHANGED
package/schema/site.schema.json
CHANGED
|
@@ -48,6 +48,16 @@
|
|
|
48
48
|
"default": 700
|
|
49
49
|
},
|
|
50
50
|
"defaultTimeZone": { "type": "string" },
|
|
51
|
+
"defaultFont": {
|
|
52
|
+
"type": "string",
|
|
53
|
+
"enum": ["sans", "serif"],
|
|
54
|
+
"default": "sans"
|
|
55
|
+
},
|
|
56
|
+
"defaultContrast": {
|
|
57
|
+
"type": "string",
|
|
58
|
+
"enum": ["standard", "high"],
|
|
59
|
+
"default": "standard"
|
|
60
|
+
},
|
|
51
61
|
"vars": { "type": "object" },
|
|
52
62
|
"extensionToShikiLanguage": {
|
|
53
63
|
"type": "object",
|
|
@@ -15,11 +15,14 @@ function getStorage(window: Window): Storage | null {
|
|
|
15
15
|
function getStoredPreference<T extends string>(
|
|
16
16
|
storage: Storage | null,
|
|
17
17
|
key: string,
|
|
18
|
-
|
|
18
|
+
storedValues: readonly T[],
|
|
19
19
|
defaultValue: T,
|
|
20
20
|
): T {
|
|
21
21
|
try {
|
|
22
|
-
|
|
22
|
+
const storedValue = storage?.getItem(key);
|
|
23
|
+
return storedValues.includes(storedValue as T)
|
|
24
|
+
? (storedValue as T)
|
|
25
|
+
: defaultValue;
|
|
23
26
|
} catch {
|
|
24
27
|
return defaultValue;
|
|
25
28
|
}
|
|
@@ -29,41 +32,69 @@ function saveStoredPreference<T extends string>(
|
|
|
29
32
|
storage: Storage | null,
|
|
30
33
|
key: string,
|
|
31
34
|
preference: T,
|
|
32
|
-
|
|
35
|
+
defaultValue: T,
|
|
33
36
|
): void {
|
|
34
37
|
try {
|
|
35
|
-
if (preference ===
|
|
36
|
-
storage?.setItem(key, preference);
|
|
37
|
-
} else {
|
|
38
|
+
if (preference === defaultValue) {
|
|
38
39
|
storage?.removeItem(key);
|
|
40
|
+
} else {
|
|
41
|
+
storage?.setItem(key, preference);
|
|
39
42
|
}
|
|
40
43
|
} catch {
|
|
41
44
|
// Storage can be unavailable in privacy-restricted contexts.
|
|
42
45
|
}
|
|
43
46
|
}
|
|
44
47
|
|
|
45
|
-
export function getFontPreference(
|
|
46
|
-
|
|
48
|
+
export function getFontPreference(
|
|
49
|
+
storage: Storage | null,
|
|
50
|
+
defaultValue: FontPreference = 'sans',
|
|
51
|
+
): FontPreference {
|
|
52
|
+
return getStoredPreference(
|
|
53
|
+
storage,
|
|
54
|
+
FONT_STORAGE_KEY,
|
|
55
|
+
['sans', 'serif'],
|
|
56
|
+
defaultValue,
|
|
57
|
+
);
|
|
47
58
|
}
|
|
48
59
|
|
|
49
60
|
export function getContrastPreference(
|
|
50
61
|
storage: Storage | null,
|
|
62
|
+
defaultValue: ContrastPreference = 'standard',
|
|
51
63
|
): ContrastPreference {
|
|
52
|
-
return getStoredPreference(
|
|
64
|
+
return getStoredPreference(
|
|
65
|
+
storage,
|
|
66
|
+
CONTRAST_STORAGE_KEY,
|
|
67
|
+
['standard', 'high'],
|
|
68
|
+
defaultValue,
|
|
69
|
+
);
|
|
53
70
|
}
|
|
54
71
|
|
|
55
72
|
export function saveFontPreference(
|
|
56
73
|
storage: Storage | null,
|
|
57
74
|
preference: FontPreference,
|
|
75
|
+
defaultValue: FontPreference = 'sans',
|
|
58
76
|
): void {
|
|
59
|
-
saveStoredPreference(storage, FONT_STORAGE_KEY, preference,
|
|
77
|
+
saveStoredPreference(storage, FONT_STORAGE_KEY, preference, defaultValue);
|
|
60
78
|
}
|
|
61
79
|
|
|
62
80
|
export function saveContrastPreference(
|
|
63
81
|
storage: Storage | null,
|
|
64
82
|
preference: ContrastPreference,
|
|
83
|
+
defaultValue: ContrastPreference = 'standard',
|
|
65
84
|
): void {
|
|
66
|
-
saveStoredPreference(storage, CONTRAST_STORAGE_KEY, preference,
|
|
85
|
+
saveStoredPreference(storage, CONTRAST_STORAGE_KEY, preference, defaultValue);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
function getDefaultFontPreference(document: Document): FontPreference {
|
|
89
|
+
return document.documentElement.dataset.defaultFontPreference === 'serif'
|
|
90
|
+
? 'serif'
|
|
91
|
+
: 'sans';
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
function getDefaultContrastPreference(document: Document): ContrastPreference {
|
|
95
|
+
return document.documentElement.dataset.defaultContrastPreference === 'high'
|
|
96
|
+
? 'high'
|
|
97
|
+
: 'standard';
|
|
67
98
|
}
|
|
68
99
|
|
|
69
100
|
export function applyFontPreference(
|
|
@@ -71,8 +102,10 @@ export function applyFontPreference(
|
|
|
71
102
|
preference: FontPreference,
|
|
72
103
|
): void {
|
|
73
104
|
if (preference === 'serif') {
|
|
74
|
-
document.documentElement.dataset.fontPreference
|
|
75
|
-
|
|
105
|
+
if (document.documentElement.dataset.fontPreference !== preference) {
|
|
106
|
+
document.documentElement.dataset.fontPreference = preference;
|
|
107
|
+
}
|
|
108
|
+
} else if (document.documentElement.dataset.fontPreference !== undefined) {
|
|
76
109
|
delete document.documentElement.dataset.fontPreference;
|
|
77
110
|
}
|
|
78
111
|
}
|
|
@@ -82,8 +115,12 @@ export function applyContrastPreference(
|
|
|
82
115
|
preference: ContrastPreference,
|
|
83
116
|
): void {
|
|
84
117
|
if (preference === 'high') {
|
|
85
|
-
document.documentElement.dataset.contrastPreference
|
|
86
|
-
|
|
118
|
+
if (document.documentElement.dataset.contrastPreference !== preference) {
|
|
119
|
+
document.documentElement.dataset.contrastPreference = preference;
|
|
120
|
+
}
|
|
121
|
+
} else if (
|
|
122
|
+
document.documentElement.dataset.contrastPreference !== undefined
|
|
123
|
+
) {
|
|
87
124
|
delete document.documentElement.dataset.contrastPreference;
|
|
88
125
|
}
|
|
89
126
|
}
|
|
@@ -129,8 +166,13 @@ export default function mountAppearancePicker(window: Window): () => void {
|
|
|
129
166
|
container.querySelectorAll<HTMLButtonElement>('button'),
|
|
130
167
|
);
|
|
131
168
|
const storage = getStorage(window);
|
|
132
|
-
|
|
133
|
-
|
|
169
|
+
const defaultFontPreference = getDefaultFontPreference(document);
|
|
170
|
+
const defaultContrastPreference = getDefaultContrastPreference(document);
|
|
171
|
+
let fontPreference = getFontPreference(storage, defaultFontPreference);
|
|
172
|
+
let contrastPreference = getContrastPreference(
|
|
173
|
+
storage,
|
|
174
|
+
defaultContrastPreference,
|
|
175
|
+
);
|
|
134
176
|
|
|
135
177
|
applyFontPreference(document, fontPreference);
|
|
136
178
|
applyContrastPreference(document, contrastPreference);
|
|
@@ -143,11 +185,15 @@ export default function mountAppearancePicker(window: Window): () => void {
|
|
|
143
185
|
|
|
144
186
|
if (fontValue === 'sans' || fontValue === 'serif') {
|
|
145
187
|
fontPreference = fontValue;
|
|
146
|
-
saveFontPreference(storage, fontPreference);
|
|
188
|
+
saveFontPreference(storage, fontPreference, defaultFontPreference);
|
|
147
189
|
applyFontPreference(document, fontPreference);
|
|
148
190
|
} else if (contrastValue === 'standard' || contrastValue === 'high') {
|
|
149
191
|
contrastPreference = contrastValue;
|
|
150
|
-
saveContrastPreference(
|
|
192
|
+
saveContrastPreference(
|
|
193
|
+
storage,
|
|
194
|
+
contrastPreference,
|
|
195
|
+
defaultContrastPreference,
|
|
196
|
+
);
|
|
151
197
|
applyContrastPreference(document, contrastPreference);
|
|
152
198
|
} else {
|
|
153
199
|
return;
|
|
@@ -75,8 +75,10 @@
|
|
|
75
75
|
}
|
|
76
76
|
|
|
77
77
|
.font-picker-option-sans {
|
|
78
|
-
font-family:
|
|
79
|
-
|
|
78
|
+
font-family:
|
|
79
|
+
-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial,
|
|
80
|
+
sans-serif;
|
|
81
|
+
font-feature-settings: normal;
|
|
80
82
|
}
|
|
81
83
|
|
|
82
84
|
.font-picker-option-serif {
|
|
@@ -86,6 +88,15 @@
|
|
|
86
88
|
font-feature-settings: var(--serif-font-feature-settings);
|
|
87
89
|
}
|
|
88
90
|
|
|
91
|
+
:root:not([data-font-preference='serif']) .font-picker-option-sans {
|
|
92
|
+
font-family: var(--sans-font);
|
|
93
|
+
font-feature-settings: var(--sans-font-feature-settings);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
:root[data-font-preference='serif'] .font-picker-option-serif {
|
|
97
|
+
font-family: var(--serif-font);
|
|
98
|
+
}
|
|
99
|
+
|
|
89
100
|
.material-symbol-icon {
|
|
90
101
|
width: 1.25rem;
|
|
91
102
|
height: 1.25rem;
|
package/src/header/_base.scss
CHANGED
package/src/header/style.scss
CHANGED
|
@@ -50,10 +50,18 @@ header nav div > p {
|
|
|
50
50
|
@include user-select(none);
|
|
51
51
|
}
|
|
52
52
|
|
|
53
|
+
:root[data-contrast-preference='high'] header:has(details[open]) {
|
|
54
|
+
background: var(--bg2-color);
|
|
55
|
+
}
|
|
56
|
+
|
|
53
57
|
@media (hover: hover) {
|
|
54
58
|
header:has(details[open]):hover {
|
|
55
59
|
background: var(--bg-color-translucent);
|
|
56
60
|
}
|
|
61
|
+
|
|
62
|
+
:root[data-contrast-preference='high'] header:hover {
|
|
63
|
+
background: var(--bg2-color);
|
|
64
|
+
}
|
|
57
65
|
}
|
|
58
66
|
|
|
59
67
|
header .results-container {
|
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
<div class="appearance-pickers" data-pagefind-ignore>
|
|
2
2
|
<div class="preference-picker font-picker" role="group" aria-label="Font style">
|
|
3
|
-
<button type="button" class="preference-picker-option font-picker-option-sans" data-font-preference-value="sans" aria-label="Use sans-serif fonts" aria-pressed="
|
|
3
|
+
<button type="button" class="preference-picker-option font-picker-option-sans" data-font-preference-value="sans" aria-label="Use sans-serif fonts" aria-pressed="<%= site.defaultFont === 'sans' %>" disabled>
|
|
4
4
|
<span aria-hidden="true">Aa</span>
|
|
5
5
|
</button>
|
|
6
|
-
<button type="button" class="preference-picker-option font-picker-option-serif" data-font-preference-value="serif" aria-label="Use serif fonts" aria-pressed="
|
|
6
|
+
<button type="button" class="preference-picker-option font-picker-option-serif" data-font-preference-value="serif" aria-label="Use serif fonts" aria-pressed="<%= site.defaultFont === 'serif' %>" disabled>
|
|
7
7
|
<span aria-hidden="true">Aa</span>
|
|
8
8
|
</button>
|
|
9
9
|
</div>
|
|
10
10
|
<div class="preference-picker contrast-picker" role="group" aria-label="Contrast">
|
|
11
|
-
<button type="button" class="preference-picker-option contrast-picker-option-standard" data-contrast-preference-value="standard" aria-label="Use standard contrast" aria-pressed="
|
|
11
|
+
<button type="button" class="preference-picker-option contrast-picker-option-standard" data-contrast-preference-value="standard" aria-label="Use standard contrast" aria-pressed="<%= site.defaultContrast === 'standard' %>" disabled>
|
|
12
12
|
<span class="material-symbol-icon material-symbol-icon-contrast-standard" aria-hidden="true"></span>
|
|
13
13
|
</button>
|
|
14
|
-
<button type="button" class="preference-picker-option contrast-picker-option-high" data-contrast-preference-value="high" aria-label="Use high contrast" aria-pressed="
|
|
14
|
+
<button type="button" class="preference-picker-option contrast-picker-option-high" data-contrast-preference-value="high" aria-label="Use high contrast" aria-pressed="<%= site.defaultContrast === 'high' %>" disabled>
|
|
15
15
|
<span class="material-symbol-icon material-symbol-icon-contrast-high" aria-hidden="true"></span>
|
|
16
16
|
</button>
|
|
17
17
|
</div>
|
package/templates/_top.html
CHANGED
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
<!doctype html>
|
|
2
|
-
<html lang="en"
|
|
2
|
+
<html lang="en"
|
|
3
|
+
data-default-font-preference="<%= site.defaultFont %>"
|
|
4
|
+
data-default-contrast-preference="<%= site.defaultContrast %>"<% if (site.defaultFont === 'serif') { %>
|
|
5
|
+
data-font-preference="serif"<% } %><% if (site.defaultContrast === 'high') { %>
|
|
6
|
+
data-contrast-preference="high"<% } %>>
|
|
3
7
|
<head>
|
|
4
8
|
<% if (site.features.favicon) { %>
|
|
5
9
|
<link rel="icon" href="/favicon.ico" sizes="any" />
|
|
@@ -36,13 +40,33 @@
|
|
|
36
40
|
<script>
|
|
37
41
|
document.documentElement.classList.add('js');
|
|
38
42
|
try {
|
|
39
|
-
|
|
40
|
-
|
|
43
|
+
const preference = window.localStorage.getItem('fontPreference');
|
|
44
|
+
const configured =
|
|
45
|
+
document.documentElement.dataset.defaultFontPreference;
|
|
46
|
+
if (
|
|
47
|
+
(preference === 'serif' || preference === 'sans') &&
|
|
48
|
+
preference !== configured
|
|
49
|
+
) {
|
|
50
|
+
if (preference === 'serif') {
|
|
51
|
+
document.documentElement.dataset.fontPreference = 'serif';
|
|
52
|
+
} else {
|
|
53
|
+
delete document.documentElement.dataset.fontPreference;
|
|
54
|
+
}
|
|
41
55
|
}
|
|
42
56
|
} catch {}
|
|
43
57
|
try {
|
|
44
|
-
|
|
45
|
-
|
|
58
|
+
const preference = window.localStorage.getItem('contrastPreference');
|
|
59
|
+
const configured =
|
|
60
|
+
document.documentElement.dataset.defaultContrastPreference;
|
|
61
|
+
if (
|
|
62
|
+
(preference === 'high' || preference === 'standard') &&
|
|
63
|
+
preference !== configured
|
|
64
|
+
) {
|
|
65
|
+
if (preference === 'high') {
|
|
66
|
+
document.documentElement.dataset.contrastPreference = 'high';
|
|
67
|
+
} else {
|
|
68
|
+
delete document.documentElement.dataset.contrastPreference;
|
|
69
|
+
}
|
|
46
70
|
}
|
|
47
71
|
} catch {}
|
|
48
72
|
</script>
|