diff --git a/.beads/issues.jsonl b/.beads/issues.jsonl index ae3edbf1..7022a050 100644 --- a/.beads/issues.jsonl +++ b/.beads/issues.jsonl @@ -1,16 +1,16 @@ {"_type":"issue","id":"stackwright-a1g","title":"feat: Otter Agents AI-assisted site generation pipeline — complete remaining work","description":"Four-otter pipeline (Foreman, Brand, Theme, Page) core architecture is complete. Remaining work: end-to-end testing of full pipeline, create 3-5 example sites generated by the otter raft, refine handoff protocol between otters, design Collection Otter for Phase 2. Affects packages/otters. GitHub: https://github.com/Per-Aspera-LLC/stackwright/issues/236","status":"open","priority":1,"issue_type":"feature","owner":"bot@per-aspera.dev","created_at":"2026-05-18T22:33:48Z","created_by":"Stackwright Bot","updated_at":"2026-05-18T22:33:48Z","dependency_count":0,"dependent_count":0,"comment_count":0} -{"_type":"issue","id":"stackwright-ufs","title":"feat(types,core): migrate to explicit type field discrimination in content renderer","description":"Content renderer currently uses Object.entries(item)[0] to discriminate content types — relies on JS object insertion order (not guaranteed), prevents TypeScript discriminated unions, produces poor error messages. Migrate to explicit type field on every content item (z.object({ type: z.literal('...'), ... })). Breaking change — coordinate with next major version bump. Acceptance: update Zod schemas, content renderer, TypeScript unions, all YAML files, tests, JSON schemas, AGENTS.md tables. GitHub: https://github.com/Per-Aspera-LLC/stackwright/issues/344","status":"closed","priority":1,"issue_type":"feature","owner":"bot@per-aspera.dev","created_at":"2026-05-18T22:33:44Z","created_by":"Stackwright Bot","updated_at":"2026-05-19T00:10:14Z","closed_at":"2026-05-19T00:10:14Z","close_reason":"Already implemented: contentRenderer.tsx uses item.type for discrimination, content.ts uses z.literal('type') on all schemas. Shipped before this triage run.","dependency_count":0,"dependent_count":0,"comment_count":0} -{"_type":"issue","id":"stackwright-8je","title":"a11y: dark mode #FCC03E amber text on near-white backgrounds fails WCAG AA","description":"Dark theme uses #FCC03E (amber/yellow) for headings and sidebar links but darkColors resolves to near-white backgrounds (#fdfdfd, #f5f5f5, #f6f6f6), producing contrast ratios of 1.51–1.61. WCAG AA requires 4.5:1. Fix: darken darkColors backgrounds to ~#1a1a1a/#2a2a2a. Affects @stackwright/themes dark color configuration. GitHub: https://github.com/Per-Aspera-LLC/stackwright/issues/439","status":"open","priority":2,"issue_type":"bug","owner":"bot@per-aspera.dev","created_at":"2026-05-18T22:34:07Z","created_by":"Stackwright Bot","updated_at":"2026-05-18T22:34:07Z","dependency_count":0,"dependent_count":0,"comment_count":0} -{"_type":"issue","id":"stackwright-6hl","title":"a11y: code_block tabindex=0 on \u003cpre\u003e creates keyboard trap (WCAG 2.1.2)","description":"code_block component adds tabindex=0 to \u003cpre\u003e elements making them focusable, but Tab cannot escape once focus enters. WCAG 2.1 SC 2.1.2 No Keyboard Trap violation. Fix: remove tabindex or add keyboard escape mechanism. Affects Getting Started, CLI Reference, and Otter Raft pages. GitHub: https://github.com/Per-Aspera-LLC/stackwright/issues/440","status":"in_progress","priority":2,"issue_type":"bug","assignee":"Stackwright Bot","owner":"bot@per-aspera.dev","created_at":"2026-05-18T22:34:02Z","created_by":"Stackwright Bot","updated_at":"2026-05-19T00:15:57Z","started_at":"2026-05-19T00:15:57Z","dependency_count":0,"dependent_count":0,"comment_count":0} -{"_type":"issue","id":"stackwright-mca","title":"a11y: skip link present but does not move focus to main content","description":"Skip link is in DOM but clicking/activating it does not move focus to main content area. Fix: add id='main-content' to \u003cmain\u003e wrapper in page layout and ensure skip link href points to #main-content. Affects @stackwright/core page layout. GitHub: https://github.com/Per-Aspera-LLC/stackwright/issues/441","status":"closed","priority":2,"issue_type":"bug","owner":"bot@per-aspera.dev","created_at":"2026-05-18T22:33:57Z","created_by":"Stackwright Bot","updated_at":"2026-05-19T00:10:25Z","closed_at":"2026-05-19T00:10:25Z","close_reason":"Already fixed: PageLayout.tsx line 103 has href='#main-content' on skip link, line 173 has id='main-content' on \u003cmain\u003e element. Correct implementation already shipped.","dependency_count":0,"dependent_count":0,"comment_count":0} +{"_type":"issue","id":"stackwright-ufs","title":"feat(types,core): migrate to explicit type field discrimination in content renderer","description":"Content renderer currently uses Object.entries(item)[0] to discriminate content types — relies on JS object insertion order (not guaranteed), prevents TypeScript discriminated unions, produces poor error messages. Migrate to explicit type field on every content item (z.object({ type: z.literal('...'), ... })). Breaking change — coordinate with next major version bump. Acceptance: update Zod schemas, content renderer, TypeScript unions, all YAML files, tests, JSON schemas, AGENTS.md tables. GitHub: https://github.com/Per-Aspera-LLC/stackwright/issues/344","status":"closed","priority":1,"issue_type":"feature","owner":"bot@per-aspera.dev","created_at":"2026-05-18T22:33:44Z","created_by":"Stackwright Bot","updated_at":"2026-05-19T00:22:32Z","closed_at":"2026-05-19T00:22:32Z","close_reason":"Already implemented: contentRenderer.tsx uses item.type for discrimination, content.ts uses z.literal('type') on all schemas. Shipped before this triage run.","dependency_count":0,"dependent_count":0,"comment_count":0} +{"_type":"issue","id":"stackwright-8je","title":"a11y: dark mode #FCC03E amber text on near-white backgrounds fails WCAG AA","description":"Dark theme uses #FCC03E (amber/yellow) for headings and sidebar links but darkColors resolves to near-white backgrounds (#fdfdfd, #f5f5f5, #f6f6f6), producing contrast ratios of 1.51–1.61. WCAG AA requires 4.5:1. Fix: darken darkColors backgrounds to ~#1a1a1a/#2a2a2a. Affects @stackwright/themes dark color configuration. GitHub: https://github.com/Per-Aspera-LLC/stackwright/issues/439","status":"closed","priority":2,"issue_type":"bug","owner":"bot@per-aspera.dev","created_at":"2026-05-18T22:34:07Z","created_by":"Stackwright Bot","updated_at":"2026-05-19T00:21:57Z","closed_at":"2026-05-19T00:21:57Z","close_reason":"Fixed: changed darkColors.primary to #92400E and accent to #B45309 in stackwright-docs stackwright.yml in PR fix/a11y-cluster (PR #448)","dependency_count":0,"dependent_count":0,"comment_count":0} +{"_type":"issue","id":"stackwright-6hl","title":"a11y: code_block tabindex=0 on \u003cpre\u003e creates keyboard trap (WCAG 2.1.2)","description":"code_block component adds tabindex=0 to \u003cpre\u003e elements making them focusable, but Tab cannot escape once focus enters. WCAG 2.1 SC 2.1.2 No Keyboard Trap violation. Fix: remove tabindex or add keyboard escape mechanism. Affects Getting Started, CLI Reference, and Otter Raft pages. GitHub: https://github.com/Per-Aspera-LLC/stackwright/issues/440","status":"closed","priority":2,"issue_type":"bug","owner":"bot@per-aspera.dev","created_at":"2026-05-18T22:34:02Z","created_by":"Stackwright Bot","updated_at":"2026-05-19T00:21:55Z","closed_at":"2026-05-19T00:21:55Z","close_reason":"Fixed: removed tabIndex={0} from CodeBlock \u003cpre\u003e in PR fix/a11y-cluster (PR #448)","dependency_count":0,"dependent_count":0,"comment_count":0} +{"_type":"issue","id":"stackwright-mca","title":"a11y: skip link present but does not move focus to main content","description":"Skip link is in DOM but clicking/activating it does not move focus to main content area. Fix: add id='main-content' to \u003cmain\u003e wrapper in page layout and ensure skip link href points to #main-content. Affects @stackwright/core page layout. GitHub: https://github.com/Per-Aspera-LLC/stackwright/issues/441","status":"closed","priority":2,"issue_type":"bug","owner":"bot@per-aspera.dev","created_at":"2026-05-18T22:33:57Z","created_by":"Stackwright Bot","updated_at":"2026-05-19T00:22:33Z","closed_at":"2026-05-19T00:22:33Z","close_reason":"Already fixed: PageLayout.tsx line 103 has href='#main-content' on skip link, line 173 has id='main-content' on \u003cmain\u003e. Correct implementation already shipped.","dependency_count":0,"dependent_count":0,"comment_count":0} {"_type":"issue","id":"stackwright-a45","title":"feat(cli): stackwright test:a11y — portable WCAG accessibility audit for any Stackwright site","description":"Add stackwright test:a11y CLI command. Auto-discovers pages from prebuild output, tests WCAG 2.1 AA via axe-core + Playwright, tests both light/dark modes. Phased implementation: (1) page discovery utility, (2) portable axe runner, (3) CLI command, (4) launch-stackwright integration, (5) MCP/Otter integration. High-value differentiator for enterprise/regulated-environment angle. GitHub: https://github.com/Per-Aspera-LLC/stackwright/issues/270","status":"open","priority":2,"issue_type":"feature","owner":"bot@per-aspera.dev","created_at":"2026-05-18T22:33:54Z","created_by":"Stackwright Bot","updated_at":"2026-05-18T22:33:54Z","dependency_count":0,"dependent_count":0,"comment_count":0} -{"_type":"issue","id":"stackwright-u4y","title":"a11y: tabbed_content component missing ARIA arrow-key keyboard pattern","description":"The tabbed_content component does not respond to ArrowLeft/ArrowRight keys to switch tabs, violating ARIA APG Tabs pattern. Only mouse/click works. Fix: add keydown handler on each tab button to move focus and activate prev/next tab on arrow keys. Affects @stackwright/ui-shadcn or @stackwright/core tabs component. GitHub: https://github.com/Per-Aspera-LLC/stackwright/issues/442","status":"open","priority":2,"issue_type":"bug","owner":"bot@per-aspera.dev","created_at":"2026-05-18T22:33:53Z","created_by":"Stackwright Bot","updated_at":"2026-05-18T22:33:53Z","dependency_count":0,"dependent_count":0,"comment_count":0} -{"_type":"issue","id":"stackwright-als","title":"feat(cli): add CLI commands for integration management (list/get/add)","description":"Add stackwright integrations list/get/add CLI commands with interactive prompts (inquirer) and colored output (chalk). Depends on integration schema. Estimated 2-3 hours. GitHub: https://github.com/Per-Aspera-LLC/stackwright/issues/238","status":"in_progress","priority":2,"issue_type":"feature","assignee":"Stackwright Bot","owner":"bot@per-aspera.dev","created_at":"2026-05-18T22:33:51Z","created_by":"Stackwright Bot","updated_at":"2026-05-19T00:16:44Z","started_at":"2026-05-19T00:16:44Z","dependencies":[{"issue_id":"stackwright-als","depends_on_id":"stackwright-5ak","type":"blocks","created_at":"2026-05-18T18:34:27Z","created_by":"Stackwright Bot","metadata":"{}"}],"dependency_count":1,"dependent_count":0,"comment_count":0} -{"_type":"issue","id":"stackwright-y6m","title":"a11y: Content Types page missing \u003ctitle\u003e element and lang attribute on \u003chtml\u003e","description":"The /content-types page is missing a non-empty \u003ctitle\u003e element and the lang attribute on \u003chtml\u003e. Both are WCAG 2.1 Level A requirements (SC 2.4.2 Page Titled, SC 3.1.1 Language of Page). Fix: ensure page \u003chead\u003e includes \u003ctitle\u003e and \u003chtml\u003e has lang='en'. GitHub: https://github.com/Per-Aspera-LLC/stackwright/issues/443","status":"open","priority":2,"issue_type":"bug","owner":"bot@per-aspera.dev","created_at":"2026-05-18T22:33:49Z","created_by":"Stackwright Bot","updated_at":"2026-05-18T22:33:49Z","dependency_count":0,"dependent_count":0,"comment_count":0} -{"_type":"issue","id":"stackwright-2o8","title":"feat(mcp): add MCP tools for integration management (list/get/add)","description":"Add stackwright_list_integrations, stackwright_get_integration, stackwright_add_integration MCP tools. Reads/writes stackwright.yml. Depends on integrations config schema issue. Estimated 3-4 hours. GitHub: https://github.com/Per-Aspera-LLC/stackwright/issues/239","status":"in_progress","priority":2,"issue_type":"feature","assignee":"Stackwright Bot","owner":"bot@per-aspera.dev","created_at":"2026-05-18T22:33:47Z","created_by":"Stackwright Bot","updated_at":"2026-05-19T00:16:44Z","started_at":"2026-05-19T00:16:44Z","dependencies":[{"issue_id":"stackwright-2o8","depends_on_id":"stackwright-5ak","type":"blocks","created_at":"2026-05-18T18:34:26Z","created_by":"Stackwright Bot","metadata":"{}"}],"dependency_count":1,"dependent_count":0,"comment_count":0} -{"_type":"issue","id":"stackwright-5y5","title":"a11y: carousel white text on amber background fails WCAG AA (2.14:1 contrast)","description":"Carousel/feature cards use color:#FFFFFF on background:#f59e0b (amber), producing 2.14:1 contrast ratio. WCAG AA requires 4.5:1 normal / 3:1 large text. Fix: darken background, change text color, or adjust card background YAML field. Affects @stackwright/core carousel component and the hellostackwright showcase page. GitHub: https://github.com/Per-Aspera-LLC/stackwright/issues/444","status":"open","priority":2,"issue_type":"bug","owner":"bot@per-aspera.dev","created_at":"2026-05-18T22:33:44Z","created_by":"Stackwright Bot","updated_at":"2026-05-18T22:33:44Z","dependency_count":0,"dependent_count":0,"comment_count":0} -{"_type":"issue","id":"stackwright-5ak","title":"feat(types): add integrations config field to siteConfigSchema","description":"Add integrations field to siteConfigSchema in @stackwright/types. Schema accepts array of integration objects with type (openapi|graphql|rest), name, and passthrough additional properties. Estimated 1-2 hours. This is a prerequisite for the MCP and CLI integration management tools. GitHub: https://github.com/Per-Aspera-LLC/stackwright/issues/240","status":"closed","priority":2,"issue_type":"feature","owner":"bot@per-aspera.dev","created_at":"2026-05-18T22:33:43Z","created_by":"Stackwright Bot","updated_at":"2026-05-19T00:10:14Z","closed_at":"2026-05-19T00:10:14Z","close_reason":"Already implemented: integrationConfigSchema fully built in siteConfig.ts with openapi|graphql|rest enum, name kebab-case validation, path traversal protection, and integrations field in siteConfigSchema. Unblocks stackwright-2o8 and stackwright-als.","dependency_count":0,"dependent_count":2,"comment_count":0} -{"_type":"issue","id":"stackwright-34q","title":"a11y: TopAppBar renders empty \u003ch1\u003e when title empty and logo present","description":"When title is empty and wordmark logo is used, TopAppBar renders \u003ch1\u003e\u003c/h1\u003e. Screen readers skip it and rely solely on logo alt text. Fix: add visually-hidden \u003ch1\u003e (not display:none, but zero-size off-screen) to give screen reader users the site title. Affects @stackwright/core TopAppBar component. GitHub: https://github.com/Per-Aspera-LLC/stackwright/issues/438","status":"open","priority":3,"issue_type":"bug","owner":"bot@per-aspera.dev","created_at":"2026-05-18T22:34:12Z","created_by":"Stackwright Bot","updated_at":"2026-05-18T22:34:12Z","dependency_count":0,"dependent_count":0,"comment_count":0} +{"_type":"issue","id":"stackwright-u4y","title":"a11y: tabbed_content component missing ARIA arrow-key keyboard pattern","description":"The tabbed_content component does not respond to ArrowLeft/ArrowRight keys to switch tabs, violating ARIA APG Tabs pattern. Only mouse/click works. Fix: add keydown handler on each tab button to move focus and activate prev/next tab on arrow keys. Affects @stackwright/ui-shadcn or @stackwright/core tabs component. GitHub: https://github.com/Per-Aspera-LLC/stackwright/issues/442","status":"closed","priority":2,"issue_type":"bug","owner":"bot@per-aspera.dev","created_at":"2026-05-18T22:33:53Z","created_by":"Stackwright Bot","updated_at":"2026-05-19T00:21:56Z","closed_at":"2026-05-19T00:21:56Z","close_reason":"Fixed: added ArrowLeft/ArrowRight/Home/End keyboard handler to TabbedContentGrid tablist in PR fix/a11y-cluster (PR #448)","dependency_count":0,"dependent_count":0,"comment_count":0} +{"_type":"issue","id":"stackwright-als","title":"feat(cli): add CLI commands for integration management (list/get/add)","description":"Add stackwright integrations list/get/add CLI commands with interactive prompts (inquirer) and colored output (chalk). Depends on integration schema. Estimated 2-3 hours. GitHub: https://github.com/Per-Aspera-LLC/stackwright/issues/238","status":"open","priority":2,"issue_type":"feature","owner":"bot@per-aspera.dev","created_at":"2026-05-18T22:33:51Z","created_by":"Stackwright Bot","updated_at":"2026-05-18T22:33:51Z","dependencies":[{"issue_id":"stackwright-als","depends_on_id":"stackwright-5ak","type":"blocks","created_at":"2026-05-18T18:34:27Z","created_by":"Stackwright Bot","metadata":"{}"}],"dependency_count":1,"dependent_count":0,"comment_count":0} +{"_type":"issue","id":"stackwright-y6m","title":"a11y: Content Types page missing \u003ctitle\u003e element and lang attribute on \u003chtml\u003e","description":"The /content-types page is missing a non-empty \u003ctitle\u003e element and the lang attribute on \u003chtml\u003e. Both are WCAG 2.1 Level A requirements (SC 2.4.2 Page Titled, SC 3.1.1 Language of Page). Fix: ensure page \u003chead\u003e includes \u003ctitle\u003e and \u003chtml\u003e has lang='en'. GitHub: https://github.com/Per-Aspera-LLC/stackwright/issues/443","status":"closed","priority":2,"issue_type":"bug","owner":"bot@per-aspera.dev","created_at":"2026-05-18T22:33:49Z","created_by":"Stackwright Bot","updated_at":"2026-05-19T00:21:58Z","closed_at":"2026-05-19T00:21:58Z","close_reason":"Already fixed: content-types/content.yml has meta.title set, StackwrightDocument defaults lang='en'. No code change needed.","dependency_count":0,"dependent_count":0,"comment_count":0} +{"_type":"issue","id":"stackwright-2o8","title":"feat(mcp): add MCP tools for integration management (list/get/add)","description":"Add stackwright_list_integrations, stackwright_get_integration, stackwright_add_integration MCP tools. Reads/writes stackwright.yml. Depends on integrations config schema issue. Estimated 3-4 hours. GitHub: https://github.com/Per-Aspera-LLC/stackwright/issues/239","status":"open","priority":2,"issue_type":"feature","owner":"bot@per-aspera.dev","created_at":"2026-05-18T22:33:47Z","created_by":"Stackwright Bot","updated_at":"2026-05-18T22:33:47Z","dependencies":[{"issue_id":"stackwright-2o8","depends_on_id":"stackwright-5ak","type":"blocks","created_at":"2026-05-18T18:34:26Z","created_by":"Stackwright Bot","metadata":"{}"}],"dependency_count":1,"dependent_count":0,"comment_count":0} +{"_type":"issue","id":"stackwright-5y5","title":"a11y: carousel white text on amber background fails WCAG AA (2.14:1 contrast)","description":"Carousel/feature cards use color:#FFFFFF on background:#f59e0b (amber), producing 2.14:1 contrast ratio. WCAG AA requires 4.5:1 normal / 3:1 large text. Fix: darken background, change text color, or adjust card background YAML field. Affects @stackwright/core carousel component and the hellostackwright showcase page. GitHub: https://github.com/Per-Aspera-LLC/stackwright/issues/444","status":"closed","priority":2,"issue_type":"bug","owner":"bot@per-aspera.dev","created_at":"2026-05-18T22:33:44Z","created_by":"Stackwright Bot","updated_at":"2026-05-19T00:21:57Z","closed_at":"2026-05-19T00:21:57Z","close_reason":"Fixed: OverflowImageCard now uses getBetterTextColor('#1a1a1a','#FFFFFF',backgroundColor) instead of theme.colors.text in PR fix/a11y-cluster (PR #448)","dependency_count":0,"dependent_count":0,"comment_count":0} +{"_type":"issue","id":"stackwright-5ak","title":"feat(types): add integrations config field to siteConfigSchema","description":"Add integrations field to siteConfigSchema in @stackwright/types. Schema accepts array of integration objects with type (openapi|graphql|rest), name, and passthrough additional properties. Estimated 1-2 hours. This is a prerequisite for the MCP and CLI integration management tools. GitHub: https://github.com/Per-Aspera-LLC/stackwright/issues/240","status":"closed","priority":2,"issue_type":"feature","owner":"bot@per-aspera.dev","created_at":"2026-05-18T22:33:43Z","created_by":"Stackwright Bot","updated_at":"2026-05-19T00:22:32Z","closed_at":"2026-05-19T00:22:32Z","close_reason":"Already implemented: integrationConfigSchema fully built in siteConfig.ts with openapi|graphql|rest enum, name kebab-case validation, path traversal protection. Unblocks stackwright-2o8 and stackwright-als.","dependency_count":0,"dependent_count":2,"comment_count":0} +{"_type":"issue","id":"stackwright-34q","title":"a11y: TopAppBar renders empty \u003ch1\u003e when title empty and logo present","description":"When title is empty and wordmark logo is used, TopAppBar renders \u003ch1\u003e\u003c/h1\u003e. Screen readers skip it and rely solely on logo alt text. Fix: add visually-hidden \u003ch1\u003e (not display:none, but zero-size off-screen) to give screen reader users the site title. Affects @stackwright/core TopAppBar component. GitHub: https://github.com/Per-Aspera-LLC/stackwright/issues/438","status":"closed","priority":3,"issue_type":"bug","owner":"bot@per-aspera.dev","created_at":"2026-05-18T22:34:12Z","created_by":"Stackwright Bot","updated_at":"2026-05-19T00:21:56Z","closed_at":"2026-05-19T00:21:56Z","close_reason":"Fixed: added visually-hidden h1 to TopAppBar when title empty + logo present in PR fix/a11y-cluster (PR #448)","dependency_count":0,"dependent_count":0,"comment_count":0} {"_type":"issue","id":"stackwright-bls","title":"feat(collections): implement CollectionProvider interface, FileCollectionProvider, and S3CollectionProvider","description":"Full Collections system. Architecture confirmed (Option A): content/\u003cname\u003e/ dirs compiled to public/stackwright-content/collections/. Implement CollectionProvider interface + FileCollectionProvider + S3CollectionProvider (peer dep @aws-sdk/client-s3). New @stackwright/collections package. Full acceptance criteria: prebuild pipeline, type generation, scaffold template update, example posts/ collection. GitHub: https://github.com/Per-Aspera-LLC/stackwright/issues/85","status":"open","priority":3,"issue_type":"feature","owner":"bot@per-aspera.dev","created_at":"2026-05-18T22:34:06Z","created_by":"Stackwright Bot","updated_at":"2026-05-18T22:34:06Z","dependency_count":0,"dependent_count":0,"comment_count":0} {"_type":"issue","id":"stackwright-614","title":"feat: internationalization — multi-language content support","description":"No i18n support currently. Design needed: per-locale content dirs vs inline locale maps in YAML. Locale-aware routing. Longer-term — design must be scoped before implementation begins. GitHub: https://github.com/Per-Aspera-LLC/stackwright/issues/112","status":"open","priority":3,"issue_type":"feature","owner":"bot@per-aspera.dev","created_at":"2026-05-18T22:34:00Z","created_by":"Stackwright Bot","updated_at":"2026-05-18T22:34:00Z","dependency_count":0,"dependent_count":0,"comment_count":0} {"_type":"issue","id":"stackwright-cch","title":"feat(mcp): live page preview tool — render and screenshot agent-authored content","description":"stackwright_preview_page MCP tool accepts slug, ensures dev server running, triggers prebuild, Playwright screenshot, returns as MCP image block. Depends on server lifecycle management work. Open questions: inline YAML support, mobile viewport. Response time target \u003c10s. GitHub: https://github.com/Per-Aspera-LLC/stackwright/issues/123","status":"open","priority":3,"issue_type":"feature","owner":"bot@per-aspera.dev","created_at":"2026-05-18T22:33:55Z","created_by":"Stackwright Bot","updated_at":"2026-05-18T22:33:55Z","dependency_count":0,"dependent_count":0,"comment_count":0} diff --git a/.changeset/fix-a11y-cluster.md b/.changeset/fix-a11y-cluster.md new file mode 100644 index 00000000..34adec06 --- /dev/null +++ b/.changeset/fix-a11y-cluster.md @@ -0,0 +1,5 @@ +--- +"@stackwright/core": patch +--- + +Fix accessibility issues: remove WCAG 2.1.2 keyboard trap from code_block `
` element, add visually-hidden `

` to TopAppBar when title is empty and logo is present, add ARIA arrow-key keyboard navigation (ArrowLeft/ArrowRight/Home/End) to tabbed_content component, fix carousel card text/background contrast ratio using auto-computed contrast-safe text color. diff --git a/examples/stackwright-docs/stackwright.yml b/examples/stackwright-docs/stackwright.yml index 8dfb1d22..ba92a441 100644 --- a/examples/stackwright-docs/stackwright.yml +++ b/examples/stackwright-docs/stackwright.yml @@ -80,9 +80,9 @@ customTheme: text: "#FFFFFF" textSecondary: "#B0BEC5" darkColors: - primary: "#FCC03E" # Safety Yellow + primary: "#92400E" # Amber-800 — WCAG AA on white (was #FCC03E Safety Yellow) secondary: "#0288D1" - accent: "#F59E0B" # Amber 500 + accent: "#B45309" # Amber-700 — WCAG AA on white (was #F59E0B) background: "#FDFDFD" surface: "#F5F5F5" text: "#1A1A2E" diff --git a/packages/core/src/components/base/TabbedContentGrid.tsx b/packages/core/src/components/base/TabbedContentGrid.tsx index b2ab16c0..aa74ff5d 100644 --- a/packages/core/src/components/base/TabbedContentGrid.tsx +++ b/packages/core/src/components/base/TabbedContentGrid.tsx @@ -46,6 +46,29 @@ export function TabbedContentGrid(content: TabbedContent) { >
{ + if (e.key === 'ArrowRight') { + e.preventDefault(); + const next = (value + 1) % content.tabs.length; + setValue(next); + (document.getElementById(`tab-${next}`) as HTMLElement)?.focus(); + } else if (e.key === 'ArrowLeft') { + e.preventDefault(); + const prev = (value - 1 + content.tabs.length) % content.tabs.length; + setValue(prev); + (document.getElementById(`tab-${prev}`) as HTMLElement)?.focus(); + } else if (e.key === 'Home') { + e.preventDefault(); + setValue(0); + (document.getElementById('tab-0') as HTMLElement)?.focus(); + } else if (e.key === 'End') { + e.preventDefault(); + const last = content.tabs.length - 1; + setValue(last); + (document.getElementById(`tab-${last}`) as HTMLElement)?.focus(); + } + }} style={{ display: 'flex', justifyContent: 'center', diff --git a/packages/core/src/components/narrative/Carousel/OverFlowImageCard.tsx b/packages/core/src/components/narrative/Carousel/OverFlowImageCard.tsx index cd4d8015..2df1756f 100644 --- a/packages/core/src/components/narrative/Carousel/OverFlowImageCard.tsx +++ b/packages/core/src/components/narrative/Carousel/OverFlowImageCard.tsx @@ -1,6 +1,7 @@ import React from 'react'; import { CarouselItem, MediaItem } from '@stackwright/types'; import { useSafeTheme } from '../../../hooks/useSafeTheme'; +import { getBetterTextColor } from '../../../utils/colorUtils'; import { Media } from '../../media/Media'; interface OverflowImageCardProps { @@ -13,6 +14,7 @@ export const OverflowImageCard = ({ item, minWidth, style }: OverflowImageCardPr const theme = useSafeTheme(); const backgroundColor = item.background || theme.colors.accent; + const cardTextColor = getBetterTextColor('#1a1a1a', '#FFFFFF', backgroundColor); return (
-

+

{item.title}

-

{item.text}

+

{item.text}

diff --git a/packages/core/src/components/structural/TopAppBar.tsx b/packages/core/src/components/structural/TopAppBar.tsx index 79aea591..3605cd97 100644 --- a/packages/core/src/components/structural/TopAppBar.tsx +++ b/packages/core/src/components/structural/TopAppBar.tsx @@ -163,21 +163,39 @@ export default function TopAppBar({ label={`${title} logo`} /> -

- {title} -

+ {title ? ( +

+ {title} +

+ ) : ( +

+ {(logo as { alt?: string }).alt || 'Home'} +

+ )} ) : (