Skip to content

fix(accessibility): reconcile robust focus appearance after #270 - #334

Open
seonghobae wants to merge 6 commits into
mainfrom
fix/focus-appearance-main
Open

fix(accessibility): reconcile robust focus appearance after #270#334
seonghobae wants to merge 6 commits into
mainfrom
fix/focus-appearance-main

Conversation

@seonghobae

@seonghobae seonghobae commented Aug 10, 2026

Copy link
Copy Markdown
Collaborator

Objective

Reconstruct the bounded WCAG focus-appearance fix directly on the protected-main baseline after #270 integrated, so base-sensitive verification runs without predecessor ancestry.

Exact current state — 2026-08-17

  • exact source head: 858e22f31ae87ae1b2335884f98c4ff69ab2c793;
  • exact protected main: eb0a32e87e7470469c8fa0f8c67d9583654bef57;
  • clean delta: two changed files; GitHub reports the PR open and mergeable;
  • exact-head repository CI, Security Scan, SAST Semgrep, fuzz, coverage, Strix, Noema, OpenCode, CodeQL, Trivy, OSV, dependency review and merge-compatibility evidence observed for this head are terminal-success;
  • skipped helper/cancellation jobs are not treated as passing required evidence;
  • current formal review inventory contains no submitted approving review, so this head is not merge-ready under the active organization ruleset.

Preserved accessibility contract

The shipped :focus-visible rule uses:

  • a 3px black outline with a 3px offset;
  • a 3px white box-shadow band;
  • no pointer-only focus replacement and no added animation.

The deterministic contract computes WCAG relative luminance and contrast, requiring at least 2 CSS px at >=3:1 against both white and black reference surfaces. It also prevents overlapping outline/shadow pixels from being double-counted by limiting the exposed shadow band to the outline offset.

Exact source identity

Changed blobs remain limited to:

  • scripts/test_viewer_focus_appearance.py;
  • src/main/resources/static/assets/viewer/viewer.css.

The protected-main CSS before reconstruction was byte-identical to the former #325 base, proving #270 did not modify this path. #325 remains predecessor evidence only and is superseded by this current-base branch.

Scope / non-completion boundary

This two-file slice does not modify viewer generation ownership (#322/#323), demo/session authority (#317), nested asynchronous controls (#264), Java controllers, build metadata, or canonical cross-cutting documentation. Issue #324 remains the product and standards authority.

Live merge gate

Keep this exact head unchanged. The active organization ruleset requires the configured central workflows, one qualifying approving review, stale-review dismissal on push, approval after the latest push, and review-thread resolution. No bypass actor is configured and the current user cannot bypass. Merge only after those live rules remain satisfied on this unchanged head; automated checks, comments, statuses, or model output do not substitute for the independent approval.

Summary by CodeRabbit

  • 개선 사항

    • 뷰어의 키보드 포커스 표시를 개선해 밝은 테마와 어두운 테마 모두에서 더 명확하게 보이도록 했습니다.
    • 포커스 테두리의 두께와 간격은 기존과 동일하게 유지됩니다.
  • 테스트

    • 다양한 배경색에서 포커스 표시의 대비와 접근성을 검증하는 테스트를 추가했습니다.

@coderabbitai

coderabbitai Bot commented Aug 10, 2026

Copy link
Copy Markdown

Review Change Stack

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: 17cc9952-1e76-4aee-84ab-eb29ee003cb9

📥 Commits

Reviewing files that changed from the base of the PR and between 961f44a and a50e4f2.

📒 Files selected for processing (2)
  • scripts/test_viewer_focus_appearance.py
  • src/main/resources/static/assets/viewer/viewer.css

📝 Walkthrough

Walkthrough

Viewer의 :focus-visible 스타일을 검정색 outline과 흰색 외곽 box-shadow 조합으로 변경했습니다. CSS를 파싱해 포커스 표시의 폭과 WCAG 대비율을 검증하는 테스트 스크립트를 추가했습니다.

Changes

포커스 대비 표시

Layer / File(s) Summary
포커스 링 스타일
src/main/resources/static/assets/viewer/viewer.css
:focus-visible의 outline 색상을 검정색으로 변경하고 흰색 3px 외곽 box-shadow를 추가했습니다. outline 두께와 offset은 유지합니다.
CSS 포커스 대비 검증
scripts/test_viewer_focus_appearance.py
CSS 변수와 제한된 color-mix 표현식을 해석하고, outline 및 shadow의 노출 폭을 계산합니다. 밝은 배경과 어두운 배경에서 3:1 이상의 대비를 갖는 표시 폭이 2px 이상인지 검증합니다. 겹치는 shadow의 중복 계산도 검증합니다.

Estimated code review effort: 4 (Complex) | ~45 minutes

Mergeability Score: ⚪ Minimal · up to a50e4

The PR makes a localized focus-appearance and deterministic verification change, with no actionable merge-blocking risk remaining after normal checks and review.

Possibly related issues

Possibly related PRs

  • ContextualWisdomLab/clearfolio#325 — 동일한 viewer.css 포커스 스타일과 대비 검증 스크립트를 수정하며, 이 PR은 검정색과 흰색 포커스 링을 적용합니다.
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed 제목은 접근성 포커스 표시 수정이라는 변경의 핵심을 정확하게 설명하며 간결하고 관련성이 높습니다.
✨ 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/focus-appearance-main

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.

@seonghobae
seonghobae marked this pull request as ready for review August 10, 2026 12:05
@seonghobae
seonghobae enabled auto-merge (squash) August 10, 2026 12:46

Copy link
Copy Markdown
Collaborator Author

@opencode-agent @cwl-noema-review Please independently review exact current head d080540076703d2e94940522f18ac6be86d2da37 against protected main 55d7ae8647208e301f282350f076eeddaba61d11. Exact-head CI 31389256791, Security Scan 31389256767, SAST 31389256739, and fuzz 31389256710 are successful. Verify the two-tone focus contract provides at least 2 CSS px at >=3:1 on both light and dark surfaces, preserves :focus-visible, does not double-count overlapping shadow pixels, and remains path-disjoint from viewer-generation, demo/session, and nested async-control work. The final commit is same-tree verification only. Advisory review; do not mutate, count as human approval, merge, or weaken gates.

Copy link
Copy Markdown
Collaborator Author

@opencode-agent review
@coderabbitai review
@cwl-noema-review review
@strix review

Review exact head 858e22f31ae87ae1b2335884f98c4ff69ab2c793 over protected base eb0a32e87e7470469c8fa0f8c67d9583654bef57 only. Current-head CI, Security Scan, SAST Semgrep, and fuzz are terminal-success. Review the deterministic focus-visible thickness/contrast contract and its behavior on both light and dark reference surfaces.

Review read-only; preserve independent reviewer identity. Do not mutate the branch, synthesize author approval, weaken protection, or merge.

@coderabbitai

coderabbitai Bot commented Aug 15, 2026

Copy link
Copy Markdown
🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

base='eb0a32e87e7470469c8fa0f8c67d9583654bef57'
head='858e22f31ae87ae1b2335884f98c4ff69ab2c793'

git cat-file -e "${base}^{commit}"
git cat-file -e "${head}^{commit}"
git merge-base --is-ancestor "$base" "$head"
printf '\n== Exact commits ==\n'
git show -s --format='%H%n%P%n%s' "$base" "$head"

printf '\n== Changed paths: base...head ==\n'
git diff --name-status "$base" "$head"

printf '\n== Exact diff ==\n'
git diff --no-ext-diff --unified=80 "$base" "$head" -- \
  scripts/test_viewer_focus_appearance.py \
  src/main/resources/static/assets/viewer/viewer.css

printf '\n== CSS structure ==\n'
ast-grep outline src/main/resources/static/assets/viewer/viewer.css --items all || true

printf '\n== Test structure ==\n'
ast-grep outline scripts/test_viewer_focus_appearance.py --items all || true

printf '\n== Focus-visible rules in exact head ==\n'
git show "${head}:src/main/resources/static/assets/viewer/viewer.css" |
  rg -n -A18 -B8 ':focus-visible|outline|box-shadow' || true

printf '\n== Excluded-area path check ==\n'
git diff --name-only "$base" "$head" |
  rg -n -i 'viewer.?gen|generation|demo|session|async|asynchronous|controller|pom\.xml|build\.gradle|settings\.gradle|README|docs' || true

Length of output: 15104


@seonghobae Reviewed exact head 858e22f31ae87ae1b2335884f98c4ff69ab2c793 over base eb0a32e87e7470469c8fa0f8c67d9583654bef57.

No findings.

The diff changes only:

  • scripts/test_viewer_focus_appearance.py
  • src/main/resources/static/assets/viewer/viewer.css

The :focus-visible rule remains in use. It provides:

  • A 3px black outline. It has 21:1 contrast against a white surface.
  • A 3px white shadow band. It has 21:1 contrast against a black surface.
  • A 3px outline offset. This keeps the two bands separate.

The contract test requires at least 2px at 3:1 on both reference surfaces. It calculates WCAG contrast from relative luminance. It limits the counted shadow width to min(shadow_spread, outline_offset). The overlap test confirms that non-exposed shadow pixels are not counted twice.

The exact diff is path-disjoint from viewer-generation, demo/session, and nested asynchronous-control work.

This was an advisory, read-only review. It did not approve, merge, mutate the branch, or change repository gates.

⚠️ Action not completed

No files to review.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant