fix(website): address accessibility audit findings

This commit is contained in:
KoalaDev
2026-07-15 04:23:14 +02:00
parent b577f06988
commit a4bbddf3a4
8 changed files with 80 additions and 19 deletions
+37
View File
@@ -10,6 +10,12 @@ const app = fs.readFileSync(path.join(repoRoot, 'website', 'app.js'), 'utf8');
const langInit = fs.readFileSync(path.join(repoRoot, 'website', 'lang-init.js'), 'utf8');
const demoCss = fs.readFileSync(path.join(repoRoot, 'website', 'styles', 'demo.css'), 'utf8');
const landingPrimaryCss = fs.readFileSync(path.join(repoRoot, 'website', 'styles', 'landing-primary.css'), 'utf8');
const legalCss = fs.readFileSync(path.join(repoRoot, 'website', 'styles', 'legal.css'), 'utf8');
const joinPage = fs.readFileSync(path.join(repoRoot, 'website', 'join.html'), 'utf8');
const imprintPage = fs.readFileSync(path.join(repoRoot, 'website', 'imprint.html'), 'utf8');
const germanImprintPage = fs.readFileSync(path.join(repoRoot, 'website', 'impressum-de.html'), 'utf8');
const alternativesIndex = fs.readFileSync(path.join(repoRoot, 'website', 'alternatives', 'index.html'), 'utf8');
const alternativesCss = fs.readFileSync(path.join(repoRoot, 'website', 'styles', 'alternatives.css'), 'utf8');
const mockupStart = template.indexOf('<div class="extension-mockup">');
const mockupEnd = template.indexOf('<div class="demo-invite-fly"', mockupStart);
@@ -82,8 +88,39 @@ if (!/color:\s*oklch\(/.test(stepNumberLightRule)
throw new Error('Getting Started step numbers must use solid readable text in light mode');
}
if (!/class="footer-disclaimer"/.test(joinPage) || /footer-disclaimer[^>]*opacity:/.test(joinPage)) {
throw new Error('Join-page disclaimer must use the contrast-safe footer-disclaimer colors without opacity');
}
if (!/\.legal-inline-link\s*\{[^}]*text-decoration:\s*underline/s.test(legalCss)) {
throw new Error('Legal prose links must use a non-color underline cue');
}
for (const [name, page] of [['imprint.html', imprintPage], ['impressum-de.html', germanImprintPage]]) {
if ((page.match(/class="legal-inline-link"/g) || []).length !== 3) {
throw new Error(`${name} must mark all three prose links as legal-inline-link`);
}
if ((page.match(/class="legal-inline-label"/g) || []).length !== 2 || /opacity:\s*0\.6/.test(page)) {
throw new Error(`${name} contact labels must use full-opacity theme text`);
}
}
if (/<h3\b/.test(alternativesIndex)
|| (alternativesIndex.match(/<h2\b/g) || []).length !== 6
|| (alternativesIndex.match(/<h2[^>]+color:\s*var\(--text\)/g) || []).length !== 6) {
throw new Error('Alternatives overview cards must use h2 headings directly below the page h1');
}
if (!/html\.theme-light \.guide-card\s*\{[^}]*background-color:\s*var\(--card-surface\)\s*!important/s.test(alternativesCss)) {
throw new Error('Alternatives cards must define a readable light-theme surface');
}
const reducedMotionRule = demoCss.match(/@media \(prefers-reduced-motion: reduce\)\s*\{\s*\.step-illustration-3 \.film-mtn-scroll,\s*\.step-illustration-3 \.film-mid-scroll,\s*\.step-illustration-3 \.film-fore-scroll\s*\{([^}]*)\}/)?.[1] || '';
if (!/animation:\s*none\s*!important/.test(reducedMotionRule)) {
throw new Error('Getting Started film layers must stop when reduced motion is requested');
}
console.log('Extension mockup theme-sensitive text uses theme-aware colors');
console.log('Landing CSS is render-blocking, single-request, and cascade-stable');
console.log('Foreground film birds use complete, always-on wing and glide animations');
console.log('All Getting Started mockups define explicit light-theme surfaces');
console.log('Getting Started step numbers stay readable in light mode');
console.log('Accessibility regressions stay fixed across legal, alternatives, and reduced-motion views');
+6 -6
View File
@@ -232,7 +232,7 @@
<!-- Teleparty Card -->
<a href="{{ASSET_PATH}}{{LANG_PREFIX}}alternatives/teleparty" class="guide-card" style="text-decoration: none; background: rgba(255, 255, 255, 0.03); border: 1px solid var(--glass-border); border-radius: 12px; padding: 1.5rem; display: flex; flex-direction: column; justify-content: space-between;">
<div>
<h3 style="margin-top: 0; margin-bottom: 0.75rem; color: #fff; font-size: 1.25rem;">{{ALT_TELEPARTY_TITLE}}</h3>
<h2 style="margin-top: 0; margin-bottom: 0.75rem; color: var(--text); font-size: 1.25rem;">{{ALT_TELEPARTY_TITLE}}</h2>
<p style="font-size: 0.9rem; line-height: 1.5; color: var(--text-muted); margin-bottom: 1.5rem;">{{ALT_TELEPARTY_META_DESC}}</p>
</div>
<div class="btn btn-primary" style="align-self: flex-start; padding: 0.5rem 1rem; font-size: 0.85rem; border-radius: 6px;">
@@ -243,7 +243,7 @@
<!-- Watch2Gether Card -->
<a href="{{ASSET_PATH}}{{LANG_PREFIX}}alternatives/watch2gether" class="guide-card" style="text-decoration: none; background: rgba(255, 255, 255, 0.03); border: 1px solid var(--glass-border); border-radius: 12px; padding: 1.5rem; display: flex; flex-direction: column; justify-content: space-between;">
<div>
<h3 style="margin-top: 0; margin-bottom: 0.75rem; color: #fff; font-size: 1.25rem;">{{ALT_W2G_TITLE}}</h3>
<h2 style="margin-top: 0; margin-bottom: 0.75rem; color: var(--text); font-size: 1.25rem;">{{ALT_W2G_TITLE}}</h2>
<p style="font-size: 0.9rem; line-height: 1.5; color: var(--text-muted); margin-bottom: 1.5rem;">{{ALT_W2G_META_DESC}}</p>
</div>
<div class="btn btn-primary" style="align-self: flex-start; padding: 0.5rem 1rem; font-size: 0.85rem; border-radius: 6px;">
@@ -254,7 +254,7 @@
<!-- Scener Card -->
<a href="{{ASSET_PATH}}{{LANG_PREFIX}}alternatives/scener" class="guide-card" style="text-decoration: none; background: rgba(255, 255, 255, 0.03); border: 1px solid var(--glass-border); border-radius: 12px; padding: 1.5rem; display: flex; flex-direction: column; justify-content: space-between;">
<div>
<h3 style="margin-top: 0; margin-bottom: 0.75rem; color: #fff; font-size: 1.25rem;">{{ALT_SCENER_TITLE}}</h3>
<h2 style="margin-top: 0; margin-bottom: 0.75rem; color: var(--text); font-size: 1.25rem;">{{ALT_SCENER_TITLE}}</h2>
<p style="font-size: 0.9rem; line-height: 1.5; color: var(--text-muted); margin-bottom: 1.5rem;">{{ALT_SCENER_META_DESC}}</p>
</div>
<div class="btn btn-primary" style="align-self: flex-start; padding: 0.5rem 1rem; font-size: 0.85rem; border-radius: 6px;">
@@ -265,7 +265,7 @@
<!-- Kosmi Card -->
<a href="{{ASSET_PATH}}{{LANG_PREFIX}}alternatives/kosmi" class="guide-card" style="text-decoration: none; background: rgba(255, 255, 255, 0.03); border: 1px solid var(--glass-border); border-radius: 12px; padding: 1.5rem; display: flex; flex-direction: column; justify-content: space-between;">
<div>
<h3 style="margin-top: 0; margin-bottom: 0.75rem; color: #fff; font-size: 1.25rem;">{{ALT_KOSMI_TITLE}}</h3>
<h2 style="margin-top: 0; margin-bottom: 0.75rem; color: var(--text); font-size: 1.25rem;">{{ALT_KOSMI_TITLE}}</h2>
<p style="font-size: 0.9rem; line-height: 1.5; color: var(--text-muted); margin-bottom: 1.5rem;">{{ALT_KOSMI_META_DESC}}</p>
</div>
<div class="btn btn-primary" style="align-self: flex-start; padding: 0.5rem 1rem; font-size: 0.85rem; border-radius: 6px;">
@@ -276,7 +276,7 @@
<!-- TwoSeven Card -->
<a href="{{ASSET_PATH}}{{LANG_PREFIX}}alternatives/twoseven" class="guide-card" style="text-decoration: none; background: rgba(255, 255, 255, 0.03); border: 1px solid var(--glass-border); border-radius: 12px; padding: 1.5rem; display: flex; flex-direction: column; justify-content: space-between;">
<div>
<h3 style="margin-top: 0; margin-bottom: 0.75rem; color: #fff; font-size: 1.25rem;">{{ALT_TWOSEVEN_TITLE}}</h3>
<h2 style="margin-top: 0; margin-bottom: 0.75rem; color: var(--text); font-size: 1.25rem;">{{ALT_TWOSEVEN_TITLE}}</h2>
<p style="font-size: 0.9rem; line-height: 1.5; color: var(--text-muted); margin-bottom: 1.5rem;">{{ALT_TWOSEVEN_META_DESC}}</p>
</div>
<div class="btn btn-primary" style="align-self: flex-start; padding: 0.5rem 1rem; font-size: 0.85rem; border-radius: 6px;">
@@ -287,7 +287,7 @@
<!-- Screen Sharing Card -->
<a href="{{ASSET_PATH}}{{LANG_PREFIX}}alternatives/screen-sharing" class="guide-card" style="text-decoration: none; background: rgba(255, 255, 255, 0.03); border: 1px solid var(--glass-border); border-radius: 12px; padding: 1.5rem; display: flex; flex-direction: column; justify-content: space-between;">
<div>
<h3 style="margin-top: 0; margin-bottom: 0.75rem; color: #fff; font-size: 1.25rem;">{{ALT_SCREEN_TITLE}}</h3>
<h2 style="margin-top: 0; margin-bottom: 0.75rem; color: var(--text); font-size: 1.25rem;">{{ALT_SCREEN_TITLE}}</h2>
<p style="font-size: 0.9rem; line-height: 1.5; color: var(--text-muted); margin-bottom: 1.5rem;">{{ALT_SCREEN_META_DESC}}</p>
</div>
<div class="btn btn-primary" style="align-self: flex-start; padding: 0.5rem 1rem; font-size: 0.85rem; border-radius: 6px;">
+5 -5
View File
@@ -175,12 +175,12 @@
E-Mail: <span class="email-reveal" data-user="koalasync" data-domain="koalastuff.net" style="color: var(--accent); cursor: pointer; text-decoration: underline;">[E-Mail anzeigen]</span>
</p>
<p style="margin-top: 0.75rem;">
<span style="opacity: 0.6;">🔒 Private Nachricht:</span>
<a href="https://mastodon.social/@koalastuff" rel="me noopener" target="_blank" style="color: var(--accent); text-decoration: none;">@koalastuff auf Mastodon</a>
<span class="legal-inline-label">🔒 Private Nachricht:</span>
<a href="https://mastodon.social/@koalastuff" rel="me noopener" target="_blank" class="legal-inline-link">@koalastuff auf Mastodon</a>
</p>
<p style="margin-top: 0.5rem;">
<span style="opacity: 0.6;">🐛 Fehlerberichte und Sicherheitsmeldungen:</span>
<a href="https://github.com/Shik3i/KoalaSync/issues" target="_blank" rel="noopener" style="color: var(--accent); text-decoration: none;">GitHub Issues</a>
<span class="legal-inline-label">🐛 Fehlerberichte und Sicherheitsmeldungen:</span>
<a href="https://github.com/Shik3i/KoalaSync/issues" target="_blank" rel="noopener" class="legal-inline-link">GitHub Issues</a>
</p>
</section>
@@ -190,7 +190,7 @@
KoalaSync ist eine kostenlose und quelloffene Browser-Erweiterung. Der Quellcode ist auf GitHub unter der MIT-Lizenz verfügbar.
</p>
<p style="margin-top: 0.5rem;">
Informationen zum Datenschutz, einschließlich Hosting, Access Logs, Relay-Verhalten und Betroffenenrechten, finden Sie in der <a href="datenschutz" style="color: var(--accent); text-decoration: none;">Datenschutzerklärung</a>.
Informationen zum Datenschutz, einschließlich Hosting, Access Logs, Relay-Verhalten und Betroffenenrechten, finden Sie in der <a href="datenschutz" class="legal-inline-link">Datenschutzerklärung</a>.
</p>
</section>
+5 -5
View File
@@ -175,12 +175,12 @@
E-Mail: <span class="email-reveal" data-user="koalasync" data-domain="koalastuff.net" style="color: var(--accent); cursor: pointer; text-decoration: underline;">[Show Email]</span>
</p>
<p style="margin-top: 0.75rem;">
<span style="opacity: 0.6;">🔒 Private message:</span>
<a href="https://mastodon.social/@koalastuff" rel="me noopener" target="_blank" style="color: var(--accent); text-decoration: none;">@koalastuff on Mastodon</a>
<span class="legal-inline-label">🔒 Private message:</span>
<a href="https://mastodon.social/@koalastuff" rel="me noopener" target="_blank" class="legal-inline-link">@koalastuff on Mastodon</a>
</p>
<p style="margin-top: 0.5rem;">
<span style="opacity: 0.6;">🐛 Bug reports and security concerns:</span>
<a href="https://github.com/Shik3i/KoalaSync/issues" target="_blank" rel="noopener" style="color: var(--accent); text-decoration: none;">GitHub Issues</a>
<span class="legal-inline-label">🐛 Bug reports and security concerns:</span>
<a href="https://github.com/Shik3i/KoalaSync/issues" target="_blank" rel="noopener" class="legal-inline-link">GitHub Issues</a>
</p>
</section>
@@ -190,7 +190,7 @@
KoalaSync is a free and open-source browser extension. The source code is available on GitHub under the MIT License.
</p>
<p style="margin-top: 0.5rem;">
For privacy-related information, including hosting, access logs, relay behavior, and data subject rights, please see the <a href="privacy" style="color: var(--accent); text-decoration: none;">Privacy Policy</a>.
For privacy-related information, including hosting, access logs, relay behavior, and data subject rights, please see the <a href="privacy" class="legal-inline-link">Privacy Policy</a>.
</p>
</section>
+1 -1
View File
@@ -184,7 +184,7 @@
<div class="container">
<p>&copy; 2026 KoalaSync. <span lang="en">Open source under the MIT License.</span><span lang="de">Open Source unter der MIT-Lizenz.</span></p>
<p style="font-size: 0.8rem; margin-top: 0.5rem;"><span lang="en">No relay logs. No tracking. Website access logs are deleted after 7 days.</span><span lang="de">Keine Relay-Logs. Kein Tracking. Website-Access-Logs werden nach 7 Tagen gelöscht.</span></p>
<p style="font-size: 0.72rem; margin-top: 1.2rem; color: var(--text-muted); opacity: 0.65; max-width: 650px; margin-left: auto; margin-right: auto; line-height: 1.5;"><span lang="en">KoalaSync is not affiliated with, endorsed by, or associated with Netflix, Disney+, Amazon, YouTube, Twitch, or any other streaming platform. All trademarks are property of their respective owners.</span><span lang="de">KoalaSync ist nicht mit Netflix, Disney+, Amazon, YouTube, Twitch oder anderen Streaming-Plattformen verbunden, wird von diesen nicht unterstützt oder steht in keiner Beziehung zu diesen. Alle Markenrechte liegen bei ihren jeweiligen Inhabern.</span></p>
<p class="footer-disclaimer" style="margin-top: 1.2rem;"><span lang="en">KoalaSync is not affiliated with, endorsed by, or associated with Netflix, Disney+, Amazon, YouTube, Twitch, or any other streaming platform. All trademarks are property of their respective owners.</span><span lang="de">KoalaSync ist nicht mit Netflix, Disney+, Amazon, YouTube, Twitch oder anderen Streaming-Plattformen verbunden, wird von diesen nicht unterstützt oder steht in keiner Beziehung zu diesen. Alle Markenrechte liegen bei ihren jeweiligen Inhabern.</span></p>
<div style="margin-top: 1.5rem; font-size: 0.8rem; display: flex; justify-content: center; align-items: center; gap: 1.5rem; flex-wrap: wrap;">
<a href="imprint" lang="en" style="color: var(--text-muted); text-decoration: none;">Legal Notice</a>
<a href="de/impressum" lang="de" style="color: var(--text-muted); text-decoration: none;">Impressum</a>
+8 -1
View File
@@ -8,6 +8,14 @@
border-color: rgba(255, 255, 255, 0.22) !important;
box-shadow: 0 12px 24px -10px rgba(0, 0, 0, 0.4);
}
html.theme-light .guide-card {
background-color: var(--card-surface) !important;
border-color: var(--card-border) !important;
}
html.theme-light .guide-card:hover {
background-color: var(--card) !important;
border-color: oklch(0.52 0.12 150 / 0.35) !important;
}
.guide-card .btn-primary {
transition: background-color 0.2s ease, transform 0.1s ease;
}
@@ -20,4 +28,3 @@
gap: 1.25rem !important;
}
}
+8
View File
@@ -1162,6 +1162,14 @@ html.theme-light .hero-demo-scene .demo-video::after {
animation: scrollFore 3s linear infinite !important;
}
@media (prefers-reduced-motion: reduce) {
.step-illustration-3 .film-mtn-scroll,
.step-illustration-3 .film-mid-scroll,
.step-illustration-3 .film-fore-scroll {
animation: none !important;
}
}
@keyframes scrollBack {
0% { transform: translateX(0); }
100% { transform: translateX(-160px); }
+10 -1
View File
@@ -31,6 +31,16 @@
font-size: 0.95rem;
}
.legal-inline-link {
color: var(--accent);
text-decoration: underline;
text-underline-offset: 0.15em;
}
.legal-inline-label {
color: var(--text-muted);
}
/* Reset global section padding for legal sections specifically */
.legal-card section {
padding: 0 !important;
@@ -173,4 +183,3 @@
gap: 0.4rem;
}
}