test: vitest unit + playwright e2e suites; fix a11y, contrast, no-JS reveal
- vitest: dictionary parity, slug-map bijection, content-schema validation, JSON-LD (23) - playwright: both locales, language-switch mapping (incl. no-JS), CV downloads, form happy-path + honeypot, axe a11y on 5 templates x 2 themes (23) - fix: raise ink-faint + light accent to meet WCAG AA 4.5:1 (axe-verified) - fix: gate reveal animations behind html.js so content is visible without JS (progressive enhancement - was hidden at opacity 0); scan reduced-motion path - fix: validate contact form before the anti-bot time-trap (no false success) - chore: ESLint node globals, typed diagram props, resvg fontFiles, prettier pass Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -25,14 +25,14 @@ const currentLabel = locale === 'en' ? d.cv.english : d.cv.norsk;
|
||||
<a
|
||||
href={current.path}
|
||||
download
|
||||
class="inline-flex items-center rounded-l-sm bg-accent px-4 py-2 text-small font-semibold text-accent-ink transition-[filter] duration-[--dur-quick] hover:brightness-105"
|
||||
class="bg-accent text-small text-accent-ink inline-flex items-center rounded-l-sm px-4 py-2 font-semibold transition-[filter] duration-[--dur-quick] hover:brightness-105"
|
||||
>
|
||||
{d.cv.download}
|
||||
{!compact && <span class="ml-2 font-mono text-mono-label opacity-70">EN/NO</span>}
|
||||
{!compact && <span class="text-mono-label ml-2 font-mono opacity-70">EN/NO</span>}
|
||||
</a>
|
||||
<details class="cv-menu">
|
||||
<summary
|
||||
class="flex cursor-pointer list-none items-center rounded-r-sm border-l border-accent-ink/20 bg-accent px-2 text-accent-ink transition-[filter] duration-[--dur-quick] hover:brightness-105"
|
||||
class="border-accent-ink/20 bg-accent text-accent-ink flex cursor-pointer list-none items-center rounded-r-sm border-l px-2 transition-[filter] duration-[--dur-quick] hover:brightness-105"
|
||||
aria-label={d.cv.download}
|
||||
>
|
||||
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" aria-hidden="true">
|
||||
@@ -40,22 +40,30 @@ const currentLabel = locale === 'en' ? d.cv.english : d.cv.norsk;
|
||||
</svg>
|
||||
</summary>
|
||||
<div
|
||||
class="absolute right-0 top-[calc(100%+8px)] z-30 w-64 overflow-hidden rounded-md border border-line-strong bg-surface-2 shadow-[var(--shadow-overlay)]"
|
||||
class="border-line-strong bg-surface-2 absolute top-[calc(100%+8px)] right-0 z-30 w-64 overflow-hidden rounded-md border shadow-[var(--shadow-overlay)]"
|
||||
>
|
||||
<a
|
||||
href={current.path}
|
||||
download
|
||||
class="flex items-center justify-between gap-2 px-4 py-3 text-small text-ink hover:bg-surface-1"
|
||||
class="text-small text-ink hover:bg-surface-1 flex items-center justify-between gap-2 px-4 py-3"
|
||||
>
|
||||
<span><span class="mr-2 font-mono text-mono-label text-accent">{d.lang[locale]}</span>{currentLabel}</span>
|
||||
<span
|
||||
><span class="text-mono-label text-accent mr-2 font-mono">{d.lang[locale]}</span>{
|
||||
currentLabel
|
||||
}</span
|
||||
>
|
||||
<span class="mono-meta">{interpolate(d.cv.fileMeta, { size: current.sizeKb })}</span>
|
||||
</a>
|
||||
<a
|
||||
href={other.path}
|
||||
download
|
||||
class="flex items-center justify-between gap-2 border-t border-line px-4 py-3 text-small text-ink-muted hover:bg-surface-1 hover:text-ink"
|
||||
class="border-line text-small text-ink-muted hover:bg-surface-1 hover:text-ink flex items-center justify-between gap-2 border-t px-4 py-3"
|
||||
>
|
||||
<span><span class="mr-2 font-mono text-mono-label">{locale === 'en' ? 'NO' : 'EN'}</span>{otherLabel}</span>
|
||||
<span
|
||||
><span class="text-mono-label mr-2 font-mono">{locale === 'en' ? 'NO' : 'EN'}</span>{
|
||||
otherLabel
|
||||
}</span
|
||||
>
|
||||
<span class="mono-meta">{interpolate(d.cv.fileMeta, { size: other.sizeKb })}</span>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user