pre-onboarding content, a11y & Core-Web-Vitals polish #74

Sammanfogat
supernaut sammanfogade 3 incheckningar från feat/65-polish in i main 2026-07-20 21:03:38 +00:00
Ägare

Pre-onboarding content, accessibility and Core-Web-Vitals polish (grab-bag). Closes #65.

Note: L1 (CSP object-src / CSP header) is intentionally out of scope here — it is handled in the separate #64 PR. astro.config.mjs was not touched.

Done

Core Web Vitals

  • M7 — Subset the four Montserrat woff2 to latin+latin-ext (+ needed punctuation, incl. the → arrow) with pyftsubset. Sizes dropped ~71%: regular 86 900 → 25 088, italic 90 432 → 25 768, medium 87 040 → 25 440, medium-italic 90 892 → 25 924 bytes. Verified the subsets still contain Swedish glyphs (å/ä/ö/é), dashes, quotes, €, ellipsis and the arrow.
  • M8 — <Font preload /> now preloads only the two upright weights (regular + medium) via the preload={[…]} array API, not the italics. Verified the built home page emits exactly two <link rel="preload" as="font" crossorigin> tags (down from four).
  • M9 — Added a slot="fallback" skeleton for the server:defer UserMenu, reserving the same row height/width to avoid header CLS.
  • M13 — Restored metric-override anchors in font-fallback.scss: local("Helvetica Neue"), local("Liberation Sans"), local("Roboto") (verified in the built CSS).

Accessibility

  • M10 — Sign-up errors are now focus-managed (a small bundled script moves focus to the error notice, which is tabindex="-1") and fields get aria-invalid + aria-describedby pointing at the message (username/email on input/taken, country on ineligible, captcha group on captcha).
  • M11 — Username field has a visible format hint plus a title (associated via aria-describedby).
  • M12 — Captcha instruction is now programmatically associated: wrapped in role="group" + aria-labelledby.
  • L6 — Breadcrumb current page is a <span aria-current="page">, not a self-link.
  • L7 — FAQ filter uses aria-labelledby instead of a duplicated aria-label + visible label.
  • L8 — Header vs footer "Bitborg" home links now have distinct aria-labels ("gå till startsidan" / "tillbaka till startsidan").
  • L9 — Skip link reveals on :focus (not only :focus-visible).

Content / i18n

  • M3 — EN pricing standardised on "SEK" (ui.ts org price + the add-on table in en/pricing.astro).
  • M4 — EN legal ## headings in en/terms.md + en/privacy.md lowered to sentence case (H1 titles kept).
  • M5 — Swedish "hosta/hosting" anglicism replaced with driftas/värd across sv/docs.md, sv/terms.md (git-värdtjänst), faq/sv/renovate-cost.md, guides/sv/renovate.md, sv/privacy.md, pricing.astro and ui.ts.
  • M6 — SV footer tagline → "Ägt, drivet och driftat i Sverige."
  • L5 — Removed the orphaned nav.cookiePolicy i18n key (no /cookies page; unused).
  • L10 — Fixed the SV Bahnhof link in sv/privacy.md to the canonical URL (was pointing at /en).
  • L11 — Spelled out "configuration" (docs.exampleConfig).
  • L12 — Added Open Graph + Twitter meta to base.astro, driven by page props with sitewide defaults (title, description → tagline fallback, type, url, site_name, locale sv_SE/en_GB, image → apple-touch-icon; no dedicated social image exists yet).

Low-risk

  • L4 — Containerfile corepack pin aligned to pnpm@11.15.0 (matches packageManager / Volta).

Deferred

  • L1 — CSP object-src / CSP header: handled in the #64 PR (not touched here).

Verification

  • pnpm check — 0 errors (only pre-existing warnings/hints in untouched files).
  • pnpm lint — clean (eslint + stylelint).
  • pnpm build — succeeds; copies the 4 subset fonts.
  • vitest run — 55/55 tests pass (via the pre-push hook).
  • web-language-check detector — no candidates across 34 content files.
  • Rendered-markup spot checks on the running standalone server: OG/Twitter tags, two font preloads, UserMenu fallback skeleton, distinct logo aria-labels, breadcrumb <span>, FAQ aria-labelledby, and the full set of sign-up aria-invalid/aria-describedby/role=group/hint/title attributes.
Pre-onboarding content, accessibility and Core-Web-Vitals polish (grab-bag). Closes #65. Note: **L1** (CSP `object-src` / CSP header) is intentionally out of scope here — it is handled in the separate #64 PR. `astro.config.mjs` was not touched. ## Done ### Core Web Vitals - **M7** — Subset the four Montserrat woff2 to latin+latin-ext (+ needed punctuation, incl. the `→` arrow) with `pyftsubset`. Sizes dropped ~71%: regular 86 900 → 25 088, italic 90 432 → 25 768, medium 87 040 → 25 440, medium-italic 90 892 → 25 924 bytes. Verified the subsets still contain Swedish glyphs (å/ä/ö/é), dashes, quotes, €, ellipsis and the arrow. - **M8** — `<Font preload />` now preloads only the two upright weights (regular + medium) via the `preload={[…]}` array API, not the italics. Verified the built home page emits exactly two `<link rel="preload" as="font" crossorigin>` tags (down from four). - **M9** — Added a `slot="fallback"` skeleton for the `server:defer` `UserMenu`, reserving the same row height/width to avoid header CLS. - **M13** — Restored metric-override anchors in `font-fallback.scss`: `local("Helvetica Neue"), local("Liberation Sans"), local("Roboto")` (verified in the built CSS). ### Accessibility - **M10** — Sign-up errors are now focus-managed (a small bundled script moves focus to the error notice, which is `tabindex="-1"`) and fields get `aria-invalid` + `aria-describedby` pointing at the message (username/email on input/taken, country on ineligible, captcha group on captcha). - **M11** — Username field has a visible format hint plus a `title` (associated via `aria-describedby`). - **M12** — Captcha instruction is now programmatically associated: wrapped in `role="group"` + `aria-labelledby`. - **L6** — Breadcrumb current page is a `<span aria-current="page">`, not a self-link. - **L7** — FAQ filter uses `aria-labelledby` instead of a duplicated `aria-label` + visible label. - **L8** — Header vs footer "Bitborg" home links now have distinct aria-labels ("gå till startsidan" / "tillbaka till startsidan"). - **L9** — Skip link reveals on `:focus` (not only `:focus-visible`). ### Content / i18n - **M3** — EN pricing standardised on "SEK" (`ui.ts` org price + the add-on table in `en/pricing.astro`). - **M4** — EN legal `##` headings in `en/terms.md` + `en/privacy.md` lowered to sentence case (H1 titles kept). - **M5** — Swedish "hosta/hosting" anglicism replaced with driftas/värd across `sv/docs.md`, `sv/terms.md` (git-värdtjänst), `faq/sv/renovate-cost.md`, `guides/sv/renovate.md`, `sv/privacy.md`, `pricing.astro` and `ui.ts`. - **M6** — SV footer tagline → "Ägt, drivet och driftat i Sverige." - **L5** — Removed the orphaned `nav.cookiePolicy` i18n key (no `/cookies` page; unused). - **L10** — Fixed the SV Bahnhof link in `sv/privacy.md` to the canonical URL (was pointing at `/en`). - **L11** — Spelled out "configuration" (`docs.exampleConfig`). - **L12** — Added Open Graph + Twitter meta to `base.astro`, driven by page props with sitewide defaults (title, description → tagline fallback, type, url, site_name, locale sv_SE/en_GB, image → apple-touch-icon; no dedicated social image exists yet). ### Low-risk - **L4** — `Containerfile` corepack pin aligned to `pnpm@11.15.0` (matches `packageManager` / Volta). ## Deferred - **L1** — CSP `object-src` / CSP header: handled in the #64 PR (not touched here). ## Verification - `pnpm check` — 0 errors (only pre-existing warnings/hints in untouched files). - `pnpm lint` — clean (eslint + stylelint). - `pnpm build` — succeeds; copies the 4 subset fonts. - `vitest run` — 55/55 tests pass (via the pre-push hook). - web-language-check detector — no candidates across 34 content files. - Rendered-markup spot checks on the running standalone server: OG/Twitter tags, two font preloads, UserMenu fallback skeleton, distinct logo aria-labels, breadcrumb `<span>`, FAQ `aria-labelledby`, and the full set of sign-up `aria-invalid`/`aria-describedby`/`role=group`/hint/`title` attributes.
supernaut lade till 2 incheckningar 2026-07-20 15:16:50 +00:00
- en pricing uses SEK consistently (M3); en legal headings to sentence case (M4)
- sv copy uses driftas/värd, not the hosta/hosting anglicism (M5)
- sv footer tagline: ägt, drivet och driftat i Sverige (M6)
- remove orphaned nav.cookiePolicy key (L5); spell out configuration (L11)
- fix sv Bahnhof link to canonical URL (L10)
- add logo home + username-hint i18n keys for the a11y work
- Containerfile corepack pnpm pinned to 11.15.0 to match packageManager (L4)
feat: core web vitals and accessibility polish
Alla kontroller lyckades
ci / ci (pull_request) Successful in 56s
50e0fd5e2a
- subset Montserrat woff2 to latin+latin-ext (~88KB -> ~25KB each) (M7)
- preload only the regular+medium upright weights, not italics (M8)
- skeleton fallback for the deferred UserMenu to avoid header CLS (M9)
- metric-override anchors in the font fallback (M13)
- signup: focus + announce errors, per-field aria-invalid/describedby (M10),
  visible username format hint + title (M11), captcha role=group label (M12)
- breadcrumb current page is a span, not a self-link (L6)
- faq filter uses aria-labelledby, not a duplicated label (L7)
- distinct aria-labels for header vs footer home links (L8)
- skip link reveals on :focus, not only :focus-visible (L9)
- open graph / twitter meta with sitewide defaults (L12)
supernaut tvångsskickade feat/65-polish från 50e0fd5e2a
Alla kontroller lyckades
ci / ci (pull_request) Successful in 56s
till 5181117e09
En del kontroller misslyckades
ci / ci (pull_request) Failing after 51s
2026-07-20 19:34:25 +00:00
Jämför
supernaut lade till 1 incheckning 2026-07-20 20:35:50 +00:00
style: apply linting
Alla kontroller lyckades
ci / ci (pull_request) Successful in 57s
a24f543eab
supernaut sammanfogade incheckning a8f6df6a43 till main 2026-07-20 21:03:38 +00:00
supernaut tog bort grenen feat/65-polish 2026-07-20 21:03:38 +00:00
supernaut refererade denna ändringsförfrågan från en incheckning 2026-07-20 21:03:40 +00:00
supernaut lade till detta till projektet Bitborg Web 2026-07-21 06:49:02 +00:00
Upphovsperson
Ägare

Deployed + verified live 2026-07-21. The build was blocked for a while by two infra issues (both now fixed): the fail2ban caddy-auth jail banning the CI runner on the registry /v2 auth handshake (bitborg-infra#127 → fixed by the /v2 ignoreregex + unbanning the stale runner-egress ban), and a Containerfile cache-mount footgun (#77). After those, run 174 (build-and-push) succeeded and the host pulled the new image.

Verified on prod: /signup returns 200 with the new CSP — object-src 'none' and style-src-elem 'self' 'nonce-…' (the per-request captcha-style nonce), replacing the old brittle hash-scraping. Fonts/a11y from #74 are in the shipped image.

Deployed + verified live 2026-07-21. The build was blocked for a while by two infra issues (both now fixed): the fail2ban `caddy-auth` jail banning the CI runner on the registry `/v2` auth handshake (bitborg-infra#127 → fixed by the `/v2` ignoreregex + unbanning the stale runner-egress ban), and a Containerfile cache-mount footgun (#77). After those, run 174 (build-and-push) succeeded and the host pulled the new image. Verified on prod: `/signup` returns 200 with the new CSP — `object-src 'none'` and `style-src-elem 'self' 'nonce-…'` (the per-request captcha-style nonce), replacing the old brittle hash-scraping. Fonts/a11y from #74 are in the shipped image.
supernaut tog bort detta från projektet Bitborg Web 2026-07-30 22:40:41 +00:00
supernaut refererade denna ändringsförfrågan från en incheckning 2026-08-03 09:41:50 +00:00
Logga in för att delta i denna konversation.
Inga granskare
Ingen milstolpe
Inget projekt
Inga tilldelade
1 deltagare
Notiser
Förfallodatum
Förfallodatumet är ogiltigt eller utanför gränserna. Använd formatet "åååå-mm-dd".

Inget förfallodatum satt.

Beroenden

Inga beroenden satta

Referens
bitborg/bitborg-web!74
Ingen beskrivning angiven.