From f8d272d9adc83e2a87f2c8670b8e60cb2feb6175 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nuno=20Cora=C3=A7=C3=A3o?= Date: Sun, 3 Aug 2025 02:14:14 +0100 Subject: [PATCH 01/63] new version --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 5f2dfc1d..d99922ca 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "hugo-blowfish-theme", - "version": "2.89.0", + "version": "2.90.0", "description": "Blowfish theme for Hugo.", "scripts": { "postinstall": "vendor-copy", From 6a4123f59fe55de25395bbcd9786d29443359c18 Mon Sep 17 00:00:00 2001 From: ZhenShuo Leo <98386542+ZhenShuo2021@users.noreply.github.com> Date: Sat, 2 Aug 2025 19:54:43 +0800 Subject: [PATCH 02/63] fix(fetch-repo): prevent DOM updates with invalid remote data --- assets/js/fetch-repo.js | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/assets/js/fetch-repo.js b/assets/js/fetch-repo.js index 07b8f6a8..61bedfd0 100644 --- a/assets/js/fetch-repo.js +++ b/assets/js/fetch-repo.js @@ -64,6 +64,16 @@ }); const data = await response.json(); + if (!response.ok) { + console.error(`fetch-repo.js: HTTP Error: ${response.status} ${response.statusText}`); + return; + } + + if (!data || typeof data !== "object") { + console.error("fetch-repo.js: Invalid or empty data received from remote"); + return; + } + Object.entries(mapping).forEach(([dataField, elementSuffix]) => { const element = document.getElementById(`${repoId}-${elementSuffix}`); if (element) { @@ -71,7 +81,9 @@ if (processors[platform]?.[dataField]) { value = processors[platform][dataField](value); } - element.innerHTML = value; + if (value != null && value !== "") { + element.innerHTML = value; + } } }); } catch (error) { From 571b875f4a4b5fb1bc36349311371fb254a2c936 Mon Sep 17 00:00:00 2001 From: ZhenShuo Leo <98386542+ZhenShuo2021@users.noreply.github.com> Date: Sun, 3 Aug 2025 19:05:33 +0800 Subject: [PATCH 03/63] fix(figure): limit link hover area to image only --- layouts/partials/hugo-embedded/shortcodes/figure-default.html | 2 +- layouts/shortcodes/figure.html | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/layouts/partials/hugo-embedded/shortcodes/figure-default.html b/layouts/partials/hugo-embedded/shortcodes/figure-default.html index e74d30be..74b12124 100644 --- a/layouts/partials/hugo-embedded/shortcodes/figure-default.html +++ b/layouts/partials/hugo-embedded/shortcodes/figure-default.html @@ -5,7 +5,7 @@ {{- if .Get "link" -}} - + {{- end -}} {{- $u := urls.Parse (.Get "src") -}} diff --git a/layouts/shortcodes/figure.html b/layouts/shortcodes/figure.html index 0b429187..35f5e331 100644 --- a/layouts/shortcodes/figure.html +++ b/layouts/shortcodes/figure.html @@ -11,7 +11,7 @@ {{- $nozoom := .Get "nozoom" | default false -}}
- {{- with $href }}{{ end -}} + {{- with $href }}{{ end -}} {{- if findRE "^https?" $url.Scheme }} {{ $altText }} {{- else }} @@ -45,7 +45,7 @@ {{ $altText }} {{- end }} {{- end }} - {{ with $caption }}
{{ . | markdownify }}
{{ end }} {{ if $href }}
{{ end }} + {{ with $caption }}
{{ . | markdownify }}
{{ end }}
{{- end -}} From 10ffbca4c0976df654cc2ffd42d106992aaf9a62 Mon Sep 17 00:00:00 2001 From: ZhenShuo Leo <98386542+ZhenShuo2021@users.noreply.github.com> Date: Tue, 5 Aug 2025 16:14:24 +0800 Subject: [PATCH 04/63] refactor(a11y): simply code --- assets/js/a11y.js | 338 +++++++++++++++++++++------------------------- 1 file changed, 156 insertions(+), 182 deletions(-) diff --git a/assets/js/a11y.js b/assets/js/a11y.js index 3117ae72..4c375b7c 100644 --- a/assets/js/a11y.js +++ b/assets/js/a11y.js @@ -1,194 +1,168 @@ -const getA11ySettings = () => { - const settings = localStorage.getItem("a11ySettings"); - return settings - ? JSON.parse(settings) - : { - disableBlur: false, - disableImages: false, - fontSize: "default", - underlineLinks: false, - zenMode: false, - }; -}; +window.A11yPanel = (() => { + const FEATURES = { + disableBlur: { + default: false, + apply: (enabled) => { + document.querySelectorAll("script[data-target-id]").forEach((script) => { + const targetId = script.getAttribute("data-target-id"); + const scrollDivisor = Number(script.getAttribute("data-scroll-divisor") || 300); + if (typeof setBackgroundBlur === "function") { + setBackgroundBlur(targetId, scrollDivisor, enabled, targetId === "menu-blur"); + } + }); + }, + }, -const saveA11ySettings = (settings) => { - localStorage.setItem("a11ySettings", JSON.stringify(settings)); -}; + disableImages: { + default: false, + apply: (enabled) => { + document.querySelectorAll("script[data-target-id]").forEach((script) => { + const image = document.getElementById(script.getAttribute("data-image-id")); + const imageUrl = script.getAttribute("data-image-url"); + if (image) { + image.style.display = enabled ? "none" : ""; + if (!enabled && imageUrl && !image.src) image.src = imageUrl; + } + }); + }, + }, -const applyImageState = (imageElement, imageUrl, disableImages) => { - if (!imageElement) return; - if (disableImages) { - imageElement.style.display = "none"; - } else { - imageElement.style.display = ""; - if (imageUrl && !imageElement.getAttribute("src")) { - imageElement.setAttribute("src", imageUrl); + fontSize: { + default: "default", + apply: (size) => { + document.documentElement.style.fontSize = size === "default" ? "" : size; + }, + }, + + underlineLinks: { + default: false, + apply: (enabled) => { + const existing = document.getElementById("a11y-underline-links"); + if (enabled && !existing) { + const style = document.createElement("style"); + style.id = "a11y-underline-links"; + style.textContent = "a { text-decoration: underline !important; }"; + document.head.appendChild(style); + } else if (!enabled && existing) { + existing.remove(); + } + }, + }, + + zenMode: { + default: false, + apply: (enabled) => { + const isActive = document.body?.classList.contains("zen-mode-enable"); + if (enabled !== isActive) { + const checkbox = document.querySelector('[id$="zen-mode"]'); + if (checkbox && typeof _toggleZenMode === "function") { + _toggleZenMode(checkbox, { scrollToHeader: false }); + } + } + }, + }, + }; + + let settings = null; + + const getSettings = () => { + if (settings) return settings; + const defaults = Object.fromEntries(Object.entries(FEATURES).map(([key, config]) => [key, config.default])); + try { + const saved = localStorage.getItem("a11ySettings"); + settings = { ...defaults, ...JSON.parse(saved || "{}") }; + } catch { + settings = defaults; } - } -}; + return settings; + }; -const applyFontSize = (fontSizePx) => { - const isDefaultSettings = localStorage.getItem("a11ySettings") === null; - if (!isDefaultSettings && fontSizePx !== "default") { - document.documentElement.style.fontSize = fontSizePx; - } -}; - -const applyUnderlineLinks = (enabled) => { - let styleElement = document.getElementById("a11y-underline-links"); - if (enabled) { - if (!styleElement) { - styleElement = document.createElement("style"); - styleElement.id = "a11y-underline-links"; - styleElement.textContent = "a { text-decoration: underline !important; }"; - document.head.appendChild(styleElement); + const updateSetting = (key, value) => { + const current = getSettings(); + current[key] = value; + try { + localStorage.setItem("a11ySettings", JSON.stringify(current)); + } catch (e) { + console.warn(`a11y.js: can not store settings: ${e}`); } - } else { - if (styleElement) { - styleElement.remove(); - } - } -}; + FEATURES[key]?.apply(value); + }; -const applyZenMode = (enabled) => { - const body = document.querySelector("body"); - const isZenModeActive = body && body.classList.contains("zen-mode-enable"); + const initPanel = (panelId) => { + const prefix = panelId.replace("a11y-panel", ""); + const current = getSettings(); - // Toggle only if current state doesn't match desired state - if (enabled !== isZenModeActive) { - const zenModeCheckbox = document.querySelector('[id$="zen-mode"]'); - if (zenModeCheckbox && typeof _toggleZenMode === "function") { - _toggleZenMode(zenModeCheckbox, { scrollToHeader: false }); - } - } -}; + Object.entries(FEATURES).forEach(([key, config]) => { + const elementId = `${prefix}${key.replace(/([A-Z])/g, "-$1").toLowerCase()}`; + const element = document.getElementById(elementId) || document.getElementById(`${elementId}-select`); -const applyA11ySettings = () => { - const settings = getA11ySettings(); - document.querySelectorAll("script[data-target-id]").forEach((script) => { - const targetId = script.getAttribute("data-target-id"); - const scrollDivisor = Number(script.getAttribute("data-scroll-divisor") || 300); - const imageId = script.getAttribute("data-image-id"); - const imageUrl = script.getAttribute("data-image-url"); - const isMenuBlur = targetId === "menu-blur"; - setBackgroundBlur(targetId, scrollDivisor, settings.disableBlur, isMenuBlur); - applyImageState(document.getElementById(imageId), imageUrl, settings.disableImages); - }); - applyFontSize(settings.fontSize); - applyUnderlineLinks(settings.underlineLinks); - applyZenMode(settings.zenMode); -}; - -const updateA11ySetting = (key, value) => { - const settings = getA11ySettings(); - settings[key] = value; - saveA11ySettings(settings); - applyA11ySettings(); -}; - -const toggleA11yPanel = (prefix = "") => { - const panel = document.getElementById(`${prefix}a11y-panel`); - const overlay = document.getElementById(`${prefix}a11y-overlay`); - const button = document.getElementById(`${prefix}a11y-toggle`); - if (!panel || !overlay || !button) return; - if (overlay.classList.contains("hidden")) { - overlay.classList.remove("hidden"); - panel.classList.remove("hidden"); - button.setAttribute("aria-pressed", "true"); - button.setAttribute("aria-expanded", "true"); - } else { - overlay.classList.add("hidden"); - panel.classList.add("hidden"); - button.setAttribute("aria-pressed", "false"); - button.setAttribute("aria-expanded", "false"); - } -}; - -const initA11yPanel = (prefix = "") => { - const settings = getA11ySettings(); - const checkboxBlur = document.getElementById(`${prefix}disable-blur`); - const checkboxImages = document.getElementById(`${prefix}disable-images`); - const checkboxUnderline = document.getElementById(`${prefix}underline-links`); - const checkboxZenMode = document.getElementById(`${prefix}zen-mode`); - const fontSizeSelect = document.getElementById(`${prefix}font-size-select`); - const toggleButton = document.getElementById(`${prefix}a11y-toggle`); - const closeButton = document.getElementById(`${prefix}a11y-close`); - const overlay = document.getElementById(`${prefix}a11y-overlay`); - - if ( - !checkboxBlur || - !checkboxImages || - !checkboxUnderline || - !checkboxZenMode || - !fontSizeSelect || - !toggleButton || - !closeButton || - !overlay - ) { - console.warn(`One or more a11y elements not found for prefix: ${prefix}`); - return; - } - - checkboxBlur.checked = settings.disableBlur; - checkboxImages.checked = settings.disableImages; - checkboxUnderline.checked = settings.underlineLinks; - checkboxZenMode.checked = settings.zenMode; - fontSizeSelect.value = settings.fontSize; - - checkboxBlur.addEventListener("change", (e) => updateA11ySetting("disableBlur", e.target.checked)); - checkboxImages.addEventListener("change", (e) => updateA11ySetting("disableImages", e.target.checked)); - checkboxUnderline.addEventListener("change", (e) => updateA11ySetting("underlineLinks", e.target.checked)); - checkboxZenMode.addEventListener("change", (e) => { - // Only save setting, let applyZenMode handle the toggle logic - updateA11ySetting("zenMode", e.target.checked); - }); - fontSizeSelect.addEventListener("change", (e) => { - // Remove fontSize from localStorage when default is selected - if (e.target.value === "default") { - const settings = getA11ySettings(); - delete settings.fontSize; - saveA11ySettings(settings); - document.documentElement.style.fontSize = ""; - } else { - updateA11ySetting("fontSize", e.target.value); - } - }); - - toggleButton.addEventListener("click", () => toggleA11yPanel(prefix)); - closeButton.addEventListener("click", () => toggleA11yPanel(prefix)); - overlay.addEventListener("click", (e) => { - if (e.target === overlay) { - toggleA11yPanel(prefix); - } - }); - - document.querySelectorAll(`.ios-toggle${prefix ? `[id^="${prefix}"]` : ""}`).forEach((toggle) => { - const checkbox = toggle.querySelector('input[type="checkbox"]'); - if (!checkbox) return; - const newToggle = toggle.cloneNode(true); - toggle.parentNode.replaceChild(newToggle, toggle); - newToggle.addEventListener("click", () => { - const newCheckbox = newToggle.querySelector('input[type="checkbox"]'); - if (newCheckbox) { - newCheckbox.checked = !newCheckbox.checked; - newCheckbox.dispatchEvent(new Event("change", { bubbles: true })); + if (element) { + if (element.type === "checkbox") { + element.checked = current[key]; + element.onchange = (e) => updateSetting(key, e.target.checked); + } else if (element.tagName === "SELECT") { + element.value = current[key]; + element.onchange = (e) => updateSetting(key, e.target.value); + } } }); - }); -}; -document.querySelectorAll("script[data-target-id]").forEach((script) => { - const imageId = script.getAttribute("data-image-id"); - const imageUrl = script.getAttribute("data-image-url"); - const settings = getA11ySettings(); - applyImageState(document.getElementById(imageId), imageUrl, settings.disableImages); -}); + const togglePanel = () => { + const panel = document.getElementById(panelId); + const overlay = document.getElementById(`${prefix}a11y-overlay`); + const toggle = document.getElementById(`${prefix}a11y-toggle`); -document.addEventListener("DOMContentLoaded", () => { - applyA11ySettings(); - const allPanels = document.querySelectorAll('[id$="a11y-panel"]'); - allPanels.forEach((panel) => { - const prefix = panel.id.replace("a11y-panel", ""); - initA11yPanel(prefix); - }); -}); + if (!panel || !overlay) return; + + const isHidden = overlay.classList.contains("hidden"); + overlay.classList.toggle("hidden"); + panel.classList.toggle("hidden"); + + if (toggle) { + toggle.setAttribute("aria-pressed", String(isHidden)); + toggle.setAttribute("aria-expanded", String(isHidden)); + } + }; + + const toggle = document.getElementById(`${prefix}a11y-toggle`); + const close = document.getElementById(`${prefix}a11y-close`); + const overlay = document.getElementById(`${prefix}a11y-overlay`); + + if (toggle) toggle.onclick = togglePanel; + if (close) close.onclick = togglePanel; + if (overlay) overlay.onclick = (e) => e.target === overlay && togglePanel(); + }; + + const applyAll = () => { + const current = getSettings(); + Object.entries(current).forEach(([key, value]) => { + FEATURES[key]?.apply(value); + }); + }; + + const init = () => { + applyAll(); + document.querySelectorAll('[id$="a11y-panel"]').forEach((panel) => { + initPanel(panel.id); + }); + }; + + if (getSettings().disableImages) { + FEATURES.disableImages.apply(true); + } + + if (document.readyState === "loading") { + document.addEventListener("DOMContentLoaded", init); + } else { + init(); + } + + return { + getSettings, + updateSetting, + addFeature: (name, config) => { + FEATURES[name] = config; + FEATURES[name].apply(getSettings()[name] || config.default); + }, + }; +})(); From ade00547b3d3bf137641080b65216742ac462062 Mon Sep 17 00:00:00 2001 From: ZhenShuo Leo <98386542+ZhenShuo2021@users.noreply.github.com> Date: Tue, 5 Aug 2025 16:39:50 +0800 Subject: [PATCH 05/63] fix(a11y): disableImages not working when layoutBackgroundBlur is false --- assets/js/a11y.js | 12 ++++------ layouts/partials/header/basic.html | 9 ++++--- layouts/partials/hero/thumbAndBackground.html | 24 +++++++------------ layouts/partials/home/background.html | 4 ++-- 4 files changed, 20 insertions(+), 29 deletions(-) diff --git a/assets/js/a11y.js b/assets/js/a11y.js index 4c375b7c..48603832 100644 --- a/assets/js/a11y.js +++ b/assets/js/a11y.js @@ -16,14 +16,10 @@ window.A11yPanel = (() => { disableImages: { default: false, apply: (enabled) => { - document.querySelectorAll("script[data-target-id]").forEach((script) => { - const image = document.getElementById(script.getAttribute("data-image-id")); - const imageUrl = script.getAttribute("data-image-url"); - if (image) { - image.style.display = enabled ? "none" : ""; - if (!enabled && imageUrl && !image.src) image.src = imageUrl; - } - }); + const image = document.getElementById("background-image"); + if (image) { + image.style.display = enabled ? "none" : ""; + } }, }, diff --git a/layouts/partials/header/basic.html b/layouts/partials/header/basic.html index 18aab05e..328d04e0 100644 --- a/layouts/partials/header/basic.html +++ b/layouts/partials/header/basic.html @@ -198,14 +198,17 @@
- {{- $toggles := slice - (dict "id" (print $prefix "disable-blur") "label" (i18n "a11y.disable_blur")) + {{ $toggles := slice }} + {{ $shouldDisableBlur := or site.Params.homepage.layoutBackgroundBlur site.Params.article.layoutBackgroundBlur site.Params.list.layoutBackgroundBlur }} + {{ if $shouldDisableBlur }} + {{ $toggles = $toggles | append (dict "id" (print $prefix "disable-blur") "label" (i18n "a11y.disable_blur")) }} + {{ end }} + {{- $toggles = $toggles | append (dict "id" (print $prefix "disable-images") "label" (i18n "a11y.disable_images")) (dict "id" (print $prefix "underline-links") "label" (i18n "a11y.show_link_underline")) (dict "id" (print $prefix "zen-mode") "label" (i18n "article.zen_mode_title.enable")) -}} - {{- range $toggles }}
-
- -
These checks highlight opportunities to improve the accessibility of your web app. Only a subset of accessibility issues can be automatically detected so manual testing is also encouraged.
-
-
- -
-
- Additional items to manually check - (10) - - - These items address areas which an automated testing tool cannot cover. Learn more in our guide on conducting an accessibility review.
-
- - - - - -
-
-
-
- -
- - - The page has a logical tab order - - -
- - - - -
-
-
-
Tabbing through the page follows the visual layout. Users cannot focus elements that are offscreen. Learn more.
-
-
-
-
- -
- - - Interactive controls are keyboard focusable - - -
- - - - -
-
-
-
Custom interactive controls are keyboard focusable and display a focus indicator. Learn more.
-
-
-
-
- -
- - - Interactive elements indicate their purpose and state - - -
- - - - -
-
-
-
Interactive elements, such as links and buttons, should indicate their state and be distinguishable from non-interactive elements. Learn more.
-
-
-
-
- -
- - - The user's focus is directed to new content added to the page - - -
- - - - -
-
-
-
If new content, such as a dialog, is added to the page, the user's focus is directed to it. Learn more.
-
-
-
-
- -
- - - User focus is not accidentally trapped in a region - - -
- - - - -
-
-
-
A user can tab into and out of any control or region without accidentally trapping their focus. Learn more.
-
-
-
-
- -
- - - Custom controls have associated labels - - -
- - - - -
-
-
-
Custom interactive controls have associated labels, provided by aria-label or aria-labelledby. Learn more.
-
-
-
-
- -
- - - Custom controls have ARIA roles - - -
- - - - -
-
-
-
Custom interactive controls have appropriate ARIA roles. Learn more.
-
-
-
-
- -
- - - Visual order on the page follows DOM order - - -
- - - - -
-
-
-
DOM order matches the visual order, improving navigation for assistive technology. Learn more.
-
-
-
-
- -
- - - Offscreen content is hidden from assistive technology - - -
- - - - -
-
-
-
Offscreen content is hidden with display: none or aria-hidden=true. Learn more.
-
-
-
-
- -
- - - HTML5 landmark elements are used to improve navigation - - -
- - - - -
-
-
-
Landmark elements (<main>, <nav>, etc.) are used to improve the keyboard navigation of the page for assistive technology. Learn more.
-
-
-
- -
-
- Passed audits - (18) - - -
-
- - - - - -
-
-
-
- -
- - - [aria-*] attributes match their roles - - -
- - - - -
-
-
-
Each ARIA `role` supports a specific subset of `aria-*` attributes. Mismatching these invalidates the `aria-*` attributes. Learn more.
-
-
-
-
- -
- - - [aria-hidden="true"] is not present on the document <body> - - -
- - - - -
-
-
-
Assistive technologies, like screen readers, work inconsistently when `aria-hidden="true"` is set on the document `<body>`. Learn more.
-
-
-
-
- -
- - - [aria-hidden="true"] elements do not contain focusable descendents - - -
- - - - -
-
-
-
Focusable descendents within an `[aria-hidden="true"]` element prevent those interactive elements from being available to users of assistive technologies like screen readers. Learn more.
-
-
-
-
- -
- - - [aria-*] attributes have valid values - - -
- - - - -
-
-
-
Assistive technologies, like screen readers, can't interpret ARIA attributes with invalid values. Learn more.
-
-
-
-
- -
- - - [aria-*] attributes are valid and not misspelled - - -
- - - - -
-
-
-
Assistive technologies, like screen readers, can't interpret ARIA attributes with invalid names. Learn more.
-
-
-
-
- -
- - - Buttons have an accessible name - - -
- - - - -
-
-
-
When a button doesn't have an accessible name, screen readers announce it as "button", making it unusable for users who rely on screen readers. Learn more.
-
-
-
-
- -
- - - The page contains a heading, skip link, or landmark region - - -
- - - - -
-
-
-
Adding ways to bypass repetitive content lets keyboard users navigate the page more efficiently. Learn more.
-
-
-
-
- -
- - - Background and foreground colors have a sufficient contrast ratio - - -
- - - - -
-
-
-
Low-contrast text is difficult or impossible for many users to read. Learn more.
-
-
-
-
- -
- - - Document has a <title> element - - -
- - - - -
-
-
-
The title gives screen reader users an overview of the page, and search engine users rely on it heavily to determine if a page is relevant to their search. Learn more.
-
-
-
-
- -
- - - [id] attributes on active, focusable elements are unique - - -
- - - - -
-
-
-
All focusable elements must have a unique `id` to ensure that they're visible to assistive technologies. Learn more.
-
-
-
-
- -
- - - Heading elements appear in a sequentially-descending order - - -
- - - - -
-
-
-
Properly ordered headings that do not skip levels convey the semantic structure of the page, making it easier to navigate and understand when using assistive technologies. Learn more.
-
-
-
-
- -
- - - <html> element has a [lang] attribute - - -
- - - - -
-
-
-
If a page doesn't specify a lang attribute, a screen reader assumes that the page is in the default language that the user chose when setting up the screen reader. If the page isn't actually in the default language, then the screen reader might not announce the page's text correctly. Learn more.
-
-
-
-
- -
- - - <html> element has a valid value for its [lang] attribute - - -
- - - - -
-
-
-
Specifying a valid BCP 47 language helps screen readers announce text properly. Learn more.
-
-
-
-
- -
- - - Image elements have [alt] attributes - - -
- - - - -
-
-
-
Informative elements should aim for short, descriptive alternate text. Decorative elements can be ignored with an empty alt attribute. Learn more.
-
-
-
-
- -
- - - Lists contain only <li> elements and script supporting elements (<script> and <template>). - - -
- - - - -
-
-
-
Screen readers have a specific way of announcing lists. Ensuring proper list structure aids screen reader output. Learn more.
-
-
-
-
- -
- - - List items (<li>) are contained within <ul> or <ol> parent elements - - -
- - - - -
-
-
-
Screen readers require list items (`<li>`) to be contained within a parent `<ul>` or `<ol>` to be announced properly. Learn more.
-
-
-
-
- -
- - - [user-scalable="no"] is not used in the <meta name="viewport"> element and the [maximum-scale] attribute is not less than 5. - - -
- - - - -
-
-
-
Disabling zooming is problematic for users with low vision who rely on screen magnification to properly see the contents of a web page. Learn more.
-
-
-
- -
-
- Not applicable - (26) - - -
-
- - - - - -
-
-
-
- -
- - - [accesskey] values are unique - - -
- - - - -
-
-
-
Access keys let users quickly focus a part of the page. For proper navigation, each access key must be unique. Learn more.
-
-
-
-
- -
- - - button, link, and menuitem elements have accessible names - - -
- - - - -
-
-
-
When an element doesn't have an accessible name, screen readers announce it with a generic name, making it unusable for users who rely on screen readers. Learn more.
-
-
-
-
- -
- - - ARIA input fields have accessible names - - -
- - - - -
-
-
-
When an input field doesn't have an accessible name, screen readers announce it with a generic name, making it unusable for users who rely on screen readers. Learn more.
-
-
-
-
- -
- - - ARIA meter elements have accessible names - - -
- - - - -
-
-
-
When an element doesn't have an accessible name, screen readers announce it with a generic name, making it unusable for users who rely on screen readers. Learn more.
-
-
-
-
- -
- - - ARIA progressbar elements have accessible names - - -
- - - - -
-
-
-
When an element doesn't have an accessible name, screen readers announce it with a generic name, making it unusable for users who rely on screen readers. Learn more.
-
-
-
-
- -
- - - [role]s have all required [aria-*] attributes - - -
- - - - -
-
-
-
Some ARIA roles have required attributes that describe the state of the element to screen readers. Learn more.
-
-
-
-
- -
- - - Elements with an ARIA [role] that require children to contain a specific [role] have all required children. - - -
- - - - -
-
-
-
Some ARIA parent roles must contain specific child roles to perform their intended accessibility functions. Learn more.
-
-
-
-
- -
- - - [role]s are contained by their required parent element - - -
- - - - -
-
-
-
Some ARIA child roles must be contained by specific parent roles to properly perform their intended accessibility functions. Learn more.
-
-
-
-
- -
- - - [role] values are valid - - -
- - - - -
-
-
-
ARIA roles must have valid values in order to perform their intended accessibility functions. Learn more.
-
-
-
-
- -
- - - ARIA toggle fields have accessible names - - -
- - - - -
-
-
-
When a toggle field doesn't have an accessible name, screen readers announce it with a generic name, making it unusable for users who rely on screen readers. Learn more.
-
-
-
-
- -
- - - ARIA tooltip elements have accessible names - - -
- - - - -
-
-
-
When an element doesn't have an accessible name, screen readers announce it with a generic name, making it unusable for users who rely on screen readers. Learn more.
-
-
-
-
- -
- - - ARIA treeitem elements have accessible names - - -
- - - - -
-
-
-
When an element doesn't have an accessible name, screen readers announce it with a generic name, making it unusable for users who rely on screen readers. Learn more.
-
-
-
-
- -
- - - <dl>'s contain only properly-ordered <dt> and <dd> groups, <script>, <template> or <div> elements. - - -
- - - - -
-
-
-
When definition lists are not properly marked up, screen readers may produce confusing or inaccurate output. Learn more.
-
-
-
-
- -
- - - Definition list items are wrapped in <dl> elements - - -
- - - - -
-
-
-
Definition list items (`<dt>` and `<dd>`) must be wrapped in a parent `<dl>` element to ensure that screen readers can properly announce them. Learn more.
-
-
-
-
- -
- - - ARIA IDs are unique - - -
- - - - -
-
-
-
The value of an ARIA ID must be unique to prevent other instances from being overlooked by assistive technologies. Learn more.
-
-
-
-
- -
- - - No form fields have multiple labels - - -
- - - - -
-
-
-
Form fields with multiple labels can be confusingly announced by assistive technologies like screen readers which use either the first, the last, or all of the labels. Learn more.
-
-
-
-
- -
- - - <frame> or <iframe> elements have a title - - -
- - - - -
-
-
-
Screen reader users rely on frame titles to describe the contents of frames. Learn more.
-
-
-
-
- -
- - - <input type="image"> elements have [alt] text - - -
- - - - -
-
-
-
When an image is being used as an `<input>` button, providing alternative text can help screen reader users understand the purpose of the button. Learn more.
-
-
-
-
- -
- - - Form elements have associated labels - - -
- - - - -
-
-
-
Labels ensure that form controls are announced properly by assistive technologies, like screen readers. Learn more.
-
-
-
-
- -
- - - The document does not use <meta http-equiv="refresh"> - - -
- - - - -
-
-
-
Users do not expect a page to refresh automatically, and doing so will move focus back to the top of the page. This may create a frustrating or confusing experience. Learn more.
-
-
-
-
- -
- - - <object> elements have [alt] text - - -
- - - - -
-
-
-
Screen readers cannot translate non-text content. Adding alt text to `<object>` elements helps screen readers convey meaning to users. Learn more.
-
-
-
-
- -
- - - No element has a [tabindex] value greater than 0 - - -
- - - - -
-
-
-
A value greater than 0 implies an explicit navigation ordering. Although technically valid, this often creates frustrating experiences for users who rely on assistive technologies. Learn more.
-
-
-
-
- -
- - - Cells in a <table> element that use the [headers] attribute refer to table cells within the same table. - - -
- - - - -
-
-
-
Screen readers have features to make navigating tables easier. Ensuring `<td>` cells using the `[headers]` attribute only refer to other cells in the same table may improve the experience for screen reader users. Learn more.
-
-
-
-
- -
- - - <th> elements and elements with [role="columnheader"/"rowheader"] have data cells they describe. - - -
- - - - -
-
-
-
Screen readers have features to make navigating tables easier. Ensuring table headers always refer to some set of cells may improve the experience for screen reader users. Learn more.
-
-
-
-
- -
- - - [lang] attributes have a valid value - - -
- - - - -
-
-
-
Specifying a valid BCP 47 language on elements helps ensure that text is pronounced correctly by a screen reader. Learn more.
-
-
-
-
- -
- - - <video> elements contain a <track> element with [kind="captions"] - - -
- - - - -
-
-
-
When a video provides a caption it is easier for deaf and hearing impaired users to access its information. Learn more.
-
-
-
- -
Trust and Safety
-
- -
- - - Ensure CSP is effective against XSS attacks - - -
- - - - -
-
-
-
A strong Content Security Policy (CSP) significantly reduces the risk of cross-site scripting (XSS) attacks. Learn more
-
-
Description
Directive
Severity
No CSP found in enforcement mode
High
-
- -
-
- Passed audits - (17) - - -
-
- - - - - -
-
-
-
- -
- - - Uses HTTPS - - -
- - - - -
-
-
-
All sites should be protected with HTTPS, even ones that don't handle sensitive data. This includes avoiding mixed content, where some resources are loaded over HTTP despite the initial request being served over HTTPS. HTTPS prevents intruders from tampering with or passively listening in on the communications between your app and your users, and is a prerequisite for HTTP/2 and many new web platform APIs. Learn more.
-
-
-
-
- -
- - - Links to cross-origin destinations are safe - - -
- - - - -
-
-
-
Add `rel="noopener"` or `rel="noreferrer"` to any external links to improve performance and prevent security vulnerabilities. Learn more.
-
-
-
-
- -
- - - Avoids requesting the geolocation permission on page load - - -
- - - - -
-
-
-
Users are mistrustful of or confused by sites that request their location without context. Consider tying the request to a user action instead. Learn more.
-
-
-
-
- -
- - - Avoids requesting the notification permission on page load - - -
- - - - -
-
-
-
Users are mistrustful of or confused by sites that request to send notifications without context. Consider tying the request to user gestures instead. Learn more.
-
-
-
-
- -
- - - Avoids front-end JavaScript libraries with known security vulnerabilities - - -
- - - - -
-
-
-
Some third-party scripts may contain known security vulnerabilities that are easily identified and exploited by attackers. Learn more.
-
-
-
-
- -
- - - Allows users to paste into password fields - - -
- - - - -
-
-
-
Preventing password pasting undermines good security policy. Learn more.
-
-
-
-
- -
- - - Displays images with correct aspect ratio - - -
- - - - -
-
-
-
Image display dimensions should match natural aspect ratio. Learn more.
-
-
-
-
- -
- - - Serves images with appropriate resolution - - -
- - - - -
-
-
-
Image natural dimensions should be proportional to the display size and the pixel ratio to maximize image clarity. Learn more.
-
-
-
-
- -
- - - Page has the HTML doctype - - -
- - - - -
-
-
-
Specifying a doctype prevents the browser from switching to quirks-mode. Learn more.
-
-
-
-
- -
- - - Properly defines charset - - -
- - - - -
-
-
-
A character encoding declaration is required. It can be done with a `<meta>` tag in the first 1024 bytes of the HTML or in the Content-Type HTTP response header. Learn more.
-
-
-
-
- -
- - - Avoids unload event listeners - - -
- - - - -
-
-
-
The `unload` event does not fire reliably and listening for it can prevent browser optimizations like the Back-Forward Cache. Consider using the `pagehide` or `visibilitychange` events instead. Learn more
-
-
-
-
- -
- - - Avoids Application Cache - - -
- - - - -
-
-
-
Application Cache is deprecated. Learn more.
-
-
-
-
- -
- - - Detected JavaScript libraries - - -
- - - - -
-
-
-
All front-end JavaScript libraries detected on the page. Learn more.
-
-
Name
Version
FuseJS
-
-
- -
- - - Avoids deprecated APIs - - -
- - - - -
-
-
-
Deprecated APIs will eventually be removed from the browser. Learn more.
-
-
-
-
- -
- - - No browser errors logged to the console - - -
- - - - -
-
-
-
Errors logged to the console indicate unresolved problems. They can come from network request failures and other browser concerns. Learn more
-
-
-
-
- -
- - - Page has valid source maps - - -
- - - - -
-
-
-
Source maps translate minified code to the original source code. This helps developers debug in production. In addition, Lighthouse is able to provide further insights. Consider deploying source maps to take advantage of these benefits. Learn more.
-
-
-
-
- -
- - - No issues in the Issues panel in Chrome Devtools - - -
- - - - -
-
-
-
Issues logged to the `Issues` panel in Chrome Devtools indicate unresolved problems. They can come from network request failures, insufficient security controls, and other browser concerns. Open up the Issues panel in Chrome DevTools for more details on each issue.
-
-
-
- -
-
- Not applicable - (1) - - -
-
- - - - - -
-
-
-
- -
- - - Fonts with font-display: optional are preloaded - - -
- - - - -
-
-
-
Preload `optional` fonts so first-time visitors may use them. Learn more
-
-
-
-
- -
These checks ensure that your page is optimized for search engine results ranking. There are additional factors Lighthouse does not check that may affect your search ranking. Learn more.
-
-
- -
-
- Additional items to manually check - (1) - - - Run these additional validators on your site to check additional SEO best practices.
-
- - - - - -
-
-
-
- -
- - - Structured data is valid - - -
- - - - -
-
-
-
Run the Structured Data Testing Tool and the Structured Data Linter to validate structured data. Learn more.
-
-
-
- -
-
- Passed audits - (13) - - -
-
- - - - - -
-
-
-
- -
- - - Has a <meta name="viewport"> tag with width or initial-scale - - -
- - - - -
-
-
-
Add a `<meta name="viewport">` tag to optimize your app for mobile screens. Learn more.
-
-
-
-
- -
- - - Document has a <title> element - - -
- - - - -
-
-
-
The title gives screen reader users an overview of the page, and search engine users rely on it heavily to determine if a page is relevant to their search. Learn more.
-
-
-
-
- -
- - - Document has a meta description - - -
- - - - -
-
-
-
Meta descriptions may be included in search results to concisely summarize page content. Learn more.
-
-
-
-
- -
- - - Page has successful HTTP status code - - -
- - - - -
-
-
-
Pages with unsuccessful HTTP status codes may not be indexed properly. Learn more.
-
-
-
-
- -
- - - Links are crawlable - - -
- - - - -
-
-
-
Search engines may use `href` attributes on links to crawl websites. Ensure that the `href` attribute of anchor elements links to an appropriate destination, so more pages of the site can be discovered. Learn More
-
-
-
-
- -
- - - Page isn’t blocked from indexing - - -
- - - - -
-
-
-
Search engines are unable to include your pages in search results if they don't have permission to crawl them. Learn more.
-
-
-
-
- -
- - - Image elements have [alt] attributes - - -
- - - - -
-
-
-
Informative elements should aim for short, descriptive alternate text. Decorative elements can be ignored with an empty alt attribute. Learn more.
-
-
-
-
- -
- - - Document has a valid hreflang - - -
- - - - -
-
-
-
hreflang links tell search engines what version of a page they should list in search results for a given language or region. Learn more.
-
-
-
-
- -
- - - Document has a valid rel=canonical - - -
- - - - -
-
-
-
Canonical links suggest which URL to show in search results. Learn more.
-
-
-
-
- -
- - - Document uses legible font sizes - 99.75% legible text - -
- - - - -
-
-
-
Font sizes less than 12px are too small to be legible and require mobile visitors to “pinch to zoom” in order to read. Strive to have >60% of page text ≥12px. Learn more.
-
- - -
- -
-
Source
Selector
% of Page Text
Font Size
.text-\[0\.6rem\]
0.25%
9.6px
Legible text
99.75%
≥ 12px
-
-
- -
- - - Document avoids plugins - - -
- - - - -
-
-
-
Search engines can't index plugin content, and many devices restrict plugins or don't support them. Learn more.
-
-
-
-
- -
- - - Tap targets are sized appropriately - 100% appropriately sized tap targets - -
- - - - -
-
-
-
Interactive elements like buttons and links should be large enough (48x48px), and have enough space around them, to be easy enough to tap without overlapping onto other elements. Learn more.
-
-
-
- -
-
- Not applicable - (1) - - -
-
- - - - - -
-
-
-
- -
- - - robots.txt is valid - - -
- - - - -
-
-
-
If your robots.txt file is malformed, crawlers may not be able to understand how you want your website to be crawled or indexed. Learn more.
-
-
-
- -
Installable
-
- -
- - - Web app manifest and service worker meet the installability requirements - - -
- - - - -
-
-
-
Service worker is the technology that enables your app to use many Progressive Web App features, such as offline, add to homescreen, and push notifications. With proper service worker and manifest implementations, browsers can proactively prompt users to add your app to their homescreen, which can lead to higher engagement. Learn more.
-
-
-
PWA Optimized
-
- -
- - - Does not register a service worker that controls page and start_url - - -
- - - - -
-
-
-
The service worker is the technology that enables your app to use many Progressive Web App features, such as offline, add to homescreen, and push notifications. Learn more.
-
-
-
-
- -
- - - Redirects HTTP traffic to HTTPS - - -
- - - - -
-
-
-
If you've already set up HTTPS, make sure that you redirect all HTTP traffic to HTTPS in order to enable secure web features for all your users. Learn more.
-
-
-
-
- -
- - - Configured for a custom splash screen - - -
- - - - -
-
-
-
A themed splash screen ensures a high-quality experience when users launch your app from their homescreens. Learn more.
-
-
-
-
- -
- - - Does not set a theme color for the address bar.
Failures: No `<meta name="theme-color">` tag found.
- -
-
- - - - -
-
-
-
The browser address bar can be themed to match your site. Learn more.
-
-
-
-
- -
- - - Content is sized correctly for the viewport - - -
- - - - -
-
-
-
If the width of your app's content doesn't match the width of the viewport, your app might not be optimized for mobile screens. Learn more.
-
-
-
-
- -
- - - Has a <meta name="viewport"> tag with width or initial-scale - - -
- - - - -
-
-
-
Add a `<meta name="viewport">` tag to optimize your app for mobile screens. Learn more.
-
-
-
-
- -
- - - Provides a valid apple-touch-icon - - -
- - - - -
-
-
-
For ideal appearance on iOS when users add a progressive web app to the home screen, define an `apple-touch-icon`. It must point to a non-transparent 192px (or 180px) square PNG. Learn More.
-
-
-
-
- -
- - - Manifest has a maskable icon - - -
- - - - -
-
-
-
A maskable icon ensures that the image fills the entire shape without being letterboxed when installing the app on a device. Learn more.
-
-
-
- -
-
- Additional items to manually check - (3) - - - These checks are required by the baseline PWA Checklist but are not automatically checked by Lighthouse. They do not affect your score but it's important that you verify them manually.
-
- - - - - -
-
-
-
- -
- - - Site works cross-browser - - -
- - - - -
-
-
-
To reach the most number of users, sites should work across every major browser. Learn more.
-
-
-
-
- -
- - - Page transitions don't feel like they block on the network - - -
- - - - -
-
-
-
Transitions should feel snappy as you tap around, even on a slow network. This experience is key to a user's perception of performance. Learn more.
-
-
-
-
- -
- - - Each page has a URL - - -
- - - - -
-
-
-
Ensure individual pages are deep linkable via URL and that URLs are unique for the purpose of shareability on social media. Learn more.
-
-
-
- -
- -
-
Runtime Settings
-
    - - -
  • - URL - http://localhost:8008/blowfish/samples/emoji/ -
  • - -
  • - Fetch Time - Jan 19, 2022, 7:17 PM GMT+11 -
  • - -
  • - Device - Emulated Moto G4 -
  • - -
  • - Network throttling - 150 ms TCP RTT, 1,638.4 Kbps throughput (Simulated) -
  • - -
  • - CPU throttling - 4x slowdown (Simulated) -
  • - -
  • - Channel - cli -
  • - -
  • - User agent (host) - Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/96.0.4664.110 Safari/537.36 -
  • - -
  • - User agent (network) - Mozilla/5.0 (Linux; Android 7.0; Moto G (4)) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4420.0 Mobile Safari/537.36 Chrome-Lighthouse -
  • - -
  • - CPU/Memory Power - 1949 -
  • - -
  • - Axe version - 4.2.1 -
  • -
-
- -
- - Generated by Lighthouse 8.0.0 | - File an issue -
-
- - -
- - - - - - - - \ No newline at end of file From ccc7fc8a98a4d38f4a8f8033b0da010cff7bf140 Mon Sep 17 00:00:00 2001 From: ZhenShuo Leo <98386542+ZhenShuo2021@users.noreply.github.com> Date: Fri, 22 Aug 2025 04:10:24 +0800 Subject: [PATCH 45/63] feat(tailwind): enable default colors --- assets/css/compiled/main.css | 32 ++++++++++++++++++++++++++++++++ tailwind.config.js | 1 + 2 files changed, 33 insertions(+) diff --git a/assets/css/compiled/main.css b/assets/css/compiled/main.css index 86428c35..ac0d14c6 100644 --- a/assets/css/compiled/main.css +++ b/assets/css/compiled/main.css @@ -1842,6 +1842,9 @@ body.zen-mode-enable { .bg-\[\#6d6d6d\] { background-color: #6d6d6d; } + .bg-black { + background-color: #000; + } .bg-neutral { background-color: rgba(var(--color-neutral), 1); } @@ -1887,6 +1890,9 @@ body.zen-mode-enable { .bg-transparent { background-color: transparent; } + .bg-white { + background-color: #fff; + } .bg-gradient-to-b { --tw-gradient-position: to bottom in oklab; background-image: linear-gradient(var(--tw-gradient-stops)); @@ -2258,6 +2264,9 @@ body.zen-mode-enable { .text-transparent { color: transparent; } + .text-white { + color: #fff; + } .capitalize { text-transform: capitalize; } @@ -2547,11 +2556,24 @@ body.zen-mode-enable { border-style: solid; } } + .group-data-\[twe-input-focused\]\:border-white { + &:is(:where(.group)[data-twe-input-focused] *) { + border-color: #fff; + } + } .group-data-\[twe-input-focused\]\:border-t-transparent { &:is(:where(.group)[data-twe-input-focused] *) { border-top-color: transparent; } } + .group-data-\[twe-input-focused\]\:shadow-white { + &:is(:where(.group)[data-twe-input-focused] *) { + --tw-shadow-color: #fff; + @supports (color: color-mix(in lab, red, red)) { + --tw-shadow-color: color-mix(in oklab, #fff var(--tw-shadow-alpha), transparent); + } + } + } .group-data-\[twe-input-state-active\]\:border-x-0 { &:is(:where(.group)[data-twe-input-state-active] *) { border-inline-style: var(--tw-border-style); @@ -3377,6 +3399,11 @@ body.zen-mode-enable { border-color: rgba(var(--color-primary-600), 1); } } + .dark\:border-white\/10 { + &:is(.dark *) { + border-color: color-mix(in oklab, #fff 10%, transparent); + } + } .dark\:prose-invert { &:is(.dark *) { --tw-prose-body: var(--tw-prose-invert-body); @@ -3551,6 +3578,11 @@ body.zen-mode-enable { color: rgba(var(--color-primary-400), 1); } } + .dark\:text-white { + &:is(.dark *) { + color: #fff; + } + } .dark\:opacity-60 { &:is(.dark *) { opacity: 60%; diff --git a/tailwind.config.js b/tailwind.config.js index 5a5d434f..b4ea8e42 100644 --- a/tailwind.config.js +++ b/tailwind.config.js @@ -16,6 +16,7 @@ module.exports = { "2xl": "1536px", }, colors: { + ...require('tailwindcss/colors'), transparent: "transparent", neutral: { DEFAULT: "rgba(var(--color-neutral), )", From d9151db6c00b2df43bd243efff1274817238b9f9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 27 Aug 2025 15:48:19 +0000 Subject: [PATCH 46/63] =?UTF-8?q?=F0=9F=91=B7=20Bump=20actions/upload-page?= =?UTF-8?q?s-artifact=20from=203=20to=204?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps [actions/upload-pages-artifact](https://github.com/actions/upload-pages-artifact) from 3 to 4. - [Release notes](https://github.com/actions/upload-pages-artifact/releases) - [Commits](https://github.com/actions/upload-pages-artifact/compare/v3...v4) --- updated-dependencies: - dependency-name: actions/upload-pages-artifact dependency-version: '4' dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/pages.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/pages.yml b/.github/workflows/pages.yml index 189ec4ba..43918754 100644 --- a/.github/workflows/pages.yml +++ b/.github/workflows/pages.yml @@ -51,7 +51,7 @@ jobs: run: | hugo --minify -s exampleSite --themesDir ../.. -d ../docs --baseURL https://nunocoracao.github.io/blowfish/ - name: Upload artifact - uses: actions/upload-pages-artifact@v3 + uses: actions/upload-pages-artifact@v4 with: path: ./docs From 55efc7f20835d6207a3f71c835990ac50059e24f Mon Sep 17 00:00:00 2001 From: aikhae Date: Sun, 31 Aug 2025 09:30:45 +0200 Subject: [PATCH 47/63] Adding myself to users :) --- exampleSite/content/users/users.json | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/exampleSite/content/users/users.json b/exampleSite/content/users/users.json index 4c5cb9c7..da759e2f 100644 --- a/exampleSite/content/users/users.json +++ b/exampleSite/content/users/users.json @@ -881,5 +881,14 @@ "tags": [ "Personal site" ] + }, + { + "title": "eike.in", + "url": "https://eike.in", + "source": "https://github.com/LarvenStein/eike.in", + "tags": [ + "Personal site", + "Portfolio" + ] } ] From 539a776d1cabaa55e847ab65106c30b428d7e2a8 Mon Sep 17 00:00:00 2001 From: ZhenShuo Leo <98386542+ZhenShuo2021@users.noreply.github.com> Date: Mon, 1 Sep 2025 02:19:30 +0800 Subject: [PATCH 48/63] chore(a11y): add title to i18n --- i18n/ar.yaml | 1 + i18n/bg.yaml | 1 + i18n/bn.yaml | 3 +++ i18n/ca.yaml | 1 + i18n/cs.yaml | 1 + i18n/de.yaml | 3 +++ i18n/en.yaml | 1 + i18n/eo.yaml | 1 + i18n/es.yaml | 3 +++ i18n/fa.yaml | 1 + i18n/fi.yaml | 1 + i18n/fr.yaml | 7 +++++++ i18n/gl.yaml | 1 + i18n/he.yaml | 1 + i18n/hr.yaml | 3 +++ i18n/hu.yaml | 1 + i18n/id.yaml | 1 + i18n/it.yaml | 7 +++++++ i18n/ja.yaml | 1 + i18n/ko.yaml | 1 + i18n/nl.yaml | 3 +++ i18n/pl.yaml | 1 + i18n/pt-BR.yaml | 1 + i18n/pt-PT.yaml | 7 +++++++ i18n/ro.yaml | 1 + i18n/ru.yaml | 1 + i18n/sv.yaml | 1 + i18n/th.yaml | 1 + i18n/tr.yaml | 3 +++ i18n/uk.yaml | 1 + i18n/vi.yaml | 1 + i18n/zh-CN.yaml | 1 + i18n/zh-TW.yaml | 1 + layouts/partials/header/basic.html | 2 +- 34 files changed, 64 insertions(+), 1 deletion(-) diff --git a/i18n/ar.yaml b/i18n/ar.yaml index 7bc969a0..89a04ec7 100644 --- a/i18n/ar.yaml +++ b/i18n/ar.yaml @@ -26,6 +26,7 @@ article: this_article: "هذه المقالة" a11y: + title: "إعدادات إمكانية الوصول" disable_blur: "تعطيل التمويه" disable_images: "تعطيل الصور" show_link_underline: "إظهار خط تحت الروابط" diff --git a/i18n/bg.yaml b/i18n/bg.yaml index 8f454f22..08a557b3 100644 --- a/i18n/bg.yaml +++ b/i18n/bg.yaml @@ -27,6 +27,7 @@ article: related_articles: "Подобни" a11y: + title: "Настройки за достъпност" disable_blur: "Изключване на замъгляването" disable_images: "Изключване на изображенията" show_link_underline: "Показване на подчертаване на връзките" diff --git a/i18n/bn.yaml b/i18n/bn.yaml index 770517b7..01c8e4b9 100644 --- a/i18n/bn.yaml +++ b/i18n/bn.yaml @@ -26,6 +26,9 @@ article: this_article: "This Article" related_articles: "Related" +a11y: + title: "অ্যাক্সেসিবিলিটি সেটিংস" + author: byline_title: "লেখক" diff --git a/i18n/ca.yaml b/i18n/ca.yaml index d5cc0a4b..612df9ea 100644 --- a/i18n/ca.yaml +++ b/i18n/ca.yaml @@ -30,6 +30,7 @@ article: disable: "Desactivar mode zen" a11y: + title: "Configuració d'accessibilitat" disable_blur: "Desactiva el desenfocament" disable_images: "Desactiva les imatges" show_link_underline: "Mostra el subratllat dels enllaços" diff --git a/i18n/cs.yaml b/i18n/cs.yaml index ddfe5891..cb49e1f2 100644 --- a/i18n/cs.yaml +++ b/i18n/cs.yaml @@ -27,6 +27,7 @@ article: related_articles: "Related" a11y: + title: "Nastavení přístupnosti" disable_blur: "Zakázat rozmazání" disable_images: "Zakázat obrázky" show_link_underline: "Zobrazit podtržení odkazů" diff --git a/i18n/de.yaml b/i18n/de.yaml index 64bb070a..37c9916c 100644 --- a/i18n/de.yaml +++ b/i18n/de.yaml @@ -20,6 +20,9 @@ article: this_article: "Dieser Artikel" related_articles: "Verwandte Artikel" +a11y: + title: "Barrierefreiheitseinstellungen" + author: byline_title: "Autor" diff --git a/i18n/en.yaml b/i18n/en.yaml index 0b87e0c0..4f789488 100644 --- a/i18n/en.yaml +++ b/i18n/en.yaml @@ -30,6 +30,7 @@ article: disable: "Disable zen mode" a11y: + title: "Accessibility settings" disable_blur: "Disable blur" disable_images: "Disable images" show_link_underline: "Show link underline" diff --git a/i18n/eo.yaml b/i18n/eo.yaml index 79ebd137..7bea66f8 100644 --- a/i18n/eo.yaml +++ b/i18n/eo.yaml @@ -30,6 +30,7 @@ article: disable: "Malŝalti zen-reĝimon" a11y: + title: "Alirebleco-agordoj" disable_blur: "Malŝalti malklarigon" disable_images: "Malŝalti bildojn" show_link_underline: "Montri substrekojn de ligiloj" diff --git a/i18n/es.yaml b/i18n/es.yaml index 862f82bb..81442a91 100644 --- a/i18n/es.yaml +++ b/i18n/es.yaml @@ -29,6 +29,9 @@ article: enable: "Activar modo zen" disable: "Desactivar modo zen" +a11y: + title: "Configuración de accesibilidad" + author: byline_title: "Autor" diff --git a/i18n/fa.yaml b/i18n/fa.yaml index ecf11782..31e92f47 100644 --- a/i18n/fa.yaml +++ b/i18n/fa.yaml @@ -30,6 +30,7 @@ article: disable: "غیر فعال کردن حالت تمام متن" a11y: + title: "تنظیمات دسترسی" disable_blur: "غیرفعال کردن تاری" disable_images: "غیرفعال کردن تصاویر" show_link_underline: "نمایش زیرخط لینک" diff --git a/i18n/fi.yaml b/i18n/fi.yaml index dd4b206a..cd2c839d 100644 --- a/i18n/fi.yaml +++ b/i18n/fi.yaml @@ -21,6 +21,7 @@ article: related_articles: "Related" a11y: + title: "Esteettömyysasetukset" disable_blur: "Poista sumennus käytöstä" disable_images: "Poista kuvat käytöstä" show_link_underline: "Näytä linkkien alleviivaus" diff --git a/i18n/fr.yaml b/i18n/fr.yaml index b780b09f..b8123097 100644 --- a/i18n/fr.yaml +++ b/i18n/fr.yaml @@ -23,6 +23,13 @@ article: enable: "Activer le mode zen" disable: "Désactiver le mode zen" +a11y: + title: "Paramètres d'accessibilité" + disable_blur: "Désactiver le flou" + disable_images: "Désactiver les images" + show_link_underline: "Afficher le soulignement des liens" + font_size: "Taille de la police" + author: byline_title: "Auteur" diff --git a/i18n/gl.yaml b/i18n/gl.yaml index e3b0281a..fc09389e 100644 --- a/i18n/gl.yaml +++ b/i18n/gl.yaml @@ -30,6 +30,7 @@ article: disable: "Desactivar modo zen" a11y: + title: "Axustes de accesibilidade" disable_blur: "Desactivar o desenfoque" disable_images: "Desactivar as imaxes" show_link_underline: "Mostrar subliñado da ligazón" diff --git a/i18n/he.yaml b/i18n/he.yaml index 368bd71d..c878b045 100644 --- a/i18n/he.yaml +++ b/i18n/he.yaml @@ -21,6 +21,7 @@ article: related_articles: "Related" a11y: + title: "הגדרות נגישות" disable_blur: "השבת טשטוש" disable_images: "השבת תמונות" show_link_underline: "הצג קו תחתון לקישורים" diff --git a/i18n/hr.yaml b/i18n/hr.yaml index 0f164e22..cb6ea4b8 100644 --- a/i18n/hr.yaml +++ b/i18n/hr.yaml @@ -26,6 +26,9 @@ article: this_article: "This Article" related_articles: "Related" +a11y: + title: "Postavke pristupačnosti" + author: byline_title: "Autor" diff --git a/i18n/hu.yaml b/i18n/hu.yaml index 40f81724..09d50c4e 100644 --- a/i18n/hu.yaml +++ b/i18n/hu.yaml @@ -21,6 +21,7 @@ article: related_articles: "Related" a11y: + title: "Akadálymentességi beállítások" disable_blur: "Elmosódás kikapcsolása" disable_images: "Képek kikapcsolása" show_link_underline: "Link aláhúzásának megjelenítése" diff --git a/i18n/id.yaml b/i18n/id.yaml index 33a0c8d3..cc68ba4e 100644 --- a/i18n/id.yaml +++ b/i18n/id.yaml @@ -27,6 +27,7 @@ article: related_articles: "Terkait" a11y: + title: "Pengaturan aksesibilitas" disable_blur: "Nonaktifkan blur" disable_images: "Nonaktifkan gambar" show_link_underline: "Tampilkan garis bawah tautan" diff --git a/i18n/it.yaml b/i18n/it.yaml index 1712a443..928d53ba 100644 --- a/i18n/it.yaml +++ b/i18n/it.yaml @@ -20,6 +20,13 @@ article: this_article: "This Article" related_articles: "Related" +a11y: + title: "Impostazioni di accessibilità" + disable_blur: "Disattiva sfocatura" + disable_images: "Disattiva immagini" + show_link_underline: "Mostra sottolineatura link" + font_size: "Dimensione del carattere" + author: byline_title: "Autore" diff --git a/i18n/ja.yaml b/i18n/ja.yaml index ca25ff42..de6ddcce 100644 --- a/i18n/ja.yaml +++ b/i18n/ja.yaml @@ -30,6 +30,7 @@ article: disable: "Zenモードを無効にする" a11y: + title: "アクセシビリティ設定" disable_blur: "ぼかしを無効にする" disable_images: "画像を無効にする" show_link_underline: "リンクの下線を表示する" diff --git a/i18n/ko.yaml b/i18n/ko.yaml index 7c12f6cd..c95aac6b 100644 --- a/i18n/ko.yaml +++ b/i18n/ko.yaml @@ -27,6 +27,7 @@ article: related_articles: "관련 글" a11y: + title: "접근성 설정" disable_blur: "흐림 효과 끄기" disable_images: "이미지 끄기" show_link_underline: "링크 밑줄 표시" diff --git a/i18n/nl.yaml b/i18n/nl.yaml index c8a3295d..afe7f27e 100644 --- a/i18n/nl.yaml +++ b/i18n/nl.yaml @@ -29,6 +29,9 @@ article: enable: "Zen-modus inschakelen" disable: "Zen-modus uitschakelen" +a11y: + title: "Toegankelijkheidsinstellingen" + author: byline_title: "Auteur" diff --git a/i18n/pl.yaml b/i18n/pl.yaml index 4fd77569..e2f14c7c 100644 --- a/i18n/pl.yaml +++ b/i18n/pl.yaml @@ -27,6 +27,7 @@ article: related_articles: "Related" a11y: + title: "Ustawienia dostępności" disable_blur: "Wyłącz rozmycie" disable_images: "Wyłącz obrazy" show_link_underline: "Pokaż podkreślenie linków" diff --git a/i18n/pt-BR.yaml b/i18n/pt-BR.yaml index 1a198bf7..a2bbbfe0 100644 --- a/i18n/pt-BR.yaml +++ b/i18n/pt-BR.yaml @@ -24,6 +24,7 @@ article: related_articles: "Relacionados" a11y: + title: "Configurações de acessibilidade" disable_blur: "Desativar desfoque" disable_images: "Desativar imagens" show_link_underline: "Mostrar sublinhado de links" diff --git a/i18n/pt-PT.yaml b/i18n/pt-PT.yaml index 24a3f8cf..468407ad 100644 --- a/i18n/pt-PT.yaml +++ b/i18n/pt-PT.yaml @@ -23,6 +23,13 @@ article: this_article: "Este artigo" related_articles: "Relacionados" +a11y: + title: "Definições de acessibilidade" + disable_blur: "Desativar desfoque" + disable_images: "Desativar imagens" + show_link_underline: "Mostrar sublinhado de links" + font_size: "Tamanho da fonte" + author: byline_title: "Autor" diff --git a/i18n/ro.yaml b/i18n/ro.yaml index d8e98182..1bf97dfb 100644 --- a/i18n/ro.yaml +++ b/i18n/ro.yaml @@ -21,6 +21,7 @@ article: related_articles: "Related" a11y: + title: "Setări de accesibilitate" disable_blur: "Dezactivează estomparea" disable_images: "Dezactivează imaginile" show_link_underline: "Afișează sublinierea linkurilor" diff --git a/i18n/ru.yaml b/i18n/ru.yaml index 9aca26c2..04f43e1d 100644 --- a/i18n/ru.yaml +++ b/i18n/ru.yaml @@ -27,6 +27,7 @@ article: related_articles: "Related" a11y: + title: "Настройки доступности" disable_blur: "Отключить размытие" disable_images: "Отключить изображения" show_link_underline: "Показать подчеркивание ссылок" diff --git a/i18n/sv.yaml b/i18n/sv.yaml index 139863f6..761d951f 100644 --- a/i18n/sv.yaml +++ b/i18n/sv.yaml @@ -21,6 +21,7 @@ article: related_articles: "Relaterade" a11y: + title: "Tillgänglighetsinställningar" disable_blur: "Inaktivera suddighet" disable_images: "Inaktivera bilder" show_link_underline: "Visa länkunderstrykning" diff --git a/i18n/th.yaml b/i18n/th.yaml index 6a48aa3b..db9265c7 100644 --- a/i18n/th.yaml +++ b/i18n/th.yaml @@ -30,6 +30,7 @@ article: disable: "ปิดโหมดเซน" a11y: + title: "การตั้งค่าการเข้าถึง" disable_blur: "ปิดการเบลอ" disable_images: "ปิดการแสดงรูปภาพ" show_link_underline: "แสดงเส้นใต้ลิงก์" diff --git a/i18n/tr.yaml b/i18n/tr.yaml index fa6f1de9..62a5e2bd 100644 --- a/i18n/tr.yaml +++ b/i18n/tr.yaml @@ -19,6 +19,9 @@ article: this_article: "This Article" related_articles: "Related" +a11y: + title: "Erişilebilirlik ayarları" + author: byline_title: "Yazar" diff --git a/i18n/uk.yaml b/i18n/uk.yaml index 8872b1bb..25338463 100644 --- a/i18n/uk.yaml +++ b/i18n/uk.yaml @@ -34,6 +34,7 @@ article: disable: "Disable zen mode" a11y: + title: "Налаштування доступності" disable_blur: "Вимкнути розмиття" disable_images: "Вимкнути зображення" show_link_underline: "Показати підкреслення посилань" diff --git a/i18n/vi.yaml b/i18n/vi.yaml index c65ec186..b08c2de5 100644 --- a/i18n/vi.yaml +++ b/i18n/vi.yaml @@ -30,6 +30,7 @@ article: disable: "Tắt zen mode" a11y: + title: "Cài đặt khả năng truy cập" disable_blur: "Tắt làm mờ" disable_images: "Tắt hình ảnh" show_link_underline: "Hiển thị gạch chân liên kết" diff --git a/i18n/zh-CN.yaml b/i18n/zh-CN.yaml index f059d138..3bf806eb 100644 --- a/i18n/zh-CN.yaml +++ b/i18n/zh-CN.yaml @@ -30,6 +30,7 @@ article: disable: "停用阅读模式" a11y: + title: "无障碍设定" disable_blur: "禁用模糊效果" disable_images: "禁用图片" show_link_underline: "显示链接下划线" diff --git a/i18n/zh-TW.yaml b/i18n/zh-TW.yaml index 99ff8559..ae19c246 100644 --- a/i18n/zh-TW.yaml +++ b/i18n/zh-TW.yaml @@ -30,6 +30,7 @@ article: disable: "停用閱讀模式" a11y: + title: "無障礙設定" disable_blur: "停用模糊效果" disable_images: "停用圖片" show_link_underline: "顯示連結底線" diff --git a/layouts/partials/header/basic.html b/layouts/partials/header/basic.html index 328d04e0..98b4dc0b 100644 --- a/layouts/partials/header/basic.html +++ b/layouts/partials/header/basic.html @@ -185,7 +185,7 @@

- Accessibility settings + {{ i18n "a11y.title" }}