fix(accessibility): preserve forced-colors state cues - #151
Conversation
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (4)
Included review availability: Your plan provides up to 1 included review per hour; 0 remain after this review. 📝 WalkthroughWalkthrough편집기와 툴바에 forced-colors 스타일을 추가했습니다. 시스템 색상, 키보드 포커스, 비활성 상태, 링크, 구조적 경계선, 협업 표시를 검증하는 Vitest 및 Playwright 테스트를 추가했습니다. Changes강제 색상 접근성
Estimated code review effort: 3 (Moderate) | ~20 minutes Merge Risk: ⚪ Minimal · up to 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: 테두리, 색상, 윤곽선, 표시 상태 반환
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
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. Comment |
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
# Conflicts: # src/editorFocusStyles.test.ts
|
Conflict resolution at merge head
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)
|
Cascade reconciliation at |
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
Replace programmatic target focus with Tab navigation so the browser evidence exercises the actual focus-visible interaction path. Signed-off-by: Seongho Bae <me@seonghobae.me> Commit-Message-Assisted-by: Claude (via Claude Code)
Use the platform keyboard chord for control traversal while keeping ordinary Tab navigation on Chromium, Firefox, and non-macOS WebKit. Signed-off-by: Seongho Bae <me@seonghobae.me> Commit-Message-Assisted-by: Claude (via Claude Code)
|
Current head RED: the first cross-engine run passed Chromium/Firefox but WebKit on macOS skipped toolbar controls under plain GREEN: the harness now uses the native macOS WebKit
Hosted current-head checks and independent review remain required; this local evidence does not transfer across head or base movement. |
Signed-off-by: Seongho Bae <me@seonghobae.me>
|
Non-force merge a7d9919 contains the current #380 parent 5a1ba2e. The child-specific delta remains src/styles.css, the two stylesheet contract tests, and the forced-colors browser spec; browser configuration stays with #380. Local stylesheet contracts pass 8/8. The final unchanged signed head passes 51/51 browser checks: forced-colors keyboard/computed-style coverage and the composition suite on Chromium, Firefox and WebKit. An overlapping earlier local retry was rejected because the harness port was occupied; it provided no evidence and was rerun sequentially. The stale PR-body statement that this spec is undiscovered has been corrected. The PR remains Draft behind its parent; these are local emulation checks, not qualifying approval, current-head hosted CI, real-device support, or protected-main integration. |
Preserve the four-file forced-colors source/test delta while inheriting #380 and its #201/#176/#402 prerequisites through ordinary history. The existing focus, forced-colors and print stylesheet tests pass. No browser discovery configuration is copied or re-owned here; normal theme rules and the already-merged #362 baseline remain intact. Signed-off-by: Seongho Bae <me@seonghobae.me>
A 320px screenshot revealed image insertion and alternative-text controls clipped inside the editor while document scroll width still passed. Assert every actual toolbar button's full bounds in normal and forced colors, retaining screenshots. The corrected Chromium baseline fails on both clipped controls; the initial mistaken locator is retained as test-authoring failure, not product evidence. Signed-off-by: Seongho Bae <me@seonghobae.me>
The six actual-editor baseline cases each lost image insertion and alternative-text controls at 320px despite a passing document-width check. Reuse native flex wrapping inside the existing group; preserve all commands, target sizes, keyboard order, theme tokens and print rules. Record the 12-observation baseline, rejected alternatives and proposed acceptance in the canonical documentation graph. Signed-off-by: Seongho Bae <me@seonghobae.me>
Signed-off-by: Seongho Bae <me@seonghobae.me>
Real narrow-toolbar visibility: 12 clipped-control observations to zero — 2026-09-06Candidate The page-width check had missed an actual authoring failure: at 320px, the image button was partly clipped and its alternative-text button was entirely hidden. A page scroll width of 320px did not prove that controls inside the editor were available. The real public editor, rather than only a smaller chrome fixture, now checks the complete bounds of every toolbar button. Baseline Fresh final-head verification:
The initial incorrectly named locator failure is not counted as a geometry RED. The earlier UI candidate's full-suite teardown-oracle failure is retained and was repaired in source owner #201, not hidden by a UI-local workaround. The parent lane's default-worker timeout and subsequent bounded-worker proof remain separately disclosed in its evidence; this final run does not erase them or establish default/hosted-load reliability. PRD, TRD and the product-technical gap baseline link the bounded doctoring record, which records the baseline, alternatives, runnable regression and W3C Reflow basis. CONTRACTS is unchanged because no public API, document/evidence schema, callback or host authority changes. Keep Draft and integrate parents first. These source-harness screenshots and a separately verified package do not establish installed-tarball browser identity, physical-device/OS high-contrast or IME acceptance, whole-product WCAG conformance, a 20ms performance target, protected merge, central review, approval or release. Re-fetch all live governance and exact-head evidence before any lifecycle transition. |
Signed-off-by: Seongho Bae <me@seonghobae.me>
Signed-off-by: Seongho Bae <me@seonghobae.me>
Signed-off-by: Seongho Bae <me@seonghobae.me>
Signed-off-by: Seongho Bae <me@seonghobae.me>
Signed-off-by: Seongho Bae <me@seonghobae.me>
Signed-off-by: Seongho Bae <me@seonghobae.me>
Signed-off-by: Seongho Bae <me@seonghobae.me>
Signed-off-by: Seongho Bae <me@seonghobae.me>
Signed-off-by: Seongho Bae <me@seonghobae.me>
Signed-off-by: Seongho Bae <me@seonghobae.me>
Signed-off-by: Seongho Bae <me@seonghobae.me>
Signed-off-by: Seongho Bae <me@seonghobae.me>
Signed-off-by: Seongho Bae <me@seonghobae.me>
Direct visual inspection found and repaired unreadable labelsCandidate: The earlier nine passing semantic/geometry checks did not establish visual Readable placeholder guidance and quoted content now use Current local evidence:
Directly inspected source and packed images cover normal and forced colors at 320 CSS Earlier failures remain retained, including the initial server startup timeout, This remains Draft/Proposed. Current protected-main ancestry, hosted checks, |
Signed-off-by: Seongho Bae <me@seonghobae.me>
Latest integration evidence — 2026-09-06
Current-head local Office verification on Python 3.14.6 also passed all
173 tests in 2.37 seconds; configured 598 statements/244 branches and public
docstrings 100%. This does not establish the hosted supported-version matrix.
Current candidate
59d32209159f74ce17fb71eb4595a3ccba92bf8dnormally mergesparent #380
6a7121e04652348e6dbc7b58bbad843ef07f6f86. It inherits the sharedexpected-archive evidence guard, with no new product delta. The shared helper
and regression exactly match the parent. Nineteen focused tests and TypeScript
pass. The full new-head configured coverage run passed 1,033 tests across
177 files in 65.85 seconds, all configured source coverage 100%.
New-head build, complete independent package consumer chain and fresh pack pass.
Archive SHA-256:
dce31fd1cf0e270633034c21950cf40a2e01b1ba0e5eaa125c579953564a14da.Full canonical packed browser run failed: 152 passed, one Firefox native-form
case timed out in its afterEach network-idle wait, and consensus did not run;
85.718207 seconds, no flaky tests or global errors. This is not full acceptance.
Nine screenshots were directly inspected: each engine's 320px normal focus,
forced selected/hover states, and structural/cursor fixture. Controls remained
unclipped, focus and selected states visible, with document/cursor boundaries
preserved. Emulated palettes differ by engine; this does not certify physical
high-contrast hardware or WCAG. Failed receipts and screenshots are retained in
/private/tmp/inkspan-pr151-current-package.31kvNI; archive digest recheckedunchanged afterward. All older passes below remain predecessor evidence.
This PR remains Draft and does not imply protected integration or release.
Subsequent full canonical
--trace onacquisition also failed: 130 passed,four Firefox failures, 20 not run in 255.529388 seconds. Korean input failed
at click before committed text; clipboard, native-form and touch cases hit
deadlines including teardown. Failed traces show page creation 7.25–9.15 s
and navigation 6.38–10.60 s in input cases. An in-run host snapshot recorded
load 32.24 on 10 CPUs, which supports a contention hypothesis, not a proven
cause. Directly inspected Korean failure frame shows the empty placeholder,
not text corruption. All failures and receipts are retained at
/private/tmp/inkspan-pr151-full-trace.ir4ndN. A one-worker full-denominatordiagnostic is pending; no canonical setting or deadline was weakened.
That one-worker full diagnostic completed: 154 passed in 170.231333 seconds,
zero skipped, unexpected, flaky or global errors. Exact-head/archive run
bac023d3-9e86-4a73-897e-7ab156b449f1; copied receipts in/private/tmp/inkspan-pr151-serial-trace.FjuWWa. Host load also decreased from16.26 to 8.57 during this run, so the concurrency effect is not isolated.
This is full-denominator serial evidence, not default three-worker acceptance
or a proven timeout repair. Original deadlines and request guards unchanged.
Closes #150.
Purpose
Implement the bounded forced-colors/high-contrast accessibility slice and keep every existing toolbar command fully visible at narrow widths. Preserve normal light/dark theme colors, command order, control sizes and host authority boundaries.
Protected
mainis the shipped implementation authority. Mutable head/base SHAs, divergence counts, workflow IDs, review counts and mergeability are decision-time evidence only and must be refetched before every lifecycle action.Test-first lineage
d89bd41dabca47a00d486e847eed0d3df8b5456bproved missing forced-colors system-state mappings.bcd993a1d521d3f44fe07eaeaa5acda10dce3d6bproved split forced-colors blocks could be overridden by later equal-specificity screen rules.@media (forced-colors: active)layer without weakening normal light/dark behavior.Tabfocus rather than programmatic.focus()for:focus-visibleevidence. That finding is addressed in the branch; its resolved/outdated review thread is not a remaining blocker.docs/doctoring/toolbar-reflow.md.Implemented boundary
Inside the final forced-colors 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 colors remain unchanged. Forced-mode placeholder guidance and quoted content use readable document text colors. Color transitions are disabled only in forced mode, and the existing system highlight pairs on hovered/active buttons and cursor labels retain readable text with a narrowly scoped adjustment exception. Cursor-label system colors override its normal inline colors; editor/document-wide automatic adjustment remains enabled. Outside that media query, the existing toolbar group also uses native flex wrapping so image insertion and alternative-text controls remain fully visible at 320px in both normal and forced colors. This preserves existing commands, DOM/keyboard order, control sizes and tokens; groups may take additional vertical space.
This slice adds no persistence, transport, credentials, model use, authorization, tenancy, network, provider, room, or durable-audit authority.
Browser-discovery dependency
This PR is stacked on #380, the dedicated browser harness/spec/config owner, and inherits its generalized desktop-engine discovery contract. Parent updates are integrated with merge commits, never by copying the configuration into a competing writer.
The committed forced-colors journey must be selected and executed by Chromium, Firefox and WebKit on every candidate generation. Local runs establish browser-emulated keyboard/focus, computed-style and directly inspected screenshot evidence only; they do not establish physical-device high-contrast support or protected-main acceptance. Refetch the current parent, child, discovery results, CI checkout identity and review threads before any lifecycle transition.
Dependency order / source ownership
This remains the earliest active owner for the forced-colors production/source boundary. Former PR #362 is already integrated on protected main and overlaps historical
src/styles.css/ focus-test work, so #151 must reconcile its net production delta against then-current protected truth non-destructively before further lifecycle advancement.For browser configuration specifically, #380 remains the single writer. Release issue #118 is a downstream stable-release acceptance boundary and does not authorize bypassing this PR's own dependency, browser-execution, review, or merge gates.
Integration boundary
Before any lifecycle transition:
tests/browser/playwright.config.ts; only after its generalized discovery contract is inherited/reconciled may fix(accessibility): preserve forced-colors state cues #151 claim forced-colors browser execution;If the available mutation surface lacks a safe non-destructive branch merge/update operation, classify only that exact reconciliation mutation
TOOL_UNAVAILABLE; do not emulate it by moving refs or copying the browser-config fix into this branch. Pending, queued, skipped-required, cancelled, absent, neutral, failed, stale, predecessor, status-only, model-only, wrong-checkout, undiscovered-test, or synthetic-source-only evidence is non-passing. Do not self-approve, weaken gates, transfer predecessor evidence, bypass governance, or fabricate release identity.