diff --git a/REQUIREMENTS.md b/REQUIREMENTS.md index ef6435d..00bc7af 100644 --- a/REQUIREMENTS.md +++ b/REQUIREMENTS.md @@ -4,10 +4,10 @@ | 항목 | 내용 | | :--- | :--- | | **문서 ID** | `REQ-ANL-WEB-001` | -| **버전** | `1.12` | +| **버전** | `1.14` | | **작성일** | 2026-07-30 | | **작성자** | claude (`canary-projects-landing-page-creator-claude`) · Role: planner | -| **상태** | 승인 (Approved) — v1.5에서 **D-01** 확정(A·B안 기각 / `intl-conf` 폐기 · 3개 카테고리), v1.6에서 **D-06** 확정(레이아웃 컨테이너 3계층 분리). v1.7에서 **§6.1.2 Research Project PageView** 신설 — 신규 미결 **D-07**(🔴 Funder 실데이터 부재)·**D-08**(🟡 프로젝트 집합 범위)은 각 기본값으로 구현을 차단하지 않는다. 잔여 미결 D-02·D-03·D-05는 🟡 등급으로 각 기본값이 적용되어 승인을 보류하지 않는다. v1.9에서 **§8.7 색 토큰 알파 계약**(R-8.21~R-8.24)을 신설하고 **D-09**(Publications 인덱스 라우트)를 확정했다. v1.10에서 개발 팀장(Agy) 이의제기를 반영해 **D-09를 Overview 뷰로 재확정**하고 R-8.25·AC-41을 신설했다. v1.11에서 강조색 교체 커밋(`eaddc4f`)의 대비 붕괴를 규명해 **§8.7에 R-8.26~R-8.28**(강조색 대비 바닥값 · 색값 변경 재측정 의무 · 명암 반전 계약)을 신설하고 **D-10을 확정**(`--cobalt` #4A7CE8 유지 + `--cobalt-dark` #32549E 재조정), **AC-43~AC-46**(대비 게이트 Gate 10 및 그 폴트 인젝션)을 신설했다. 신규 미결 **D-11**(🟡 `text-vermillion` 소형 텍스트 30여 곳)은 현행 유지를 기본값으로 하여 구현을 차단하지 않는다. v1.12에서 개발 팀장(Agy) 이의제기(Job `7f136931`)를 반영해 **D-10의 배지·칩 전경/배경을 재확정**(`bg-cobalt text-ink` 폐기 → `bg-{accent}-dark text-ivory`)하고 **R-8.29**(반전 토큰 쌍의 `dark:` 불필요 원칙)·**AC-47**(팔레트 외 색 상한)을 신설했다 | +| **상태** | 승인 (Approved) — v1.5에서 **D-01** 확정(A·B안 기각 / `intl-conf` 폐기 · 3개 카테고리), v1.6에서 **D-06** 확정(레이아웃 컨테이너 3계층 분리). v1.7에서 **§6.1.2 Research Project PageView** 신설 — 신규 미결 **D-07**(🔴 Funder 실데이터 부재)·**D-08**(🟡 프로젝트 집합 범위)은 각 기본값으로 구현을 차단하지 않는다. 잔여 미결 D-02·D-03·D-05는 🟡 등급으로 각 기본값이 적용되어 승인을 보류하지 않는다. v1.9에서 **§8.7 색 토큰 알파 계약**(R-8.21~R-8.24)을 신설하고 **D-09**(Publications 인덱스 라우트)를 확정했다. v1.10에서 개발 팀장(Agy) 이의제기를 반영해 **D-09를 Overview 뷰로 재확정**하고 R-8.25·AC-41을 신설했다. v1.11에서 강조색 교체 커밋(`eaddc4f`)의 대비 붕괴를 규명해 **§8.7에 R-8.26~R-8.28**(강조색 대비 바닥값 · 색값 변경 재측정 의무 · 명암 반전 계약)을 신설하고 **D-10을 확정**(`--cobalt` #4A7CE8 유지 + `--cobalt-dark` #32549E 재조정), **AC-43~AC-46**(대비 게이트 Gate 10 및 그 폴트 인젝션)을 신설했다. 신규 미결 **D-11**(🟡 `text-vermillion` 소형 텍스트 30여 곳)은 현행 유지를 기본값으로 하여 구현을 차단하지 않는다. v1.12에서 개발 팀장(Agy) 이의제기(Job `7f136931`)를 반영해 **D-10의 배지·칩 전경/배경을 재확정**(`bg-cobalt text-ink` 폐기 → `bg-{accent}-dark text-ivory`)하고 **R-8.29**(반전 토큰 쌍의 `dark:` 불필요 원칙)·**AC-47**(팔레트 외 색 상한)을 신설했다. v1.13에서 Primary #4E77FF 전면 적용 커밋군(`ca4a7ee`~`082d71e`)을 검증해 **Gate 0~10 전량 통과 상태에서 AA 미달 6건·통일성 결함 9건**을 실측 확정하고, 게이트 범위 결함 3종에 대해 **R-8.30~R-8.32**(비텍스트 UI 대비 · 역할 단위 색 통일 · 게이트 면제 형식 제한)와 **AC-48~AC-50**(Gate 11 · 폴트 인젝션 F1~F9 · `docs/DESIGN.md` 동기화)을 신설했다. **§8.1을 실제 토큰값으로 동기화**하고 **D-10 확정값을 #345AD2로 개정**했다. 신규 미결 **D-12**(🔴 Primary 적용의 판정 기준 및 히어로 `Orchestration` 시맨틱 규약)는 **A안+B안 병행**을 기본값으로 하여 구현을 차단하지 않으며, **D-13**(🟡 `--vermillion` 반전 1.25)은 현행 유지 + 화이트리스트 등재를 기본값으로 한다. v1.14에서 개발 팀장(Agy) 이의제기(Job `4962a667`)를 반영해 **R-8.33**(토큰 등급 불변식)을 신설하고 **R-8.29를 강화**(강조색 `dark:` 변형 금지 · 현행 위반 38건)했으며, 다크 테마 `bg-paper` 소형 텍스트 **8곳의 AA 미달(4.37)** 과 **G-7**(AC-44 정규식이 다크 절반을 설계상 면제)을 확정해 **AC-51**을 신설했다. 신규 미결 **D-14**(🔴 `--cobalt` 반전 1.00)는 **A안(브랜드 고정 예외)** 을 기본값으로 하되 규격 완화를 포함하므로 **cline·GM 심사 전에는 집행하지 않는다** | | **대상 독자** | General Manager, Developer Team Leader(Agy), Reviewer Team Leader(Cline), 지도교수 | | **선행 문서** | [`README.md`](./README.md), [`.agents/MULTI_AGENT_RULES.md`](./.agents/MULTI_AGENT_RULES.md), [`refer_landing_page/docs/DESIGN.md`](./refer_landing_page/docs/DESIGN.md) | | **적용 범위** | `refer_landing_page/` (Next.js 14 App Router 애플리케이션) 전체 | @@ -414,9 +414,20 @@ interface ResearchProject { | `ink` / `ink-soft` / `ink-mute` | `#0A0A0A` / `#262420` / `#6B655B` | 본문·괘선 | | `ivory` / `paper` / `line` | `#F5F1E8` / `#ECE6D6` / `#D8D1C0` | 종이 배경 / 인셋 / 헤어라인 | | `vermillion` / `vermillion-dark` | `#D9342B` / `#A8231C` | 강조 (Hot) — **최초 커밋 이래 불변** | -| `cobalt` / `cobalt-dark` | `#4A7CE8` / `#32549E` *(v1.11 갱신)* | 강조 (Cool) | +| `cobalt` / `cobalt-dark` | `#4E77FF` / `#345AD2` *(v1.13 갱신)* | 강조 (Cool) — Primary | + +**실측 대비 (v1.13 기준선 · WCAG 2.1 재계산)** + +| 토큰 | `ivory`(L) | `paper`(L) | `ivory`(D) | `paper`(D) | 라이트↔다크 반전 대비 | +| :--- | ---: | ---: | ---: | ---: | ---: | +| `cobalt` #4E77FF | 3.45 | 3.12 | 4.82 | 4.37 | **1.00 ❌ (R-8.28 위반)** | +| `cobalt-dark` #345AD2 | 5.26 | **4.76** | 6.57 | 5.96 | 2.08 ✅ | +| `vermillion` #D9342B | 4.16 | 3.77 | 5.01 | 4.54 | **1.25 ❌ (→ D-13)** | +| `vermillion-dark` #A8231C | 6.38 | 5.77 | 6.72 | 6.09 | 2.58 ✅ | > **v1.11 갱신 근거**: 커밋 `eaddc4f`가 `cobalt`를 `#1B3A8A` → `#4A7CE8`, `cobalt-dark`를 `#122863` → `#3462CC`로 변경했다. `#4A7CE8`은 사용자 지정 값이므로 유지하되, `cobalt-dark`는 `paper` 배경에서 4.48:1로 미달하므로 **D-10 결정에 따라 `#32549E`(paper 5.82:1)로 재조정**한다. `vermillion`(#D9342B)은 변경된 적이 없다 — `eaddc4f`의 커밋 메시지 `…and secondary to #D9342B`는 현상 유지의 서술이다(→ §12.1 D-10 상세). **v1.12**: 두 강조색의 `-dark` 변형(`#A8231C` / `#32549E`)은 소형 텍스트 전경뿐 아니라 **`text-[0.65rem]` 상태 칩의 배경**으로도 사용된다 — `ivory` 전경만으로 6.38~6.43(라이트) / 6.57~6.72(다크)를 확보한다(→ R-8.26 · R-8.29 · §12.1 D-10 보론). +> +> **v1.13 갱신 근거**: 커밋 `ca4a7ee`·`8db16e4`가 `cobalt`를 `#4A7CE8` → **`#4E77FF`**, `cobalt-dark`를 D-10 확정값 `#32549E`가 아닌 **`#345AD2`** 로 설정했다. `#4E77FF`는 사용자 지정 Primary이므로 유지하며, `#345AD2`도 `paper` **4.76**으로 R-8.26 바닥값을 충족하므로 **D-10 확정값을 `#345AD2`로 개정**한다(단 여유가 0.26뿐이라 §12.2 R-4로 등재). 다만 **`--cobalt`의 반전 대비가 1.00으로 R-8.28을 다시 위반**하며 — 이는 v1.11에서 D-10의 근본 원인으로 규명한 실패 유형의 재발이다 — AC-45 게이트가 `-dark` 2개 토큰만 검사하도록 구현되어 **검출하지 못했다**(→ R-8.28 개정 · AC-45 개정 · §12.1 D-12 상세). 4개 색 변경 커밋 **전부 본문이 비어 있어 R-8.1·R-8.27의 대비 재산정표 첨부 의무가 4회 연속 미이행**이다. **R-8.1** 신규 색 토큰 추가 금지. 색상 값 변경 시 `tailwind.config.ts`와 `app/globals.css`의 `:root` CSS 변수를 **반드시 함께** 수정하며, **R-8.26~R-8.28의 대비·반전 제약을 재산정해 첨부**한다. **R-8.2** `brand` / `accent` 별칭은 레거시 호환 전용이며 신규 코드에서 사용 금지. @@ -429,6 +440,7 @@ interface ResearchProject { ### 8.3 강조색 시맨틱 계약 **R-8.5** `vermillion` = Agent Engineering / Orchestration(홀수 항목), `cobalt` = MCP / A2A Protocol(짝수 항목). 목록 렌더 시 인덱스 기반 교차 배정을 따른다. +- **[v1.13 · 적용 범위 명시]** 본 계약은 `docs/DESIGN.md` §2 "의미 있는 색(Semantic accent pairing)"의 정본 서술과 **동일한 내용**이며, 목록 교차 배정뿐 아니라 **단일 강조 표면(히어로 강조어·섹션 키커 등)에도 적용되는지**는 확정되지 않았다. 커밋 `2441f35`가 히어로의 `Orchestration` 강조어를 vermillion → cobalt로 변경해 **같은 페이지 안에서 규약이 둘로 갈린 상태**이므로 **D-12로 이관**한다. 어느 쪽으로 확정하든 **코드와 `docs/DESIGN.md`가 같은 값을 말해야 한다**(→ AC-23 · AC-50). ### 8.4 컴포넌트 재사용 @@ -510,11 +522,13 @@ Job `343b5808` 검증에서 본문 좌우 여백·최대 폭 미적용(B1)이, **R-8.26 [필수 · 강조색 대비 바닥값] *(v1.11 신설)*** 강조 토큰(`vermillion`·`cobalt`)의 **DEFAULT 변형은 대형 텍스트(≥24 px, 굵게 ≥18.66 px)·도형·테두리·아이콘 전용**이며 **3:1** 이상을 만족한다. **소형 텍스트에는 `-dark` 변형만 사용**하고, `-dark`는 `ivory`·`paper` **양 배경에서 4.5:1 이상**이어야 한다. - `paper`(#ECE6D6)가 `ivory`(#F5F1E8)보다 어두워 **항상 더 엄격한 제약**이므로 바닥값 산정은 `paper` 기준으로 한다. 실측 차이는 약 0.3~0.5 이며, `ivory`만 보고 통과 판정하면 `bg-paper` 카드 내부에서 미달한다. +- **[v1.14 개정 · 판정 격자]** 바닥값 판정은 **{라이트, 다크} × {`ivory`, `paper`} 4개 셀 전부**에서 수행한다. **`paper` 기준 산정 원칙은 다크 테마에도 동일하게 적용된다** — 다크 지면 `paper`(`30 28 26`)도 `ivory`(`18 18 18`)보다 밝아 더 엄격하다. v1.12가 지시한 소형 텍스트 라우팅 `text-cobalt-dark dark:text-cobalt`는 **라이트 절반만 `-dark`로 보내고 다크 절반은 DEFAULT로 되돌려**, `bg-paper` 카드 내부 **8곳이 다크 테마에서 4.37로 미달**한다(→ AC-51). 이는 본 규칙을 **한쪽 테마에만 적용한 계획 오류**이며, v1.11 §6.5의 일관성 결함과 같은 형태다. - 실측 근거: `--cobalt: #4A7CE8`은 `ivory` 3.49 / `paper` 3.16으로 **대형 텍스트 기준(3:1)은 충족하나 소형 텍스트 기준은 미달**한다. 반면 `--cobalt-dark: #32549E`는 6.43 / 5.82로 양 기준을 충족하며, `--vermillion-dark: #A8231C`(6.38 / 5.77)와 **동일 등급**이 되어 두 강조색의 `-dark` 슬롯이 대칭을 이룬다. - **[v1.12 추가 · 배지·칩 라우팅]** 강조색을 **배경**으로 쓰는 **비인터랙티브 상태 칩**(`text-[0.65rem]` 등급)은 **`bg-{accent}-dark` + `text-ivory`** 를 사용한다. DEFAULT 배경 위에서는 팔레트 내 전경 중 통과 후보가 **0~1개뿐**이라 설계 여유가 없다 — 실측상 `bg-cobalt`(#4A7CE8) 위 4개 후보(`ivory` 3.49 · `white` 3.93 · `ink-soft` 3.94 · `ink` 5.03) 중 통과는 `ink` **1개뿐**이고, `bg-vermillion`(#D9342B) 위 `ivory`는 **4.16으로 미달**한다. `-dark` 배경은 `ivory` 전경만으로 **6.38~6.43(라이트) / 6.57~6.72(다크)** 를 확보한다. - **[v1.12 추가 · 짝 칩 등급 일치]** 같은 컴포넌트에서 **짝을 이루는 강조색 칩은 동일 변형 등급**을 사용한다. 한쪽만 `-dark`로 내리면 두 칩의 상대휘도 대비가 **1.19 → 1.54로 악화**된다(실측: `vermillion` L=0.1738 ↔ `cobalt-dark` L=0.0949). 양쪽을 `-dark`로 통일하면 **1.01**로 균형이 잡힌다(`vermillion-dark` L=0.0961 ↔ `cobalt-dark` L=0.0949) — 두 강조색의 `-dark` 변형이 접근성 등급뿐 아니라 **휘도까지 대칭**이기 때문이다. - **인터랙티브 내비·토글 요소는 예외**로 DEFAULT 배경 + `text-white dark:text-ivory`(4.69 / 5.01)를 유지한다. 근거는 §12.1 D-10 상세(부류 A/B 구분) 참조. -- 자동 검증: **AC-42 · AC-43 · AC-44**. +- **[v1.13 개정 · `text-white`의 적용 조건]** 위 예외는 **배경이 DEFAULT 변형일 때에 한정**한다. **`-dark` 배경 위 전경은 `ivory` 단독을 정본**으로 하며 `text-white`·`dark:` 변형을 붙이지 않는다 — 실측 `bg-cobalt-dark` 위 `ivory`는 라이트 **5.26** / 다크 **6.57**로 양 테마를 통과하므로 팔레트 외 색이 불필요하다(→ R-8.29). 커밋 `2441f35`가 `Header.tsx:69,129`·`CategoryNav.tsx:22`의 배경을 `bg-vermillion` → `bg-cobalt-dark`로 바꾸면서 **v1.12가 인정했던 `text-white`의 불가피성이 소멸**했다. +- 자동 검증: **AC-42 · AC-43 · AC-44 · AC-47**. **R-8.27 [필수 · 색값 변경 시 재측정 의무] *(v1.11 신설)*** `--*-rgb` 값을 변경하는 모든 커밋은 **해당 토큰이 참여하는 전 전경/배경 조합의 대비를 재산정**하고 그 표를 커밋 메시지 또는 리뷰 리포트에 첨부한다. - `docs/DESIGN.md`의 강조색 교체 안내(커스터마이즈 훅)에 **이 제약을 명문화**한다. 현행 안내는 "강조색 2개와 `-dark` 변형만 교체하면 됩니다"라고 **교체 방법만** 적고 **지켜야 할 대비 제약을 적지 않아**, 안내를 그대로 따른 커밋 `eaddc4f`가 라이트 테마 대비를 9.23 → 3.49로 붕괴시켰다. 문서가 사고의 직접 원인이므로 문서 교정이 재발 방지의 일부다. @@ -523,12 +537,42 @@ Job `343b5808` 검증에서 본문 좌우 여백·최대 폭 미적용(B1)이, **R-8.28 [필수 · 명암 반전 계약] *(v1.11 신설)*** `html.dark`에서 반전되는 모든 토큰은 **라이트 값과 다크 값의 상대휘도가 유의미하게 달라야** 한다 — 두 값 사이의 대비가 **2.0 이상**이어야 한다. - 근거(실측): 변경 전 `cobalt`는 라이트 `L=0.0509`(#1B3A8A) ↔ 다크 `L=0.2199`(#4D77FF)로 대비 **3.13**이었으나, `eaddc4f` 이후 라이트 `L=0.2170`(#4A7CE8) ↔ 다크 `L=0.2199`로 대비 **1.01**이 되었다. 즉 **라이트 테마가 다크 테마용 밝기를 그대로 반입**했고, 이것이 R-8.26 미달의 직접 원인이다. - 한 토큰만 반전 계약에서 이탈하면 그 시점에는 반대 테마가 우연히 무사할 수 있으나, **반대 테마 값을 조정하는 순간 양 테마가 동시에 무너진다.** +- **[v1.13 개정 · 검사 범위]** 검사 대상은 **`:root`와 `html.dark` 양쪽에 정의된 전 토큰**이다(현행 10종). 일부 토큰만 검사하는 구현은 본 규칙을 충족하지 않는다 — 현행 게이트는 `cobalt-dark`·`vermillion-dark` **2종만** 검사해 **`--cobalt`의 반전 대비 1.00을 검출하지 못했다**. `--vermillion`(1.25)도 미달이나 최초 커밋 이래의 상태이므로 **D-13**으로 분리한다. - 자동 검증: **AC-45**. **R-8.29 [필수 · 반전 토큰 쌍의 `dark:` 불필요 원칙] *(v1.12 신설)*** 전경과 배경이 **모두 반전 토큰**(`--*-rgb`로 정의되어 `html.dark`에서 값이 바뀌는 토큰)이면 **`dark:` 변형 없이 양 테마가 성립해야 한다.** 어떤 조합에 `dark:` 변형이 필요하다면 그것은 **반전하지 않는 색(`white`·리터럴 hex 등)이 섞였다는 신호**이므로, 팔레트 외 색을 제거할 수 있는지 **먼저 검토**한다. - 실측 대조: `bg-cobalt-dark text-ivory`는 라이트 **6.43** / 다크 **6.57**로 `dark:` 없이 통과한다. 반면 `bg-cobalt text-ink`는 다크에서 `--ink-rgb`가 `245 241 232`로 반전되어 **3.49로 미달**하므로 `dark:text-ivory`를 수동으로 덧대야 한다 — **반전 계약을 손으로 우회하는 구조**이며 R-8.28의 취지에 역행한다. - `white`가 불가피한 경우(`bg-vermillion` 위 `ivory`가 4.16으로 미달하는 인터랙티브 요소)는 **AC-47 화이트리스트**로 상한을 관리한다. 화이트리스트는 상한이지 허가가 아니다 — 신규 사용처는 먼저 `-dark` 배경으로 대체 가능한지 검토한다. -- 자동 검증: **AC-47**. +- **[v1.14 강화 · 강조색 `dark:` 금지]** **강조색(`cobalt`·`vermillion` 및 각 `-dark`)에는 `dark:` 변형을 사용하지 않는다.** 반전 토큰 위에 `dark:`를 덧대는 것은 **반전 계약을 손으로 무력화**하는 행위이며, 실제로 `text-cobalt-dark dark:text-cobalt`는 다크 절반을 DEFAULT로 되돌려 **`bg-paper` 위 4.37**을 만든다. `-dark` 단독은 4개 셀 전부(5.26 / 4.76 / 6.57 / 5.96)를 통과한다. +- 세 가지 정본 패턴만 사용한다 — ⓐ 대형 텍스트(≥24 px)·도형·테두리·아이콘·SVG: **`text-cobalt` / `bg-cobalt` / `border-cobalt`**(3.12~4.82, 바닥값 3.0), ⓑ 소형 텍스트: **`text-cobalt-dark`**(4.76~6.57, 바닥값 4.5), ⓒ 강조 배경: **`bg-cobalt-dark text-ivory`**(5.26 / 6.57). **세 패턴 모두 `dark:` 변형이 없다.** +- 현행 위반 **38건**(`dark:text-cobalt` 28 · `dark:bg-cobalt` 6 · `dark:hover:border-cobalt` 2 · `dark:hover:text-cobalt` 1 · `dark:group-hover:text-cobalt` 1) 전량이 제거 대상이다. +- 자동 검증: **AC-47 · AC-48(C11-9) · AC-51**. + +**R-8.30 [필수 · 비텍스트 UI 대비 계약] *(v1.13 신설)*** 테두리·포커스 링·아이콘·상태 도형 등 **비텍스트 UI 구성요소**(WCAG 2.1 §1.4.11)는 인접색 대비 **3:1** 이상을 만족한다. +- **슬래시 알파 수식자를 사용한 색은 배경과 합성한 실효색으로 산정**한다. 알파는 대비를 조용히 갉아먹으며 토큰 값만으로는 판정할 수 없다 — 실측: `focus:ring-cobalt/50`은 `cobalt` 자체가 3.45임에도 `ivory` 위 합성 후 **1.80**(다크 2.07), `hover:border-cobalt/60`은 `paper` 위 **1.95**(다크 2.38)로 **양쪽 다 미달**한다. +- 이는 §12.1 D-09(알파 계약 붕괴)·§12.1 D-10(반전 계약 이탈)에 이은 **"알파·토큰 조합이 무성으로 대비를 무너뜨리는" 유형의 세 번째 발현**이다. 강조색에 알파 수식자를 붙이는 것은 **원칙적으로 지양**하고, 필요하면 `-dark` 변형을 불투명하게 사용한다. +- 통과 확인된 사용처(회귀 방어 기준선): `hover:border-cobalt` 3.12 / `hover:border-cobalt-dark` 4.76 / `hover:border-vermillion` 3.77 / `ring-vermillion` 4.16 / 불릿 `bg-cobalt` 3.45 / 히어로 SVG `var(--cobalt)` 3.45 · `var(--vermillion)` 4.16 (전부 `paper` 또는 `ivory` 기준 라이트값). +- 자동 검증: **AC-48**(Gate 11 · C11-5). + +**R-8.31 [필수 · 역할 단위 색 통일 계약] *(v1.13 신설)*** **동일한 클래스 시그니처를 갖는 요소는 단일 색 패턴을 사용한다.** 역할은 파일·행이 아니라 시그니처로 식별한다. +- 판정 대상 시그니처(최소): ⓐ 섹션 장식 괘선 `h-px w-8 bg-*`, ⓑ 섹션 키커 `font-mono text-xs … uppercase tracking-widest … font-bold`, ⓒ 강조 배경 배지·칩의 전경, ⓓ 카드 `hover:border-*`, ⓔ 포커스 인디케이터 `ring-*`. +- 판정 기준은 **"어떤 색인가"가 아니라 "색 패턴이 하나뿐인가"** 이다. 따라서 색 선택 결정(D-12)이 확정되기 전에도 게이트를 구현·운용할 수 있고, 결정이 바뀌어도 게이트는 수정할 필요가 없다. +- 실측 위반: ⓐ `bg-cobalt-dark dark:bg-cobalt` 6곳 ↔ `bg-vermillion` 1곳(`DirectionsBlock.tsx:7`), ⓑ `text-cobalt-dark dark:text-cobalt` 11곳 ↔ `text-vermillion` 1곳(`DirectionsBlock.tsx:8`), ⓒ `text-white dark:text-ivory` 6곳 ↔ `text-ivory` 4곳, ⓓ 4종, ⓔ 2종. +- **같은 데이터가 서로 다른 색으로 렌더되는 것도 위반**이다 — 지도교수 이메일 `sjkoh@knu.ac.kr` 한 값이 `members:54`(5.26) · `DirectionsBlock:43`(4.16) · `Footer:53`(paper 위 hover 3.77)에서 **3색 3대비**로 나타난다. +- 예외는 **화이트리스트 등재**(R-8.32 형식)로만 허용한다. +- 자동 검증: **AC-48**(Gate 11 · C11-1~C11-4). + +**R-8.32 [필수 · 게이트 면제 형식 제한] *(v1.13 신설)*** 자동 게이트의 예외는 **`(파일, 행, 사유)` 3-튜플 등재로만** 허용하며, **라인 부분문자열 면제(`if "…" in line: continue`)를 금지**한다. 등재 항목이 실제 소스에 존재하지 않으면(고아 항목) 게이트는 **실패**해야 한다. +- 근거(실측): `run_e2e_tests.py`의 AC-44 구현은 면제 조항에 `"text-vermillion" in line`을 두었는데, 위반 판정 정규식이 `text-(cobalt|vermillion)`이므로 **vermillion으로 매치된 라인은 예외 없이 그 문자열을 포함**한다 — 즉 **AC-44의 vermillion 절반이 영구적으로 발화하지 않는다.** 실제 소스 4개 라인(`lectures:50`·`members:114`·`publications:72`·`DirectionsBlock:8`)과 회귀 주입 2건을 동일 로직에 투입해 **전부 면제됨**을 재현했다. +- 나아가 `"text-3xl"`·`"Pillar #"` 등의 면제도 **라인 전체 부분문자열 검사**라, 삼항식 한 줄에 두 색이 섞이면 **cobalt 검사까지 함께 무력화**된다 — 회귀가 가장 숨기 쉬운 형태가 정확히 그 형태다. +- 이는 **N6**(Gate 8 C1/C2 공허 단정, 10라운드 미해소)과 **동일 유형**이다. 개별 수정이 아니라 **형식 차원의 금지**로 대응한다. +- 자동 검증: **AC-48 · AC-49**(F2 · F9). + +**R-8.33 [필수 · 토큰 등급 불변식] *(v1.14 신설)*** 각 테마에서 **`-dark` 변형은 해당 테마의 지면 배경(`ivory`·`paper`) 대비가 DEFAULT보다 커야** 한다. DEFAULT 토큰의 값을 조정할 때는 **같은 테마의 `-dark` 값과의 관계를 반드시 함께 검토**한다. +- **절대 휘도 순서가 테마 간에 뒤집히는 것은 정상 동작이며 위반이 아니다.** `-dark`는 "절대적으로 어두운 색"이 아니라 **"지면 대비가 더 깊은 변형"** 이므로, 다크 지면에서 대비를 깊게 하려면 더 밝아진다. 실측: 라이트 `cobalt` L=0.2203 > `cobalt-dark` L=0.1270 이지만 다크에서는 `cobalt` L=0.2199 < `cobalt-dark` L=0.3184이며, vermillion 쌍도 동일하게 뒤집힌다. **판정 기준을 절대 휘도로 두면 정상 상태를 위반으로 오판한다.** +- 현행 실측(8개 셀 전부 충족): 라이트 `ivory` 3.45→5.26 · 라이트 `paper` 3.12→4.76 · 다크 `ivory` 4.82→6.57 · 다크 `paper` 4.37→5.96 (cobalt), 라이트 `ivory` 4.16→6.38 · 다크 `ivory` 5.01→6.72 (vermillion). +- 근거: 개발 팀장(Agy) 이의제기(Job `4962a667`)가 **다크 DEFAULT만 단독 상향하면 계층이 무너짐**을 지적했고 실측으로 확인했다 — 다크 DEFAULT를 L≈0.52로 올리면 다크 `paper` 대비가 **9.2**가 되어 `-dark`(5.96)를 역전한다. +- 자동 검증: **AC-43**(정책 표에 등급 관계를 포함). --- @@ -635,18 +679,51 @@ Job `343b5808` 검증에서 본문 좌우 여백·최대 폭 미적용(B1)이, - [ ] AC-41 *(v1.10 신설 · R-8.25)* 산출 정적 HTML 전 라우트의 **`
` 내부 콘텐츠를 정규화 해시**해 **동일 해시가 2건 이상 존재하지 않음**을 자동 게이트로 확인한다. `canonical`이 명시된 예외 쌍만 화이트리스트로 허용한다 - [ ] AC-42 *(v1.10 신설 · v1.11 개정 · R-9.6 · AC-38 확장)* **vermillion 배경 위 텍스트 전량**이 라이트·다크 양 테마에서 4.5:1 이상임을 확인한다. **"전량"은 Header·`CategoryNav`에 한정되지 않으며, `group-open:`·`hover:` 등 상태 변형으로 적용되는 배경도 포함한다.** 검증 대상은 **두 부류로 나누어 각각의 기대 패턴과 기대 대비를 판정**한다*(v1.12 개정)*. - **부류 A — `text-[0.65rem]` 비인터랙티브 상태 칩**: `app/standardization/page.tsx:40`·`:88` → **`bg-vermillion-dark text-ivory`**(라이트 **6.38** / 다크 **6.72**, `dark:` 변형 없음). R-8.26 배지·칩 라우팅 조항 적용 - - **부류 B — 인터랙티브 내비·토글**: `components/Header.tsx:69,129`(교정 완료), `CategoryNav.tsx:22`(교정 완료), `app/lectures/page.tsx:89`·`app/members/page.tsx:177`(미교정) → **`text-white dark:text-ivory`**(라이트 **4.69** / 다크 **5.01**). Header·`CategoryNav` 2곳은 `02247a0`에서 교정되어 재작업 대상이 아니다 + - **부류 B — 인터랙티브 내비·토글**: `components/Header.tsx:69,129`, `CategoryNav.tsx:22`, `app/lectures/page.tsx:89`, `app/members/page.tsx:177` → **`text-white dark:text-ivory`**(라이트 **4.69** / 다크 **5.01**) + - **[v1.13 개정 · 부류 B 재산정]** ⓐ `Header.tsx:69,129`·`CategoryNav.tsx:22`는 `2441f35`에서 **배경이 `bg-vermillion` → `bg-cobalt-dark`로 바뀌어** `text-white`의 불가피성이 소멸했다 — R-8.26 v1.13 조항에 따라 **`text-ivory` 단독**(라이트 5.26 / 다크 6.57)으로 정정한다. ⓑ **`app/lectures/page.tsx:89`는 여전히 `group-open:text-ivory`(4.16)로 미교정**이며, 동일 관용구인 `members/page.tsx:177`만 교정되어 **한 쌍이 갈라져 있다**. ⓒ **`app/not-found.tsx:22`를 신규 등재** — `text-ivory hover:bg-vermillion`으로 hover 시 **4.16**이며 v1.12까지의 어떤 목록에도 없었다. 권고 조치는 `hover:bg-vermillion-dark`(→ 6.38)로, `white` 없이 해소된다 - *v1.10 기재 정정*: `text-white` on `#D9342B`의 실측은 **4.69:1**이다(직전 수렴 리포트의 4.58:1은 오기 — 판정은 동일하게 통과) - *현행 미교정 4곳의 실측은 모두 **4.16:1***이며, `lectures:89`·`members:177`은 `group-open:` 상태 변형으로 배경이 적용되어 **육안 리뷰에서 누락되기 쉽다** -- [ ] AC-43 *(v1.11 신설 · R-8.26·R-8.27·R-9.6)* **대비 자동 게이트(Gate 10)** — `app/globals.css`의 `:root`·`html.dark` `--*-rgb` 정의를 파싱해 **양 테마 전 조합의 대비를 계산**하고 정책 표의 바닥값 미만이면 실패한다. 최소 대상: `{ink, ink-soft, ink-mute, vermillion, vermillion-dark, cobalt, cobalt-dark} × {ivory, paper}` 및 `{ink, ivory, white} × {vermillion, vermillion-dark, cobalt, cobalt-dark}`. **`-dark` 변형이 배경으로 쓰이는 경우**(`{ivory, white} × {cobalt-dark, vermillion-dark}`, 양 테마)를 반드시 포함한다 — v1.11 목록은 `-dark`를 전경으로만 다루어 **상태 칩 배경을 검사하지 못했다***(v1.12 개정)*. 정책 표는 스크립트 상단 상수 블록에 두어 규격 변경 시 1곳만 수정되게 한다. *(현행 실측: `cobalt`는 `ivory` 3.49 / `paper` 3.16, `cobalt-dark`는 `paper` 4.48로 **실패해야 한다**)* -- [ ] AC-44 *(v1.11 신설 · R-8.26)* **소형 텍스트 라우팅 게이트** — `app/**`·`components/**`에서 `text-cobalt`·`text-vermillion`(DEFAULT 변형)이 **소형 텍스트 크기 클래스와 동일 요소에 공존하지 않음**을 확인한다. 부모로부터 크기를 상속받아 정적 판정이 불가능한 케이스는 **화이트리스트에 사유와 함께 등재**한다. *(현행 실측: `text-cobalt` 소형 텍스트 사용처 **12건** + `bg-cobalt` 소형 배지 **2건** 미달)* -- [ ] AC-45 *(v1.11 신설 · R-8.28)* **반전 계약 게이트** — `:root`와 `html.dark`의 동일 토큰 쌍에 대해 라이트↔다크 상대휘도 대비가 **2.0 이상**임을 확인한다. *(현행 실측: `cobalt`는 **1.01**로 실패해야 한다)* +- [ ] AC-43 *(v1.11 신설 · v1.12·v1.13 개정 · R-8.26·R-8.27·R-9.6)* **대비 자동 게이트(Gate 10)** — `app/globals.css`의 `:root`·`html.dark` `--*-rgb` 정의를 파싱해 **양 테마 전 조합의 대비를 계산**하고 정책 표의 바닥값 미만이면 실패한다. 최소 대상: `{ink, ink-soft, ink-mute, vermillion, vermillion-dark, cobalt, cobalt-dark} × {ivory, paper}` 및 `{ink, ivory, white} × {vermillion, vermillion-dark, cobalt, cobalt-dark}`. **`-dark` 변형이 배경으로 쓰이는 경우**(`{ivory, white} × {cobalt-dark, vermillion-dark}`, 양 테마)를 반드시 포함한다 — v1.11 목록은 `-dark`를 전경으로만 다루어 **상태 칩 배경을 검사하지 못했다***(v1.12 개정)*. 정책 표는 스크립트 상단 상수 블록에 두어 규격 변경 시 1곳만 수정되게 한다. *(현행 실측: `cobalt`는 `ivory` 3.49 / `paper` 3.16, `cobalt-dark`는 `paper` 4.48로 **실패해야 한다**)* + - **[v1.13 개정 · C10-1]** 현행 구현은 ⓐ 정책 값이 **함수 본문에 흩어져 있어** 상수 블록 요건을 충족하지 않고, ⓑ **토큰 값만 검사하고 소스의 전경/배경 쌍은 보지 않는다** — 따라서 `bg-cobalt-dark text-white`(다크 **2.85**)를 작성해도 통과한다. 검사 대상에 **소스에서 실제로 함께 쓰인 전경/배경 조합**을 추가하고, `text-white`가 전경인 조합을 **양 테마 모두** 계산한다 + - **[v1.14 개정]** ⓐ **DEFAULT 토큰 × {`ivory`,`paper`} × {라이트,다크}** 를 **3:1 바닥값**으로 명시 추가한다 — 이 검사가 **D-14 A안의 안전망 본체**이며, 브랜드 색이 어느 테마에서든 역할 바닥값 아래로 내려가면 즉시 실패해야 한다. ⓑ **R-8.33 등급 관계**(각 테마 지면 대비에서 `-dark` > DEFAULT)를 정책 표에 포함한다 +- [ ] AC-44 *(v1.11 신설 · v1.13 개정 · R-8.26·R-8.32)* **소형 텍스트 라우팅 게이트** — `app/**`·`components/**`에서 `text-cobalt`·`text-vermillion`(DEFAULT 변형)이 **소형 텍스트 크기 클래스와 동일 요소에 공존하지 않음**을 확인한다. 부모로부터 크기를 상속받아 정적 판정이 불가능한 케이스는 **화이트리스트에 사유와 함께 등재**한다. *(현행 실측: `text-cobalt` 소형 텍스트 사용처 **12건** + `bg-cobalt` 소형 배지 **2건** 미달)* + - **[v1.13 개정 · C10-2]** 현행 구현의 **라인 부분문자열 면제 4종(`"text-vermillion"`·`"text-3xl"`·`"Pillar #"`·`"w-1.5 h-1.5"`)을 전량 제거**하고 R-8.32의 `(파일, 행, 사유)` 화이트리스트로 대체한다. 첫 번째 면제 때문에 **AC-44의 vermillion 절반이 구조적으로 발화하지 않음**을 재현 확인했다(→ R-8.32). 제거 후 `text-vermillion` **23건** 중 소형 텍스트 사용처가 검출되어야 하며, 최저값은 `bg-paper` 카드 내부의 `members/page.tsx:114,144` **3.77**이다 + - **[v1.14 개정 · G-7]** 판정 정규식의 **부정 후방탐색 `(? 8)** *(⑤·⑥은 v1.12 신설)*. **6건 모두 실패를 재현하지 못하면 Gate 10을 채택하지 않는다** — 통과만으로는 게이트가 결함을 검출한다는 증명이 되지 않는다 - ⑤는 **기각·교체된 설계를 게이트가 실제로 잡는지** 확인한다. v1.10에서 기각한 D-09 C안을 주입해 AC-41을 검증한 것과 같은 방식이며, **교체된 설계는 반드시 게이트의 검출 대상이 되어야 한다** -- [ ] AC-47 *(v1.12 신설 · R-8.29)* **팔레트 외 색 상한 게이트** — `app/**`·`components/**`에서 `text-white`·`bg-white` 등 **팔레트 외 색 유틸리티의 출현 횟수가 화이트리스트 등재 건수를 초과하지 않음**을 확인한다. +- [ ] AC-47 *(v1.12 신설 · v1.13 개정 · R-8.29)* **팔레트 외 색 상한 게이트** — `app/**`·`components/**`에서 `text-white`·`bg-white` 등 **팔레트 외 색 유틸리티의 출현 횟수가 화이트리스트 등재 건수를 초과하지 않음**을 확인한다. - 화이트리스트(부류 B 한정, 총 **8건**): `components/Header.tsx:69,75,129,136,145`(5) · `CategoryNav.tsx:22`(1) · `lectures/page.tsx:89`(1) · `members/page.tsx:177`(1) - 각 항목에 **사유**(해당 위치에서 `ivory` 전경이 4.16으로 미달)를 함께 기재한다. 화이트리스트는 **상한이지 허가가 아니며**, 신규 사용처는 `-dark` 배경으로 대체 가능한지 먼저 검토한 뒤에만 등재한다 - 근거: `docs/DESIGN.md`는 "토큰만 사용 — 임의 회색·팔레트 밖 hex 금지"를 규정한다. `white`는 Issue 01 팔레트(`ink`/`ivory`/`paper`/`line`/`vermillion`/`cobalt`) 밖의 색으로, `02247a0`에서 **불가피성 때문에** 도입되었다. 상한을 두지 않으면 그 불가피성이 관행으로 굳는다 + - **[v1.13 개정 · C10-4]** 현행 구현은 `content.count("text-white")` **단순 계수**라 **위치를 검증하지 않는다.** 화이트리스트를 `(파일, 행)` 집합으로 두고 **실제 출현 위치 집합과 완전히 일치**할 때만 통과시킨다(초과·고아 양방향 검출, R-8.32). 배경 변경(`bg-vermillion` → `bg-cobalt-dark`)으로 **현행 7건 중 6건이 R-8.29상 제거 대상**이 되었으므로, Phase 3 완료 후 화이트리스트는 **`lectures/page.tsx:89`·`members/page.tsx:177` 2건**으로 축소되어야 한다 — 이 2곳만이 DEFAULT `bg-vermillion` 위(ivory 4.16 미달)에 있다 + +**색 통일성 (v1.13 신설)** +- [ ] AC-48 *(v1.13 신설 · R-8.30·R-8.31·R-8.32)* **색 통일성 게이트(Gate 11)** — 아래 8개 검사를 자동화한다. C11-1~C11-4는 R-8.31, C11-5는 R-8.30, C11-7은 AC-23 회귀 방어에 대응한다. + - **C11-1 괘선 통일** — `h-px w-8 bg-*` 시그니처의 색 클래스가 **2종 이상이면 실패** *(현행: `bg-cobalt-dark dark:bg-cobalt` 6곳 ↔ `bg-vermillion` 1곳 → **실패해야 한다**)* + - **C11-2 키커 통일** — `font-mono text-xs … uppercase tracking-widest … font-bold` 시그니처의 색 클래스가 2종 이상이면 실패 *(현행 11곳 ↔ 1곳 → **실패해야 한다**)* + - **C11-3 강조 배경 전경 통일** — `bg-{accent}-dark` 요소에 `text-white`가 결합되어 있으면 실패(R-8.29) *(현행 6건 → **실패해야 한다**)* + - **C11-4 상태 배경 전경 쌍** — `group-open:bg-*`·`hover:bg-*`로 배경이 바뀌는 요소의 대응 상태 전경과의 대비가 4.5 미만이면 실패 *(현행 `lectures:89` 4.16 · `not-found:22` 4.16 → **실패해야 한다**)* + - **C11-5 비텍스트 UI 3:1** — `border-{accent}*`·`ring-{accent}*`·도형 `bg-{accent}*`·SVG의 `var(--*)` 참조를 수집하고, **슬래시 알파는 배경과 합성한 뒤** 계산해 3.0 미만이면 실패 *(현행 `focus:ring-cobalt/50` **1.80** · `hover:border-cobalt/60` **1.95** → **실패해야 한다**)* + - **C11-6 전역 CSS 조합** — `globals.css`의 `background`/`color` 쌍(`::selection` 등)을 파싱해 4.5 미만이면 실패 *(현행 `::selection`은 `ivory` on `vermillion` **4.16** → **실패해야 한다**)* + - **C11-7 문서 동기화** — `docs/DESIGN.md` §3 색상표의 hex ↔ `globals.css`의 `--*-rgb` 대조, 불일치 시 실패 *(현행 일치 — 회귀 방어용)* + - **C11-8 시맨틱 페어링** — R-8.5의 `vermillion = Orchestration` 대응을 히어로 강조 요소에 대해 확인. **D-12 확정 이후에만 활성화**한다 + - **C11-9 `dark:` 변형 제로** *(v1.14 신설 · R-8.29)* — `app/**`·`components/**`에 **`dark:` + 강조색**(`cobalt`·`vermillion` 및 각 `-dark`) 조합이 **1건이라도 있으면 실패**. 예외는 R-8.32 화이트리스트 등재로만 허용한다(부류 B의 `dark:text-ivory` 등) *(현행 `dark:*-cobalt` **38건** → **실패해야 한다**)* +- [ ] AC-49 *(v1.13 신설 · AC-48 유효성)* **Gate 10·11 폴트 인젝션** — ① F1 `DirectionsBlock:8` 현행 유지 → C11-2 실패, ② F2 `lectures:50`의 `text-xs text-vermillion` 현행 유지 → AC-44 실패(**면제 제거 확인**), ③ F3 다크 `--cobalt-rgb`를 라이트와 동일하게 유지 → AC-45 실패(1.00), ④ F4 `Header:69`에서 `dark:text-ivory` 제거 → AC-43 또는 C11-3 실패(다크 2.85), ⑤ F5 `standardization:89`를 `bg-cobalt text-ivory`로 되돌림 → AC-43 실패(3.45), ⑥ F6 화이트리스트 밖 위치에 `text-white` 1건 추가 → AC-47 실패(**위치 불일치** — 단순 계수로는 통과했을 사례), ⑦ F7 `focus:ring-cobalt/50` 현행 유지 → C11-5 실패(1.80), ⑧ F8 `docs/DESIGN.md` 색상표 hex 1글자 변경 → C11-7 실패, ⑨ F9 실존하지 않는 `(파일, 행)`을 화이트리스트에 등재 → 고아 항목으로 실패, **⑩ F10 `members/page.tsx:108`을 `text-cobalt-dark dark:text-cobalt`로 되돌리면 AC-44 실패(다크 4.37) — 후방탐색 `(? DEFAULT 9.14로 R-8.33 충족). 이의제기 원안의 `#85ACFF`는 반전 **1.73**으로 **R-8.28 미달**이라 미채택하고, `#B0CDFF`의 기재 반전 2.50은 `#345AD2`의 상대휘도를 폐기값 #32549E의 0.0949로 적은 오기에서 파생된 값으로 실제는 **3.68**이다. B안의 비용은 다크 강조색이 **파스텔로 변해 브랜드 색이 다크 테마에서 사라지고** `bg-cobalt-dark` 칩이 대비 12.75의 거의 흰 배경이 되는 것 — **D-12(브랜드 가시성)를 다크 테마에서 악화**시킨다. **A안은 본 계획자가 작성한 R-8.28을 스스로 완화하는 제안이므로 cline·GM의 별도 심사를 요청**하며, 승인 전에는 집행하지 않는다 → R-8.28 · R-8.29 · R-8.33 · AC-43 · AC-45 | #### D-01 상세 @@ -873,6 +953,34 @@ cobalt 칩만 어둡게 내리면 vermillion 칩이 밝은 채로 남아 무게 **시각 변경 고지.** 부류 A의 vermillion 칩 2곳은 배경이 **#D9342B → #A8231C로 실제로 어두워진다.** `#A8231C`는 팔레트에 이미 정의된 `vermillion-dark`이므로 신규 색이 아니며(R-8.1 위반 아님) 대상 면적도 `text-[0.65rem]` 칩 2개로 극히 작다. **GM이 배경 무변경을 선호하면 부류 B 패턴(`bg-vermillion text-white dark:text-ivory`, 4.69)으로 내려도 규격은 충족**되며, 그 경우 위 표의 무게 불균형 1.54가 남는다는 점만 함께 기록한다 — **차단 사유가 아니라 선택지다.** +#### D-12 상세 — 게이트가 녹색인 채로 남은 결함과 브랜드 색의 가시성 *(v1.13)* + +**관측.** `eaddc4f` → `082d71e` 4개 커밋 이후 상태에서 `npm run build`(exit 0 · 13/13 정적 · `ƒ Dynamic` 0건)와 `run_e2e_tests.py` **Gate 0~10 전량**이 통과한다. 그러나 같은 상태에서 **WCAG AA 미달 6건과 통일성 결함 9건**이 실재한다. 특히 `lectures/page.tsx:89`는 **v1.12 AC-42 부류 B에 "미교정"으로 명시 등재된 항목**인데 신설된 대비 게이트가 이를 통과시켰다. + +**원인 — 게이트의 범위 결함 3종.** + +| ID | 결함 | 결과 | +| :--- | :--- | :--- | +| G-1 | AC-44 구현의 면제 조항 `if … or "text-vermillion" in line: continue`. 위반 판정 정규식이 `text-(cobalt\|vermillion)`이므로 **vermillion으로 매치된 라인은 예외 없이 그 문자열을 포함**한다 | **AC-44의 vermillion 절반이 영구 무효.** 실제 소스 4개 라인 + 주입 2건을 동일 로직에 투입해 전부 면제됨을 재현 | +| G-2 | AC-45 구현이 `cobalt-dark`·`vermillion-dark` **2종만** 검사 | **`--cobalt` 반전 대비 1.00 미검출** — D-10 근본 원인의 재발 | +| G-3 | AC-43 구현이 토큰 값만 보고 **소스의 전경/배경 쌍은 보지 않음** | `bg-cobalt-dark text-white`(다크 2.85)를 작성해도 통과 | + +G-1은 **N6**(Gate 8 C1/C2 공허 단정, 10라운드 미해소)과 **동일 유형**이다 — 단정·면제가 구조적으로 발화하지 않는데 출력은 ✅로 찍힌다. 개별 수정이 아니라 형식 차원의 금지(**R-8.32**)로 대응한다. 아울러 §12.1 D-09(알파 계약)·D-10(반전 계약)에 이어 `focus:ring-cobalt/50` **1.80** · `hover:border-cobalt/60` **1.95**가 드러났다 — **알파·토큰 조합이 무성으로 대비를 무너뜨리는 유형의 세 번째 발현**이며 **R-8.30**의 근거다. + +**브랜드 색의 가시성.** 라이트 테마에서 지정 Primary **#4E77FF가 정적으로 칠해지는 표면은 히어로 SVG와 6 px 불릿 2곳뿐**이다. 나머지는 전부 hover·focus 상태이거나 `-dark` **#345AD2**다. + +| 표면 | 색 | 상태 | +| :--- | :--- | :--- | +| 히어로 `HeroComposition` SVG (`var(--cobalt)`) | **#4E77FF** | 정적 | +| Pillar 불릿 `page.tsx:174` `bg-cobalt` (6 px) | **#4E77FF** | 정적 | +| `members:102,132` `hover:border-cobalt` · `ProjectPageView:35,44` | #4E77FF | hover/focus 전용 | +| `ThemeToggle:146` `text-cobalt` | #4E77FF | **다크 테마 전용 렌더** | +| 섹션 괘선·키커·링크·지표·Pillar 라벨(20여 곳) | **#345AD2** | 정적 — 사용자가 "Primary"로 인지하는 색 | + +즉 **지시는 토큰 수준에서 충족되었으나 화면 수준에서는 다른 색이 Primary로 읽힌다.** 접근성을 지키면서 이 간극을 좁히는 유일한 경로가 **B안(대형 표면 확대)** 이다 — `page.tsx:84,92`의 30 px 지표처럼 **3:1만 요구되는 표면**은 #4E77FF로 칠해도 적법하다(실측 3.45). 반대로 `-dark`를 브랜드 색 쪽으로 밝히는 C안은 `paper` 여유가 0.26뿐이라 **D-10이 #3C64BC를 배격한 것과 같은 사유**로 기각한다. + +**시맨틱 규약의 분열.** `docs/DESIGN.md:30`과 R-8.5는 **vermillion = Agent Eng / Orchestration**을 규정한다. `2441f35`가 히어로의 `Orchestration` 강조어를 cobalt로 바꾸었으나, 같은 파일의 PILLARS 교차 배정(`page.tsx:12~48`)은 규약을 유지 중이다 — **한 페이지 안에서 규약이 둘로 갈렸다.** 코드를 되돌리든 문서를 개정하든 무방하나, **둘 중 하나는 반드시 상대에 맞춰야** AC-23이 성립한다. + --- ### 12.2 리스크 @@ -888,6 +996,10 @@ cobalt 칩만 어둡게 내리면 vermillion 칩이 밝은 채로 남아 무게 | R-05 | 잔재 검사(MG-08)가 논문 제목의 도메인 용어까지 오검출 | **실데이터를 잔재로 오인해 삭제** → PR-01 위반 | MG-08 예외 규정을 검사 스크립트에 반영. 검사 범위를 정체성 서술 영역으로 한정 | | R-06 | 문서-코드 불일치 재발 | 후속 작업자 혼선 | R-9.19. 미완 영역은 문서에 미완으로 표기 | | R-07 | P2(Header 수정)와 P3~P5 병렬 진행 시 충돌 | 머지 충돌 | §11.1 주석대로 P2 선행 완료 | +| R-10 *(v1.13 신설)* | 색값 교체가 **대비 재산정표 없이** 5회 연속 진행됨(`eaddc4f`·`ca4a7ee`·`8db16e4`·`2441f35`·`082d71e` 전부 커밋 본문 없음) | 관행화 시 무성 실패가 반복 발생 | R-8.1·R-8.27 이행 강제 + **AC-50**으로 `docs/DESIGN.md` 커스터마이즈 훅 교정. 문서가 원인으로 규명된 지 2라운드째 미교정 | +| R-11 *(v1.13 신설)* | **게이트 통과가 결함 부재의 근거로 오용될 위험** — Gate 0~10 전량 ✅인 상태에서 AA 미달 6건이 실재했다 | 잘못된 PASS 확정 | 폴트 인젝션 없는 게이트는 채택하지 않는다(**AC-46 · AC-49**). 신설 게이트는 **현행 코드 자체가 주입 상태**인 항목(F1·F2·F3·F7)으로 즉시 실효성을 확인한다 | +| R-12 *(v1.13 신설)* | `--cobalt-dark` #345AD2의 `paper` 여유가 **0.26**뿐 | 후속 변경 1회로 재미달 | 추가 상향 금지(D-10 v1.13 개정). 변경 시 R-8.27 재산정 필수 | +| R-13 *(v1.13 신설)* | Phase 3 색 통일 작업이 "에디토리얼 디자인 시스템 유지" 목표와 충돌할 소지 | 시각적 대변경 | 단일화 대상을 **동일 역할 시그니처 내부**로 한정(R-8.31). 색 선택 자체는 **D-12**로 이관 | --- @@ -935,3 +1047,5 @@ cobalt 칩만 어둡게 내리면 vermillion 칩이 밝은 채로 남아 무게 | 1.10 | 2026-07-31 | claude (planner) | 개발 팀장(Agy) 기술 이의제기(Job `22b7a309`) 반영. **D-09 재확정** — v1.9의 C안(첫 카테고리 본문 재렌더)이 **동일 DOM 정적 HTML 2본**을 만든다는 지적이 타당하여 **A안(Overview 뷰)** 으로 교체하고, `All` 탭 재도입(D안)은 commit `22a31ff` 결정 역행·P-07 충돌로 기각. **R-8.25 신설**(라우트 간 콘텐츠 중복 금지 + canonical 예외 절차), **AC-41 신설**(`
` 정규화 해시 중복 0건), **IA-03 재개정**. 이의제기의 `isActive` 논거는 정정 — `pathname.startsWith(\`${href}/\`)` 일반 규칙이 하위 카테고리를 이미 포괄하므로 모호성이 없음을 코드로 확인. 아울러 별건으로 `CategoryNav` 활성 탭(`bg-vermillion text-ivory`)이 **라이트 테마 4.16:1로 R-9.6 미달**임을 발견해 **AC-42 신설**. Job `6a6094c6` | | 1.11 | 2026-07-31 | claude (planner) | 강조색 교체 커밋 `eaddc4f` 검증 및 리뷰 수렴. **라이트 테마 cobalt 대비가 9.23:1 → 3.49:1(ivory) / 8.35 → 3.16(paper)로 붕괴**하여 소형 텍스트 **14개 사용처**가 AA 미달임을 WCAG 공식 재계산으로 확정. 근본 원인은 **명암 반전 계약 이탈**(라이트↔다크 상대휘도 대비 3.13 → **1.01**)이며, `run_e2e_tests.py`에 대비 검사가 **0건**이라 게이트 0~9와 빌드가 전부 통과한 채로 통과했다 — §12.1 알파 계약 사고와 동일한 무성 실패 유형의 **두 번째 발현**. **R-8.26~R-8.28 신설**(강조색 대비 바닥값 · 색값 변경 시 재측정 의무 · 명암 반전 계약 ≥2.0), **AC-43~AC-46 신설**(대비 게이트 Gate 10 · 소형 텍스트 라우팅 · 반전 계약 · 폴트 인젝션 4종). **D-10 확정** — `--cobalt`는 사용자 지정 #4A7CE8을 **유지**하고 `--cobalt-dark`만 #3462CC → **#32549E**(paper 4.48 → 5.82)로 재조정해 소형 텍스트를 `-dark`로 라우팅(A·B·D안 기각). **D-11 신설**(🟡 `text-vermillion` 소형 텍스트 30여 곳, 기본값 현행 유지). **AC-42 개정** — 직전 수렴에서 통과 판정되었으나 `standardization:40,88`·`lectures:89`·`members:177` **4곳이 4.16:1로 미교정** 잔존함을 확인하고 대상을 명시 목록화, `text-white` on vermillion 수치를 4.58 → **4.69**로 정정. §8.1 색상 토큰표를 실제 값과 동기화하고, **Secondary #D9342B는 최초 커밋 이래 무변경(no-op)** 임을 계보로 확인해 기록. Job `5c2137c6` | | 1.12 | 2026-07-31 | claude (planner) | 개발 팀장(Agy) 기술 이의제기(Job `7f136931`) 반영. **D-10 배지·칩 결정 재확정** — v1.11의 `bg-cobalt text-ink dark:text-ivory`(5.03 / 4.82)는 채택안 C의 원칙(작은 요소는 `-dark` 라우팅)을 **소형 텍스트 12곳에만 적용하고 동일 크기 등급의 상태 칩 2곳에는 적용하지 않은 일관성 결함**이었음을 인정하고 폐기, **`bg-{accent}-dark text-ivory`** 로 교체(6.38~6.43 / 6.57~6.72). 이의제기의 권장 전경 `text-white dark:text-ivory`(7.25)는 **미채택** — `-dark` 배경에서는 `ivory`만으로 양 테마가 통과해 **팔레트 외 색 `white`와 `dark:` 변형이 모두 불필요**하다(**R-8.29 신설**). 아울러 권장안을 그대로 적용하면 `standardization:87-89` 삼항식의 나란한 두 칩 상대휘도 대비가 **1.19 → 1.54로 악화**됨을 실측해, vermillion 칩도 `-dark`로 통일하여 **1.01** 균형을 달성(**R-8.26에 배지·칩 라우팅 및 짝 칩 등급 일치 조항 추가**). 배지류를 **부류 A(`text-[0.65rem]` 상태 칩 4곳) / 부류 B(인터랙티브 내비·토글 5곳)** 로 분리해 **AC-42 개정**, `-dark`가 **배경**으로 쓰이는 조합을 **AC-43 검사 대상에 추가**(v1.11 목록은 전경만 다루어 칩 배경을 놓쳤다), **AC-47 신설**(팔레트 외 색 상한 8건 화이트리스트), **AC-46에 폴트 인젝션 ⑤·⑥ 추가**(폐기된 v1.11 칩 패턴 및 `white` 증가 검출). 부류 A vermillion 칩 2곳의 배경이 #D9342B → #A8231C로 어두워지는 **시각 변경은 GM 승인 사항으로 명시**하되 차단 사유가 아님을 기록. Job `3d3b823a` | +| 1.13 | 2026-07-31 | claude (planner) | 테마 색상 통일성 검증 계획 수립 (`eaddc4f`→`082d71e` 4개 커밋). **Gate 0~10 전량 통과·빌드 exit 0인 상태에서 WCAG AA 미달 6건·통일성 결함 9건이 실재**함을 실측으로 확정 — 게이트 통과가 곧 오탐 신호였다. 원인은 게이트 **범위 결함 3종**: ⓐ **AC-44의 vermillion 절반이 구조적으로 무효**(면제 조항 `"text-vermillion" in line`이 판정 정규식과 항상 동시 매치 — 실소스 4라인 + 주입 2건으로 재현), ⓑ AC-45가 `-dark` 2종만 검사해 **`--cobalt` 반전 대비 1.00**(D-10 근본 원인의 재발)을 미검출, ⓒ AC-43이 소스의 전경/배경 쌍을 보지 않아 `bg-cobalt-dark text-white`(다크 2.85)를 통과. **R-8.30 신설**(비텍스트 UI 3:1 · 알파는 합성 후 산정 — `focus:ring-cobalt/50` **1.80** · `hover:border-cobalt/60` **1.95** 검출), **R-8.31 신설**(역할 시그니처 단위 색 통일 — 괘선 6:1 · 키커 11:1 · 배지 전경 6:4 · hover 테두리 4종 · 포커스 2종, 지도교수 이메일 1값이 3색 3대비), **R-8.32 신설**(게이트 면제는 `(파일,행,사유)` 등재만 허용 · 라인 부분문자열 면제 금지 — **N6과 동일 유형**). **R-8.5·R-8.26·R-8.28 개정**, **AC-42·43·44·45·47 개정**, **AC-48~AC-50 신설**(Gate 11 C11-1~8 · 폴트 인젝션 F1~F9 · `docs/DESIGN.md` 동기화 4건). **§8.1 색상표를 실제 토큰값 `#4E77FF`/`#345AD2`로 동기화**하고 **D-10 확정값을 #345AD2로 개정**(paper 4.76, 여유 0.26 → R-12). **D-12 신설**(🔴 Primary 적용의 판정 기준 — 라이트 테마에서 #4E77FF가 정적으로 보이는 곳이 **2곳뿐**이며 인지색은 #345AD2. 히어로 `Orchestration`이 R-8.5·DESIGN.md §2를 위반해 cobalt로 변경되어 한 페이지 안에서 규약이 분열), **D-13 신설**(🟡 `--vermillion` 반전 1.25). **A-1 `lectures:89` 4.16 미교정 잔존**·**A-2 `not-found.tsx:22` 4.16 신규 발견**(어떤 AC에도 없던 항목)·**A-7 `::selection` 4.16 미등재** 확정. **D-11 실측 갱신**(23건, 최저 3.77). 색 교체 5회 연속 대비표 미첨부(R-10). Job `43f3f74a` | +| 1.14 | 2026-07-31 | claude (planner) | 개발 팀장(Agy) 기술 이의제기(Job `4962a667`) 반영. **구조적 통찰 채택** — 다크 `--cobalt`만 단독 상향하면 다크 지면 대비가 DEFAULT 9.2 > `-dark` 5.96으로 **계층이 역전**됨을 실측 확인, v1.13 §7 각주의 누락을 인정하고 **R-8.33 신설**(토큰 등급 불변식). 다만 불변식을 **절대 휘도 순서가 아니라 테마 상대 대비**로 정식화 — 절대 순서의 테마 간 뒤집힘은 vermillion 쌍에서도 동일한 **정상 동작**이며 현행 8개 셀 전부에서 성립하므로, 절대 휘도로 판정하면 정상 상태를 오판한다. **제안 수치 미채택** — 주 권장값 `#85ACFF`의 반전 대비는 **1.73**으로 조정을 촉발한 R-8.28(≥2.0) 자체를 충족하지 못하며, 제안 표의 `#345AD2` L=0.095는 **폐기된 #32549E의 값**(실제 0.1270)이라 `#B0CDFF` 반전 대비 2.50도 실제 **3.68**이다. **이의제기 지점에서 더 큰 결함 발굴** — 다크 `--cobalt`(#4D77FF)는 `bg-paper` 위 **4.37**이므로 v1.12가 지시한 `text-cobalt-dark dark:text-cobalt` 라우팅이 **다크 절반을 DEFAULT로 되돌려 8곳이 AA 미달**이다(**AC-51 신설**). 원인은 R-8.26의 "`paper` 기준 산정" 원칙을 **본 계획자가 라이트 테마에만 적용한 오류**로, v1.11 §6.5와 같은 형태의 누락이다. 게이트도 AC-44 정규식의 **부정 후방탐색 `(?
- - + + Location & Contact
@@ -48,7 +48,7 @@ export function DirectionsBlock() { 관련 기관 -
+
경북대학교 (KNU) ↗ diff --git a/refer_landing_page/app/_components/ProjectPageView.tsx b/refer_landing_page/app/_components/ProjectPageView.tsx index 9dd53ba..06ae3d7 100644 --- a/refer_landing_page/app/_components/ProjectPageView.tsx +++ b/refer_landing_page/app/_components/ProjectPageView.tsx @@ -11,8 +11,8 @@ export function ProjectPageView() {
- - + + Key Initiatives
@@ -50,7 +50,7 @@ export function ProjectPageView() { {proj.title} {proj.period && ( - + {proj.period} )} @@ -85,12 +85,12 @@ export function ProjectPageView() { ) : proj.standardsTrack ? (
Standards Track: - {proj.standardsTrack} + {proj.standardsTrack}
) : proj.standardsOrg ? (
Organization: - {proj.standardsOrg} + {proj.standardsOrg}
) : null} diff --git a/refer_landing_page/app/lectures/page.tsx b/refer_landing_page/app/lectures/page.tsx index bbc6c37..728b178 100644 --- a/refer_landing_page/app/lectures/page.tsx +++ b/refer_landing_page/app/lectures/page.tsx @@ -10,8 +10,8 @@ export default function LecturesPage() { {/* Header */}
- - + + Academic Courses
@@ -27,7 +27,7 @@ export default function LecturesPage() {
-
+
Recent Courses ({recentSemesters.length} Semesters)

@@ -47,7 +47,7 @@ export default function LecturesPage() { {sem.term} {sem.year} - + Latest

@@ -86,7 +86,7 @@ export default function LecturesPage() { 2016 Fall ~ 2024 Spring 학기별 개설 교과목 이력

- + 전체 보기 ▾ 접기 ▴ diff --git a/refer_landing_page/app/members/page.tsx b/refer_landing_page/app/members/page.tsx index 4a96f49..1c1c8f7 100644 --- a/refer_landing_page/app/members/page.tsx +++ b/refer_landing_page/app/members/page.tsx @@ -15,8 +15,8 @@ export default function MembersPage() { {/* Header */}
- - + + People & Researchers
@@ -30,7 +30,7 @@ export default function MembersPage() { {/* Professor Section */}
-
+
Faculty
@@ -51,7 +51,7 @@ export default function MembersPage() {
sjkoh@knu.ac.kr @@ -60,7 +60,7 @@ export default function MembersPage() { href="https://github.com/sjkoh12" target="_blank" rel="noreferrer" - className="text-cobalt-dark dark:text-cobalt hover:underline" + className="text-cobalt-dark hover:underline" > GitHub @sjkoh12 ↗ @@ -81,7 +81,7 @@ export default function MembersPage() {
-
+
Active Researchers ({activeMembers.length} Members)

@@ -105,13 +105,13 @@ export default function MembersPage() { {mem.ko} - + {mem.degree}

{mem.en}
{mem.affiliation && ( -
+
with {mem.affiliation}
)} @@ -135,13 +135,13 @@ export default function MembersPage() { {mem.ko} - + {mem.degree}
{mem.en}
{mem.affiliation && ( -
+
with {mem.affiliation}
)} @@ -174,7 +174,7 @@ export default function MembersPage() { 2007년부터 2026년까지 수여된 박사(Ph.D.) 및 석사(M.S.) 졸업생 이력

- + 전체 보기 ▾ 접기 ▴ @@ -199,7 +199,7 @@ export default function MembersPage() { {alum.major && {alum.major}}
{alum.currentPosition && ( -
+
{alum.currentPosition}
)} diff --git a/refer_landing_page/app/not-found.tsx b/refer_landing_page/app/not-found.tsx index 1a21e4d..1206595 100644 --- a/refer_landing_page/app/not-found.tsx +++ b/refer_landing_page/app/not-found.tsx @@ -5,7 +5,7 @@ export default function NotFound() { return (
-
+
404 Error

@@ -19,7 +19,7 @@ export default function NotFound() {
메인 페이지로 돌아가기 diff --git a/refer_landing_page/app/page.tsx b/refer_landing_page/app/page.tsx index 517250f..380749a 100644 --- a/refer_landing_page/app/page.tsx +++ b/refer_landing_page/app/page.tsx @@ -63,7 +63,7 @@ export default function HomePage() { {/* Hero Section */}
- + Kyungpook National University · AI Agent Networking Lab (ANL)
@@ -72,7 +72,7 @@ export default function HomePage() {

Multi-Agent
- Orchestration + Orchestration

AI 에이전트 네트워크 연구실(ANL)은 멀티 AI 에이전트 오케스트레이션을 위해 서로 소통하고 협력하는 에이전트 네트워킹 기술과 표준 프레임워크 기술을 연구합니다. @@ -81,7 +81,7 @@ export default function HomePage() { {/* Metrics Row (Derived from data array, AC-13) */}

-
+
{PILLARS.length}
@@ -89,7 +89,7 @@ export default function HomePage() {
-
+
{Math.floor((publications.length + patents.length) / 10) * 10}+
@@ -120,7 +120,7 @@ export default function HomePage() {
-
+
Research Areas

@@ -145,7 +145,7 @@ export default function HomePage() {
[{pillar.no}] @@ -184,7 +184,7 @@ export default function HomePage() { ANL Core Spec Pillar #{pillar.no} diff --git a/refer_landing_page/app/publications/[category]/page.tsx b/refer_landing_page/app/publications/[category]/page.tsx index 1bd1477..4223c7f 100644 --- a/refer_landing_page/app/publications/[category]/page.tsx +++ b/refer_landing_page/app/publications/[category]/page.tsx @@ -59,8 +59,8 @@ export default function PublicationCategoryPage({ params }: PageProps) { {/* Header */}
- - + + Publications Category
@@ -81,7 +81,7 @@ export default function PublicationCategoryPage({ params }: PageProps) { Showing {records.length} Pre-rendered Records - + SSG ● Static HTML
@@ -108,7 +108,7 @@ export default function PublicationCategoryPage({ params }: PageProps) {

@@ -121,7 +121,7 @@ export default function PublicationCategoryPage({ params }: PageProps) { 출원번호: {rec.appNo} ({rec.country}, {rec.appDate})

{rec.regNo && ( -

+

등록번호: {rec.regNo} ({rec.regDate})

)} diff --git a/refer_landing_page/app/publications/_components/CategoryNav.tsx b/refer_landing_page/app/publications/_components/CategoryNav.tsx index 34eee38..43e063d 100644 --- a/refer_landing_page/app/publications/_components/CategoryNav.tsx +++ b/refer_landing_page/app/publications/_components/CategoryNav.tsx @@ -20,7 +20,7 @@ export function CategoryNav({ currentCategory }: CategoryNavProps) { className={`px-4 py-2 rounded text-xs font-mono tracking-wider transition-colors ${ isActive ? "bg-cobalt-dark text-white dark:text-ivory font-bold" - : "bg-paper text-ink border border-line hover:border-cobalt-dark dark:hover:border-cobalt" + : "bg-paper text-ink border border-line hover:border-cobalt-dark" }`} > {cat.label} diff --git a/refer_landing_page/app/publications/page.tsx b/refer_landing_page/app/publications/page.tsx index d010363..75232ef 100644 --- a/refer_landing_page/app/publications/page.tsx +++ b/refer_landing_page/app/publications/page.tsx @@ -26,8 +26,8 @@ export default function PublicationsIndexPage() { {/* Header section */}
- - + + BIBLIOGRAPHY & INTELLECTUAL PROPERTY
@@ -49,13 +49,13 @@ export default function PublicationsIndexPage() { return (
Category -

+

{cat.label}

@@ -69,7 +69,7 @@ export default function PublicationsIndexPage() { 전체 보기 → diff --git a/refer_landing_page/app/standardization/page.tsx b/refer_landing_page/app/standardization/page.tsx index d6e4283..e31a3b0 100644 --- a/refer_landing_page/app/standardization/page.tsx +++ b/refer_landing_page/app/standardization/page.tsx @@ -13,8 +13,8 @@ export default function StandardizationPage() { {/* Header */}

- - + + Open Standards & Contributions
@@ -33,7 +33,7 @@ export default function StandardizationPage() {
- + [{body.scope}] {body.role && ( @@ -61,7 +61,7 @@ export default function StandardizationPage() {
- + {proj.wg} {proj.name} diff --git a/refer_landing_page/components/Footer.tsx b/refer_landing_page/components/Footer.tsx index eb72451..beb18f9 100644 --- a/refer_landing_page/components/Footer.tsx +++ b/refer_landing_page/components/Footer.tsx @@ -50,7 +50,7 @@ export default function Footer() { 경북대학교 IT대학 5호관(415동) 527호
sjkoh@knu.ac.kr @@ -68,7 +68,7 @@ export default function Footer() {
{l.ko}{" "} {l.en} diff --git a/refer_landing_page/components/Header.tsx b/refer_landing_page/components/Header.tsx index 901595a..7440c29 100644 --- a/refer_landing_page/components/Header.tsx +++ b/refer_landing_page/components/Header.tsx @@ -67,7 +67,7 @@ export default function Header() { className={`group relative flex items-baseline gap-1.5 text-[0.78rem] font-semibold uppercase tracking-[0.18em] transition-all px-3 py-1.5 rounded-md ${ active ? "bg-cobalt-dark text-white dark:text-ivory shadow-sm font-bold" - : "text-ink hover:text-cobalt-dark dark:hover:text-cobalt hover:bg-paper/60" + : "text-ink hover:text-cobalt-dark hover:bg-paper/60" }`} >