Skip to content

fix(accessibility): preserve forced-colors state cues - #151

Draft
seonghobae wants to merge 14 commits into
mainfrom
fix/forced-colors-accessibility
Draft

fix(accessibility): preserve forced-colors state cues#151
seonghobae wants to merge 14 commits into
mainfrom
fix/forced-colors-accessibility

Conversation

@seonghobae

@seonghobae seonghobae commented Aug 10, 2026

Copy link
Copy Markdown
Contributor

Closes #150.

Purpose

Implement the bounded forced-colors/high-contrast accessibility slice without changing Inkspan's normal light/dark theme behavior or host authority boundaries.

Current exact authority

Fresh state after the latest protected-main and review changes:

  • protected shipped truth: main@057762e003fadad418c38ee748bc3e5b20e711eb;
  • exact PR head: a517183774745040b1a4012e570040d3f92e2580 on fix/forced-colors-accessibility;
  • lifecycle: Draft; GitHub currently reports not mergeable;
  • live ancestry: diverged, 11 ahead / 127 behind, merge base 3b38ead2d00f44eb578d0689087b9293b3dabe1e;
  • net product delta versus live protected main remains src/editorFocusStyles.test.ts, src/forcedColorsStyles.test.ts, src/styles.css, and tests/browser/specs/forced-colors.browser.spec.ts;
  • formal submitted reviews: one Devin COMMENTED, 0 APPROVED;
  • unresolved inline review threads: 2, both on tests/browser/specs/forced-colors.browser.spec.ts.

Protected main remains the shipped implementation authority. This snapshot is decision-time evidence only and must be refetched before any later lifecycle action.

Test-first lineage

  • RED d89bd41dabca47a00d486e847eed0d3df8b5456b proved missing forced-colors system-state mappings.
  • RED bcd993a1d521d3f44fe07eaeaa5acda10dce3d6b proved split forced-colors blocks could be overridden by later equal-specificity screen rules.
  • Source/test corrections consolidated one final screen forced-colors layer and tightened test scope without weakening normal theme behavior.
  • Predecessor workflow/review evidence does not transfer after branch or protected-base movement.

Implemented boundary

Inside one final screen @media (forced-colors: active) layer, Inkspan uses CSS system colors to preserve editor/container boundaries, toolbar/collaboration chrome, grouping, keyboard focus, active and disabled states, authored links, code/pre/table boundaries, and collaboration cursors. Disabled controls do not rely on opacity alone. Normal light/dark theme declarations remain unchanged outside that media query and Inkspan does not opt out of user-agent forced-color adjustment.

This slice adds no persistence, transport, credentials, model use, authorization, tenancy, network, provider, room, or durable-audit authority.

Verified false-green browser evidence defect

The current #151 branch contains tests/browser/specs/forced-colors.browser.spec.ts, but its inherited tests/browser/playwright.config.ts selects only /(?:clipboard|print)\.browser\.spec\.ts/u. Therefore the forced-colors spec is structurally undiscoverable by Chromium, Firefox, and WebKit on this exact branch. Existing CI/security success must not be represented as execution evidence for that browser spec.

The browser harness/spec/config boundary already has an active dedicated Inkspan writer: Draft #380. Its current exact head b89b38e22c10d01d2462b22361e4bc20b08f9ba0 owns tests/browser/playwright.config.ts and currently uses /\.browser\.spec\.ts$/u, which would discover every committed *.browser.spec.ts, including this forced-colors spec after the branches are reconciled. #151 must not race that config writer by duplicating the selector repair locally.

The second unresolved review observation notes that programmatic .focus() may not exercise :focus-visible reliably. Treat that as an unproven/flakiness risk until the spec is actually discovered and executed; do not resolve the thread or claim GREEN from file-presence/static evidence.

Current evidence boundary

Repository workflows recorded for this exact branch head are terminal-success technical evidence only for what those workflows actually executed:

  • CI 32064781481: completed / success;
  • Security Scan 32064781699: completed / success;
  • SAST Semgrep 32064781459: completed / success.

They were generated before the current protected-base divergence was reconciled and do not prove the eventual integrated/live-base result. In particular, they do not prove the undiscovered forced-colors browser spec. No qualifying formal approval is bound to this head. Required central workflows and exact integrated-base browser/Office/coverage/package evidence must be regenerated and inspected after reconciliation. Pending, queued, skipped, cancelled, absent, neutral, failed, stale, predecessor, status-only, model-only, wrong-checkout, undiscovered-test, or synthetic-merge-only evidence is non-passing.

Dependency order / source ownership

This remains the earliest active owner for the forced-colors production/source boundary. However, former Draft #362 was merged into protected main as 057762e003fadad418c38ee748bc3e5b20e711eb despite previously overlapping src/styles.css and src/editorFocusStyles.test.ts. #151 must therefore reconcile its production delta against that protected-main truth before further source work or review advancement; the old instruction that #362 would consume #151 is superseded by the actual protected merge.

For browser configuration specifically, Draft #380 is the existing dedicated writer. Reconcile through that owner rather than editing tests/browser/playwright.config.ts from #151.

Release issue #118 remains a downstream protected-release acceptance boundary; it does not authorize bypassing this PR's own dependency, browser-execution, review, or merge gates.

Integration boundary

Before any further lifecycle transition:

  1. refetch exact fix(accessibility): preserve forced-colors state cues #151 head, protected main/live base, ancestry/mergeability, changed paths/active writers, rulesets/protection, formal reviews/threads, and every required repository/central workflow/job;
  2. reconcile the 127-commit protected-main divergence and the already-merged fix(a11y): repair editor contrast and keyboard focus #362 overlap non-destructively through a supported branch-update/merge mechanism; never force-push or destructively rebase;
  3. preserve test(input): add multilingual browser input baseline #380 as the single writer for tests/browser/playwright.config.ts; only after its selector contract is inherited/reconciled may fix(accessibility): preserve forced-colors state cues #151 rely on forced-colors browser discovery;
  4. produce realistic RED -> narrow fix -> GREEN for any still-valid forced-colors browser finding, including keyboard-driven :focus-visible behavior if the risk reproduces;
  5. regenerate exact-current-head/live-base CI, security/SAST, coverage, packed-package, browser/forced-colors, Office, and applicable central workflow evidence and verify actual checkout SHAs/test discovery;
  6. obtain all qualifying independent formal approvals required by then-live governance with zero unresolved threads;
  7. merge only the unchanged exact head after every applicable gate passes.

If the available mutation surface still lacks a safe non-destructive branch merge/update operation, classify only that reconciliation mutation TOOL_UNAVAILABLE; do not emulate it by moving refs. Do not self-approve, weaken gates, transfer predecessor evidence, invent approval/evidence, bypass governance, or fabricate release identity.


Open in Devin Review

@coderabbitai

coderabbitai Bot commented Aug 10, 2026

Copy link
Copy Markdown

Review Change Stack

Important

Draft PR not reviewed

Draft PRs are not automatically reviewed by default.

  • Trigger a manual review

To automatically review draft PRs, update your CodeRabbit configuration:

reviews:
  auto_review:
    drafts: true

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: e3322af6-a686-4f3a-984c-fa60c39efdaa

📥 Commits

Reviewing files that changed from the base of the PR and between 3b38ead and a517183.

📒 Files selected for processing (4)
  • src/editorFocusStyles.test.ts
  • src/forcedColorsStyles.test.ts
  • src/styles.css
  • tests/browser/specs/forced-colors.browser.spec.ts

Included review availability: Your plan provides up to 1 included review per hour; 0 remain after this review.


📝 Walkthrough

Walkthrough

편집기와 툴바에 forced-colors 스타일을 추가했습니다. 시스템 색상, 키보드 포커스, 비활성 상태, 링크, 구조적 경계선, 협업 표시를 검증하는 Vitest 및 Playwright 테스트를 추가했습니다.

Changes

강제 색상 접근성

Layer / File(s) Summary
Forced-colors CSS 계약
src/styles.css
편집기 콘텐츠에 포커스 윤곽선을 추가했습니다. 편집기, 툴바, 링크, 문서 구조, 협업 표시를 시스템 색상으로 매핑했습니다.
스타일시트 계약 검증
src/forcedColorsStyles.test.ts, src/editorFocusStyles.test.ts
forced-colors 블록의 위치와 단일성, 시스템 색상 사용, 포커스·상태·구조적 경계선 규칙을 검증합니다.
브라우저 forced-colors 검증
tests/browser/specs/forced-colors.browser.spec.ts
브라우저에서 테두리, 포커스, 비활성 버튼, 링크, 코드·표 경계선, 협업 커서와 라벨을 검증합니다.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Merge Risk: ⚪ Minimal · up to a5171

This localized accessibility change preserves forced-colors state cues without altering normal theme behavior, and no actionable merge-blocking risk remains after normal checks and review.

Sequence Diagram(s)

sequenceDiagram
  participant Browser
  participant ForcedColorsSpec
  participant LocalHarness
  participant Stylesheet
  Browser->>ForcedColorsSpec: forced-colors 테스트 실행
  ForcedColorsSpec->>LocalHarness: 로컬 fixture와 스타일시트 요청
  LocalHarness-->>Browser: 편집기 DOM과 CSS 제공
  Browser->>Stylesheet: forced-colors 스타일 적용
  ForcedColorsSpec->>Browser: computed style 및 포커스 상태 수집
  Browser-->>ForcedColorsSpec: 테두리, 색상, 윤곽선, 표시 상태 반환
Loading
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Linked Issues check ✅ Passed 변경 사항은 이슈 #150의 요구사항을 충족합니다. 단일 forced-colors 레이어에 CSS 시스템 색상을 적용했고, 포커스·활성·비활성·링크·구조 경계선·협업 표시를 보존했습니다. 결정적 스타일시트 테스트와 실제 브라우저 테스트도 추가했습니다. 일반 테마 선언과 사용자 에이전트의 forced-color 조정을 유지하며, PR을 Draft 상태로 유지…
Out of Scope Changes check ✅ Passed 변경 범위는 이슈 #150과 일치합니다. 변경 파일은 스타일시트, 관련 테스트, 기존 Playwright 브라우저 사양으로 제한되며 persistence, networking, authorization 또는 기타 무관한 기능 변경은 없습니다.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check. Docstring coverage is scoped to functions touched by this diff. Analyzed 0 functions across 3…
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed 제목은 forced-colors 접근성 상태 표시를 보존하는 주요 변경 사항을 정확하고 간결하게 요약합니다.
Full details: Linked Issues check

Explanation

변경 사항은 이슈 #150의 요구사항을 충족합니다. 단일 forced-colors 레이어에 CSS 시스템 색상을 적용했고, 포커스·활성·비활성·링크·구조 경계선·협업 표시를 보존했습니다. 결정적 스타일시트 테스트와 실제 브라우저 테스트도 추가했습니다. 일반 테마 선언과 사용자 에이전트의 forced-color 조정을 유지하며, PR을 Draft 상태로 유지하는 경계도 준수합니다.

Full details: Docstring Coverage

Explanation

No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check. Docstring coverage is scoped to functions touched by this diff. Analyzed 0 functions across 3 files. (1 skipped: 1 unsupported.)

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/forced-colors-accessibility

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@opencode-agent opencode-agent Bot added area: accessibility Accessibility and assistive-technology support priority: medium Normal-priority or P2 work status: draft Draft pull request type: bug Defect or incorrect behavior labels Aug 22, 2026
@seonghobae
seonghobae marked this pull request as ready for review August 25, 2026 18:15
@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.
To continue using code reviews, you can upgrade your account or add credits to your account and enable them for code reviews in your settings.

@devin-ai-integration devin-ai-integration Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Devin Review found 2 potential issues.

Open in Devin Review

expect(rejectedExternalRequests).toEqual([]);
});

test('preserves state and structural cues in forced colors', async ({ page }) => {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 New forced-colors browser test never runs

The spec file matches no Playwright project's testMatch (/(?:clipboard|print)\.browser\.spec\.ts/u in playwright.config.ts), so Playwright silently skips it. It is also outside vitest's src/** include, so no runner executes it and the forced-colors browser verification never happens.

Prompt for agents
The new spec tests/browser/specs/forced-colors.browser.spec.ts is never run. In tests/browser/playwright.config.ts, ENGINE_BROWSER_SPECS is defined as /(?:clipboard|print)\.browser\.spec\.ts/u and used as the testMatch for the chromium, firefox and webkit projects; the consensus project matches only clipboard.consensus.spec.ts. Because the filename forced-colors.browser.spec.ts does not contain 'clipboard' or 'print', it matches no project and Playwright skips it without error. Update the ENGINE_BROWSER_SPECS pattern (or add the new file to a project's testMatch) so that forced-colors.browser.spec.ts is discovered and executed, e.g. by extending the alternation to include 'forced-colors'.
Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

Comment thread tests/browser/specs/forced-colors.browser.spec.ts Outdated
@seonghobae
seonghobae marked this pull request as draft August 26, 2026 00:11
# Conflicts:
#	src/editorFocusStyles.test.ts
@seonghobae

Copy link
Copy Markdown
Contributor Author

Conflict resolution at merge head 5a0d410 (main@057762e + this branch):

  • src/styles.css: removed the duplicated ordinary focus rule and the small outline-color: CanvasText fragment left by the fix(a11y): repair editor contrast and keyboard focus #362 auto-merge; the comprehensive forced-colors block from this branch is now the single authoritative cascade (toolbar focus = Highlight offset +2px, editor content focus = Highlight offset −2px, structure/text = CanvasText family).
  • src/editorFocusStyles.test.ts: unified contract asserts (1) exactly one ordinary accent rule, (2) forced-colors block cascades AFTER it, (3) content focus Highlight −2px, toolbar Highlight +2px, and no competing partial override.
  • Both test files pass locally: 9/9.

CI re-verifies at this head.

- Single screen @media (forced-colors: active) layer after base state rules:
  editor content focus = CanvasText outline-color (guaranteed canvas
  contrast), toolbar focus/active = Highlight family, structure = CanvasText
- editorFocusStyles contract asserts the unified cascade; designTokens and
  forcedColors contracts both satisfied (17 tests pass)
@seonghobae

Copy link
Copy Markdown
Contributor Author

Cascade reconciliation at f522d1f: the #362-merged CanvasText content-focus contract and this branch's comprehensive forced-colors layer are now one block — single screen forced-colors layer after base state rules; editor content focus = CanvasText outline-color; toolbar focus/active = Highlight family. designTokens, forcedColors, and editorFocus contracts all pass locally (17/17). CI re-verifies.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area: accessibility Accessibility and assistive-technology support priority: medium Normal-priority or P2 work status: draft Draft pull request type: bug Defect or incorrect behavior

Projects

None yet

Development

Successfully merging this pull request may close these issues.

fix(accessibility): preserve forced-colors toolbar and editor state cues

1 participant