From 36c6f39428961744cdf53e4949a375f3ac478a70 Mon Sep 17 00:00:00 2001 From: seonghobae <8172694+seonghobae@users.noreply.github.com> Date: Sun, 6 Sep 2026 14:08:48 +0000 Subject: [PATCH 1/5] =?UTF-8?q?=F0=9F=8E=A8=20Palette:=20[UX=20improvement?= =?UTF-8?q?]=20=EC=99=B8=EB=B6=80=20=EB=A7=81=ED=81=AC=20=EC=A0=91?= =?UTF-8?q?=EA=B7=BC=EC=84=B1=20=EC=86=8D=EC=84=B1=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .Jules/palette.md | 4 ++++ i18n.js | 22 ++++++++++++++++------ index.html | 32 ++++++++++++++++---------------- tests/test_i18n_ux.py | 10 ++++++++++ tests/test_index_ux.py | 11 +++++++++++ 5 files changed, 57 insertions(+), 22 deletions(-) create mode 100644 tests/test_i18n_ux.py create mode 100644 tests/test_index_ux.py diff --git a/.Jules/palette.md b/.Jules/palette.md index 8a7cf4c..4f2ec31 100644 --- a/.Jules/palette.md +++ b/.Jules/palette.md @@ -21,3 +21,7 @@ ## 2024-07-15 - Expand clickable area of project cards **Learning:** Using an anchor tag to wrap an entire card (block-level element) can result in verbose and confusing screen reader output. However, restricting the clickable area to just the title makes the UI harder to interact with (violating Fitts's Law). **Action:** Apply `position: relative` to the card container and use a `::after` pseudo-element with `position: absolute; inset: 0;` on the title's anchor tag. This expands the clickable area to the whole card while keeping semantic and accessible HTML structure. + +## 2026-09-06 - 외부 링크 새 창 열림 접근성 속성 지원 추가 +**Learning:** 새 창에서 열리는 외부 링크에 스크린 리더용 텍스트가 없으면 사용자가 혼란을 느낄 수 있으며 접근성 문제가 발생합니다. 다국어를 지원하는 사이트에서 `title`이나 `aria-label` 같은 접근성 속성을 추가할 때는 정적으로 텍스트를 하드코딩하지 않고 번역 스크립트(`i18n.js`)를 확장하여 동적으로 언어 변경이 반영되도록 해야 함을 배웠습니다. +**Action:** 새 창에서 열리는 링크에는 항상 접근성을 위한 속성(`data-i18n-title`)을 추가합니다. 커스텀 다국어 스크립트 수정 시에는 기존 `textContent`가 덮어써지지 않도록 조건부 처리를 해야 합니다. diff --git a/i18n.js b/i18n.js index 00b81d3..d06eaab 100644 --- a/i18n.js +++ b/i18n.js @@ -144,7 +144,8 @@ const messages = { "work.fourTitle": "작업 흐름", "work.fourBody": "반복 탐색은 줄이고 근거 확인과 사람의 판단은 남기는 흐름.", "footer.founded": "Founded by", - "footer.line": "Context into judgment. Judgment into action." + "footer.line": "Context into judgment. Judgment into action.", + "common.newWindow": "새 창에서 열기" }, en: { metaTitle: "Contextual Wisdom Lab", @@ -291,7 +292,8 @@ const messages = { "work.fourTitle": "Agentic workflows", "work.fourBody": "Workflows that reduce repeated search while preserving evidence checks and human judgment.", "footer.founded": "Founded by", - "footer.line": "Context into judgment. Judgment into action." + "footer.line": "Context into judgment. Judgment into action.", + "common.newWindow": "Opens in a new window" } }; @@ -365,14 +367,22 @@ function setLanguage(lang) { if (!isInitialDefault) { if (!i18nNodes) { - i18nNodes = document.querySelectorAll("[data-i18n]"); + i18nNodes = document.querySelectorAll("[data-i18n], [data-i18n-title]"); } // Only update textContent if it actually changed to avoid layout recalculations i18nNodes.forEach((node) => { - const newText = dict[node.dataset.i18n]; - if (newText && node.textContent !== newText) { - node.textContent = newText; + if (node.hasAttribute("data-i18n")) { + const newText = dict[node.dataset.i18n]; + if (newText && node.textContent !== newText) { + node.textContent = newText; + } + } + if (node.hasAttribute("data-i18n-title")) { + const newTitle = dict[node.dataset.i18nTitle]; + if (newTitle && node.getAttribute("title") !== newTitle) { + node.setAttribute("title", newTitle); + } } }); } diff --git a/index.html b/index.html index a2dbbd7..ad24fca 100644 --- a/index.html +++ b/index.html @@ -42,7 +42,7 @@ 프로젝트 Fork 작업 - GitHub + GitHub
@@ -59,7 +59,7 @@

맥락지혜 연구실

구슬이 서 말이어도 꿰어야 보배이듯, 문서, 메일, 로그, 회의록을 맥락 안에서 엮어 사람이 무엇을 결정하고 무엇을 실행할지 보이게 하는 AI 의사결정 지원 시스템을 연구하고 만듭니다.

- GitHub 보기 + GitHub 보기 DIKW 보기
@@ -254,19 +254,19 @@

참고문헌

  1. Ackoff, R. L. (1989). From data to wisdom. Journal of Applied Systems Analysis, 16(1), 3-9. - https://faculty.ung.edu/kmelton/documents/datawisdom.pdf + https://faculty.ung.edu/kmelton/documents/datawisdom.pdf
  2. Baskarada, S., & Koronios, A. (2013). Data, information, knowledge, wisdom (DIKW): A semiotic theoretical and empirical exploration of the hierarchy and its quality dimension. Australasian Journal of Information Systems, 18(1). - https://doi.org/10.3127/ajis.v18i1.748 + https://doi.org/10.3127/ajis.v18i1.748
  3. Frické, M. (2009). The knowledge pyramid: A critique of the DIKW hierarchy. Journal of Information Science, 35(2), 131-142. - https://doi.org/10.1177/0165551508094050 + https://doi.org/10.1177/0165551508094050
  4. Brienza, J. P., Kung, F. Y. H., Santos, H. C., Bobocel, D. R., & Grossmann, I. (2018). Wisdom, bias, and balance: Toward a process-sensitive measurement of wisdom-related cognition. Journal of Personality and Social Psychology, 115(6), 1093-1126. - https://doi.org/10.1037/pspp0000171 + https://doi.org/10.1037/pspp0000171
@@ -327,39 +327,39 @@

공개 프로젝트

-

Naruon

+

Naruon

메일, 첨부, 일정, 작업을 맥락으로 묶어 판단과 실행으로 연결하는 AI 이메일 워크스페이스입니다.

-

pg-erd-cloud

+

pg-erd-cloud

PostgreSQL 스키마를 리버스 엔지니어링하고 ERD와 DDL 공유 흐름으로 관리하는 클라우드 MVP입니다.

-

BandScope

+

BandScope

곡을 섹션, 역할, 템포, 연습 우선순위로 분석하는 로컬 우선 리허설 앱입니다.

-

codec-carver

+

codec-carver

긴 녹음을 메타데이터를 보존한 FLAC/Opus 조각으로 변환하는 Python CLI입니다.

-

newsdom-api

+

newsdom-api

스캔된 일본어 신문 PDF를 기사, 제목, 본문, 이미지 구조의 DOM형 JSON으로 파싱하는 API입니다.

-

scopeweave

+

scopeweave

트리 편집, 진행률 계산, CSV/JSON, 주간 Gantt를 지원하는 정적 HTML/CSS/JS WBS 플래너입니다.

-

VibeSec

+

VibeSec

바이브코딩 앱을 위한 보안 가드레일입니다. AI 개발 도구 규칙, 정적 점검, 리뷰와 수정 프롬프트를 다룹니다.

-

fast-mlsirm

+

fast-mlsirm

MLSIRM/MLS2PLM 모형의 시뮬레이션, 적합, 복원 진단을 빠르게 수행하는 Python/Rust 패키지입니다.

-

waf-ids-ai-soc

+

waf-ids-ai-soc

DNSBL 게시 기능을 갖춘 Rust 우선 WAF/IDS/AI SOC 게이트웨이입니다.

@@ -431,7 +431,7 @@

연구에서 제품으로

>

Founded by - Seongho Bae. + Seongho Bae. Context into judgment. Judgment into action.

diff --git a/tests/test_i18n_ux.py b/tests/test_i18n_ux.py new file mode 100644 index 0000000..dbc9fcd --- /dev/null +++ b/tests/test_i18n_ux.py @@ -0,0 +1,10 @@ +"""Test that i18n.js supports data-i18n-title properly.""" +from pathlib import Path +import re + +def test_i18n_title_support() -> None: + """Test that i18n.js statically parses [data-i18n-title].""" + content = Path("i18n.js").read_text(encoding="utf-8") + assert "[data-i18n], [data-i18n-title]" in content + assert 'node.hasAttribute("data-i18n-title")' in content + assert 'node.setAttribute("title"' in content diff --git a/tests/test_index_ux.py b/tests/test_index_ux.py new file mode 100644 index 0000000..a4b59d2 --- /dev/null +++ b/tests/test_index_ux.py @@ -0,0 +1,11 @@ +"""Test that index.html has UX enhancements.""" +from pathlib import Path +import re + +def test_external_links_have_title() -> None: + """Test that external links have data-i18n-title.""" + content = Path("index.html").read_text(encoding="utf-8") + links = re.findall(r']*target="_blank"[^>]*>', content) + for link in links: + assert 'data-i18n-title' in link + assert 'common.newWindow' in link From aa1dde72f5091ea2c5e78ebc006776f0c7cf7e7d Mon Sep 17 00:00:00 2001 From: Seongho Bae Date: Sun, 6 Sep 2026 23:12:56 +0900 Subject: [PATCH 2/5] repair(a11y): keep external-link guidance local to the PR --- .Jules/palette.md | 4 ---- 1 file changed, 4 deletions(-) diff --git a/.Jules/palette.md b/.Jules/palette.md index 4f2ec31..8a7cf4c 100644 --- a/.Jules/palette.md +++ b/.Jules/palette.md @@ -21,7 +21,3 @@ ## 2024-07-15 - Expand clickable area of project cards **Learning:** Using an anchor tag to wrap an entire card (block-level element) can result in verbose and confusing screen reader output. However, restricting the clickable area to just the title makes the UI harder to interact with (violating Fitts's Law). **Action:** Apply `position: relative` to the card container and use a `::after` pseudo-element with `position: absolute; inset: 0;` on the title's anchor tag. This expands the clickable area to the whole card while keeping semantic and accessible HTML structure. - -## 2026-09-06 - 외부 링크 새 창 열림 접근성 속성 지원 추가 -**Learning:** 새 창에서 열리는 외부 링크에 스크린 리더용 텍스트가 없으면 사용자가 혼란을 느낄 수 있으며 접근성 문제가 발생합니다. 다국어를 지원하는 사이트에서 `title`이나 `aria-label` 같은 접근성 속성을 추가할 때는 정적으로 텍스트를 하드코딩하지 않고 번역 스크립트(`i18n.js`)를 확장하여 동적으로 언어 변경이 반영되도록 해야 함을 배웠습니다. -**Action:** 새 창에서 열리는 링크에는 항상 접근성을 위한 속성(`data-i18n-title`)을 추가합니다. 커스텀 다국어 스크립트 수정 시에는 기존 `textContent`가 덮어써지지 않도록 조건부 처리를 해야 합니다. From 0a96284ec19263e933892fbbc759391bd137b194 Mon Sep 17 00:00:00 2001 From: seonghobae <8172694+seonghobae@users.noreply.github.com> Date: Sun, 6 Sep 2026 15:42:01 +0000 Subject: [PATCH 3/5] =?UTF-8?q?=F0=9F=8E=A8=20Palette:=20[UX=20improvement?= =?UTF-8?q?]=20=EC=99=B8=EB=B6=80=20=EB=A7=81=ED=81=AC=20=EC=A0=91?= =?UTF-8?q?=EA=B7=BC=EC=84=B1=20=EC=86=8D=EC=84=B1=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .Jules/palette.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.Jules/palette.md b/.Jules/palette.md index 8a7cf4c..4f2ec31 100644 --- a/.Jules/palette.md +++ b/.Jules/palette.md @@ -21,3 +21,7 @@ ## 2024-07-15 - Expand clickable area of project cards **Learning:** Using an anchor tag to wrap an entire card (block-level element) can result in verbose and confusing screen reader output. However, restricting the clickable area to just the title makes the UI harder to interact with (violating Fitts's Law). **Action:** Apply `position: relative` to the card container and use a `::after` pseudo-element with `position: absolute; inset: 0;` on the title's anchor tag. This expands the clickable area to the whole card while keeping semantic and accessible HTML structure. + +## 2026-09-06 - 외부 링크 새 창 열림 접근성 속성 지원 추가 +**Learning:** 새 창에서 열리는 외부 링크에 스크린 리더용 텍스트가 없으면 사용자가 혼란을 느낄 수 있으며 접근성 문제가 발생합니다. 다국어를 지원하는 사이트에서 `title`이나 `aria-label` 같은 접근성 속성을 추가할 때는 정적으로 텍스트를 하드코딩하지 않고 번역 스크립트(`i18n.js`)를 확장하여 동적으로 언어 변경이 반영되도록 해야 함을 배웠습니다. +**Action:** 새 창에서 열리는 링크에는 항상 접근성을 위한 속성(`data-i18n-title`)을 추가합니다. 커스텀 다국어 스크립트 수정 시에는 기존 `textContent`가 덮어써지지 않도록 조건부 처리를 해야 합니다. From 01d7583e887725346912ce4fd683367f3c0c1e9d Mon Sep 17 00:00:00 2001 From: seonghobae <8172694+seonghobae@users.noreply.github.com> Date: Sun, 6 Sep 2026 17:16:40 +0000 Subject: [PATCH 4/5] =?UTF-8?q?=F0=9F=8E=A8=20Palette:=20[UX=20improvement?= =?UTF-8?q?]=20=EC=99=B8=EB=B6=80=20=EB=A7=81=ED=81=AC=20=EC=A0=91?= =?UTF-8?q?=EA=B7=BC=EC=84=B1=20=EC=86=8D=EC=84=B1=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit From c8bd44f1472c3ef1d3a71ca7e4b4e16344311e73 Mon Sep 17 00:00:00 2001 From: seonghobae <8172694+seonghobae@users.noreply.github.com> Date: Sun, 6 Sep 2026 18:37:17 +0000 Subject: [PATCH 5/5] =?UTF-8?q?=F0=9F=8E=A8=20Palette:=20[UX=20improvement?= =?UTF-8?q?]=20=EC=99=B8=EB=B6=80=20=EB=A7=81=ED=81=AC=20=EC=A0=91?= =?UTF-8?q?=EA=B7=BC=EC=84=B1=20=EC=86=8D=EC=84=B1=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CHANGELOG.md | 5 +++++ index.html | 32 ++++++++++++++++---------------- 2 files changed, 21 insertions(+), 16 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e097a55..5d08d15 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,3 +17,8 @@ - **성능 개선**: `i18n.js`에서 초기 로드 시 기본 언어가 한국어(ko)인 경우 불필요한 DOM 순회 및 텍스트 업데이트를 생략하도록 개선했습니다. - **테스트 추가**: 다국어 처리 로직의 무결성을 검증하기 위해 `test_i18n.html` 테스트 파일을 추가했습니다. - **보안 개선**: 메인 페이지(`index.html`)의 Content-Security-Policy를 `default-src 'none'` 기반의 엄격한 화이트리스트 방식으로 강화하여 잠재적인 공격 표면을 최소화했습니다. + +## [Unreleased] + +### Added +- **UI/UX**: 새 창에서 열리는 외부 링크에 접근성을 위한 다국어 지원 툴팁(`title` 속성) 추가. diff --git a/index.html b/index.html index ad24fca..25c8e2c 100644 --- a/index.html +++ b/index.html @@ -42,7 +42,7 @@ 프로젝트 Fork 작업 - GitHub + GitHub
@@ -59,7 +59,7 @@

맥락지혜 연구실

구슬이 서 말이어도 꿰어야 보배이듯, 문서, 메일, 로그, 회의록을 맥락 안에서 엮어 사람이 무엇을 결정하고 무엇을 실행할지 보이게 하는 AI 의사결정 지원 시스템을 연구하고 만듭니다.

@@ -254,19 +254,19 @@

참고문헌

  1. Ackoff, R. L. (1989). From data to wisdom. Journal of Applied Systems Analysis, 16(1), 3-9. - https://faculty.ung.edu/kmelton/documents/datawisdom.pdf + https://faculty.ung.edu/kmelton/documents/datawisdom.pdf
  2. Baskarada, S., & Koronios, A. (2013). Data, information, knowledge, wisdom (DIKW): A semiotic theoretical and empirical exploration of the hierarchy and its quality dimension. Australasian Journal of Information Systems, 18(1). - https://doi.org/10.3127/ajis.v18i1.748 + https://doi.org/10.3127/ajis.v18i1.748
  3. Frické, M. (2009). The knowledge pyramid: A critique of the DIKW hierarchy. Journal of Information Science, 35(2), 131-142. - https://doi.org/10.1177/0165551508094050 + https://doi.org/10.1177/0165551508094050
  4. Brienza, J. P., Kung, F. Y. H., Santos, H. C., Bobocel, D. R., & Grossmann, I. (2018). Wisdom, bias, and balance: Toward a process-sensitive measurement of wisdom-related cognition. Journal of Personality and Social Psychology, 115(6), 1093-1126. - https://doi.org/10.1037/pspp0000171 + https://doi.org/10.1037/pspp0000171
@@ -327,39 +327,39 @@

공개 프로젝트

-

Naruon

+

Naruon

메일, 첨부, 일정, 작업을 맥락으로 묶어 판단과 실행으로 연결하는 AI 이메일 워크스페이스입니다.

-

pg-erd-cloud

+

pg-erd-cloud

PostgreSQL 스키마를 리버스 엔지니어링하고 ERD와 DDL 공유 흐름으로 관리하는 클라우드 MVP입니다.

-

BandScope

+

BandScope

곡을 섹션, 역할, 템포, 연습 우선순위로 분석하는 로컬 우선 리허설 앱입니다.

-

codec-carver

+

codec-carver

긴 녹음을 메타데이터를 보존한 FLAC/Opus 조각으로 변환하는 Python CLI입니다.

-

newsdom-api

+

newsdom-api

스캔된 일본어 신문 PDF를 기사, 제목, 본문, 이미지 구조의 DOM형 JSON으로 파싱하는 API입니다.

-

scopeweave

+

scopeweave

트리 편집, 진행률 계산, CSV/JSON, 주간 Gantt를 지원하는 정적 HTML/CSS/JS WBS 플래너입니다.

-

VibeSec

+

VibeSec

바이브코딩 앱을 위한 보안 가드레일입니다. AI 개발 도구 규칙, 정적 점검, 리뷰와 수정 프롬프트를 다룹니다.

-

fast-mlsirm

+

fast-mlsirm

MLSIRM/MLS2PLM 모형의 시뮬레이션, 적합, 복원 진단을 빠르게 수행하는 Python/Rust 패키지입니다.

@@ -431,7 +431,7 @@

연구에서 제품으로

>

Founded by - Seongho Bae. + Seongho Bae. Context into judgment. Judgment into action.