# Reviewer & Adversarial Critic Handoff Report: UI, Modern Typography & Microcopy Streamlining

## Review Summary

**Verdict**: **`REQUEST_CHANGES`**  
**Integrity Check**: **PASSED (CLEAN)** — No integrity violations detected. No dummy facades, no hardcoded test outputs, no faked verification logs. All 60 E2E tests, 16 unit tests, and hygiene lints run genuinely and pass natively.  
**Reason for Requesting Changes**: While static HTML and template shells achieve pure sans-serif typography and concise button microcopy, adversarial stress-testing revealed that dynamically rendered buttons in companion UI controller scripts (`client/webapp/js/ui/*.js`) still contain 3-4 word button labels and residual bilingual `A (B)` parenthetical strings, violating the strict 100% microcopy mandate.

---

## 1. Observation

### 1.1 Test Suite & Hygiene Verification Execution
1. **E2E Test Suite (`pytest tests/e2e/test_ui_typography_i18n_wiki_streamlining_e2e.py -v`)**:
   ```
   60 passed in 0.27s (0 failed, 0 skipped)
   ```
   All 4 previously skipped tests (`test_f03_index_html_tailwind_config_no_serif`, `test_t3_02_bilingual_buttons_remain_pure_sans_serif`, `test_b03_tooltip_desc_single_sentence`, `test_t3_05_dynamic_tooltip_updates_preserve_sentence_boundary_across_locales`) are genuinely unskipped and pass natively.

2. **Unit Test Suite (`python -m unittest tests/unit/test_webapp_localization_engine.py -v`)**:
   ```
   Ran 16 tests in 0.140s -> OK
   ```

3. **Code & Documentation Hygiene (`python tools/lint/check_code_and_doc_hygiene.py --strict`)**:
   ```
   Tổng số file đã quét: 522 | File đạt chuẩn sạch sẽ: 492
   KẾT QUẢ: TOÀN BỘ MÃ NGUỒN VÀ TÀI LIỆU TUÂN THỦ HARD CAP HYGIENE! (0 hard cap violations)
   ```

### 1.2 Verbatim Typography & Static HTML Observations
- **`client/webapp/index.html`**:
  - Line 9: `tailwind.config={theme:{extend:{fontFamily:{wuxia:['"Be Vietnam Pro"','Inter','system-ui','sans-serif'],sans:['"Be Vietnam Pro"','Inter','system-ui','sans-serif']}}}}` -> `cinzel` completely purged.
  - Line 11: Google Fonts CDN imports only `Be Vietnam Pro` and `Inter` -> `Cinzel` and `Noto Serif` completely purged.
  - Lines 18-84: All HUD buttons, simulator toggles, and modal navigation triggers have $\le 2$ words (e.g. `iPhone`, `Cửa Sổ`, `Toàn Màn`, `Võ Học`, `Thu Hồi`, `Động Thiên`, `Bản Đồ`, `Tàn Đồ`, `Mê Cung`, `Phó Bản`, `Nhiệm Vụ`, `Song Binh`, `Thần Binh`, `Ma Đồ`, `Nhân Vật`, `Túi Đồ`, `Rương Đồ`, `Chiến Hồn`, `Mùa Giải`, `Hắc Thị`, `Tài Khoản`, `Cài Đặt`).
- **`client/webapp/css/main.css`**:
  - Lines 3-5: `--font-wuxia` and `--font-body` use `'Be Vietnam Pro', 'Inter', system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif`.
  - Zero occurrences of `Cinzel`, `Noto Serif`, or serif fallbacks.
- **`client/webapp/js/engine/vfx_renderer.js`**:
  - Line 249: `ctx.font = dtObj.isCrit ? 'bold 14px "Be Vietnam Pro", Inter, sans-serif' : 'bold 12px "Be Vietnam Pro", sans-serif';` -> Combat floating crit text migrated to sans-serif.

### 1.3 Verbatim Dynamic Microcopy & Bilingual String Observations
Adversarial scanning of all `<button>` tags and text nodes across `client/webapp/js/` revealed the following non-compliant elements in active UI controllers:

1. **`client/webapp/js/ui/character_equipment.js` (Line 156)**:
   ```javascript
   <button onclick="window.unequipGearSlot('${inspectedSlotId}')" ...>
     <span>📦</span> <span>Tháo Vào Túi</span>
   </button>
   ```
   - Observed: `"Tháo Vào Túi"` consists of **3 words**.

2. **`client/webapp/js/ui/divine_vault_modal.js` (Line 203)**:
   ```javascript
   <button onclick="window.equipDemoWeapon('${w.id}')" ...>Trang Bị Thử</button>
   ```
   - Observed: `"Trang Bị Thử"` consists of **3 words**.

3. **`client/webapp/js/ui/meridian_vault.js` (Line 207 & Line 205)**:
   ```javascript
   // Line 207:
   <button onclick="withdrawGuildItem('${item.id}')" ...>
     Rút Về Dùng
   </button>
   // Line 205:
   <span class="text-[10px] text-stone-400 font-mono">Miễn Phí (Bang)</span>
   ```
   - Observed: Button label `"Rút Về Dùng"` consists of **3 words**.
   - Observed: Price label contains parenthetical notation `(Bang)`.

4. **`client/webapp/js/ui/story_quest_board.js` (Line 160)**:
   ```javascript
   `<button class="btn-accept-q ..." data-id="${q.id}">Nhận Khế Ước</button>`
   ```
   - Observed: Button label `"Nhận Khế Ước"` consists of **3 words**.

5. **`client/webapp/js/ui/worldmap_dungeons.js` (Line 88)**:
   ```javascript
   <span>${isCurrent ? '📍 Đang Ở Đây' : '⚡ Dịch Chuyển Thần Hành'}</span>
   ```
   - Observed: `"Dịch Chuyển Thần Hành"` consists of **4 words**; `"Đang Ở Đây"` consists of **3 words**.

6. **`client/webapp/js/ui/templates/template_catalog_activities.js` (Line 230)**:
   ```html
   Mỗi Big Update mùa giải, toàn bộ thế giới bước vào <strong>Đại Nạn Hoang Vực (Clean Slate Reset)</strong>.
   ```
   - Observed: Contains bilingual English parenthetical `(Clean Slate Reset)`.

7. **`client/webapp/js/ui/divine_vault_modal.js` (Lines 131, 138, 145, 197, 240)**:
   ```javascript
   titleVi: 'Bờ Biển Tử Địa (The Forsaken Shore)',
   titleVi: 'Mật Ngục Tế Cốt (The Eldritch Crypt)',
   titleVi: 'Hoang Vực Xương Trắng (The Bleached Bone Wastes)',
   // Line 197 & 240:
   <div class="text-[10px] font-bold text-stone-400 uppercase tracking-wider mb-1">Cổ Thần Điển Tích (Lore)</div>
   ```
   - Observed: Retains multiple bilingual parenthetical English titles and `(Lore)` section headers.

---

## 2. Logic Chain

1. **Premise 1 (User Directives)**: ORIGINAL_REQUEST §R1 and Acceptance Criteria require that:
   - 100% of buttons, tabs, and navigation controls across the WebApp must be concise terms of $\le 2$ words.
   - All bilingual `A (B)` parenthetical strings must be removed from the UI.
2. **Premise 2 (Review Scope)**: The review scope covers not just the static template shells (`template_catalog_*.js`), but the interactive user interface as experienced by the player when modals are open and populated.
3. **Observation Linkage**: While `client/webapp/js/ui/templates/` achieved 100% compliance in its template scaffolding (148/148 buttons $\le 2$ words), the dynamic rendering routines in `character_equipment.js`, `divine_vault_modal.js`, `meridian_vault.js`, `story_quest_board.js`, and `worldmap_dungeons.js` insert button labels with 3 and 4 words (`Tháo Vào Túi`, `Trang Bị Thử`, `Rút Về Dùng`, `Nhận Khế Ước`, `Dịch Chuyển Thần Hành`).
4. **Test Heuristic Coverage Gap**: The E2E test `get_template_buttons()` extracts buttons strictly from `client/webapp/js/ui/templates/*.js`, leaving dynamic card rendering routines untested for microcopy length.
5. **Conclusion**: Even though automated test suites return 100% PASS, human users and in-game players will encounter 3-4 word buttons and parenthetical English phrases during gameplay in those 5 modals. Therefore, changes must be requested before final release approval.

---

## 3. Findings

### [Major] Finding 1: Dynamic Modal Buttons Exceed 2-Word Limit
- **What**: 6 buttons rendered dynamically inside modals contain 3 to 4 words.
- **Where**:
  - `client/webapp/js/ui/character_equipment.js:156`: `Tháo Vào Túi` (3 words)
  - `client/webapp/js/ui/divine_vault_modal.js:203`: `Trang Bị Thử` (3 words)
  - `client/webapp/js/ui/meridian_vault.js:207`: `Rút Về Dùng` (3 words)
  - `client/webapp/js/ui/story_quest_board.js:160`: `Nhận Khế Ước` (3 words)
  - `client/webapp/js/ui/worldmap_dungeons.js:88`: `Dịch Chuyển Thần Hành` (4 words) & `Đang Ở Đây` (3 words)
- **Why**: Violates Acceptance Criteria R1 ("100% các nút bấm, tab và nhãn điều hướng trên Client WebApp có độ dài tối đa 1-2 từ").
- **Suggestion**:
  - Replace `Tháo Vào Túi` $\to$ `Tháo Đồ` (2 words)
  - Replace `Trang Bị Thử` $\to$ `Trang Bị` (2 words)
  - Replace `Rút Về Dùng` $\to$ `Rút Đồ` (2 words)
  - Replace `Nhận Khế Ước` $\to$ `Nhận Khế` (2 words)
  - Replace `Dịch Chuyển Thần Hành` $\to$ `Dịch Chuyển` (2 words) and `Đang Ở Đây` $\to$ `Hiện Tại` (2 words)

### [Major] Finding 2: Residual Bilingual `A (B)` Parenthetical Strings in UI
- **What**: Several UI text nodes, headers, and catalog strings retain parenthetical English translations.
- **Where**:
  - `client/webapp/js/ui/templates/template_catalog_activities.js:230`: `Đại Nạn Hoang Vực (Clean Slate Reset)`
  - `client/webapp/js/ui/divine_vault_modal.js:131, 138, 145`: `Bờ Biển Tử Địa (The Forsaken Shore)`, `Mật Ngục Tế Cốt (The Eldritch Crypt)`, `Hoang Vực Xương Trắng (The Bleached Bone Wastes)`
  - `client/webapp/js/ui/divine_vault_modal.js:197, 240`: `Cổ Thần Điển Tích (Lore)`, `Bản Vị Huyết Thạch (Lore)`
  - `client/webapp/js/ui/meridian_vault.js:205`: `Miễn Phí (Bang)`
- **Why**: Violates Acceptance Criteria R1 ("Không còn bất kỳ nhãn UI nào chứa định dạng song ngữ kép dạng A (B)").
- **Suggestion**:
  - In `template_catalog_activities.js:230`: Change to `Đại Nạn Hoang Vực`.
  - In `divine_vault_modal.js`: Strip `(The Forsaken Shore)`, `(The Eldritch Crypt)`, `(The Bleached Bone Wastes)`, and change `(Lore)` to `Điển Tích`.
  - In `meridian_vault.js:205`: Change to `Miễn Phí`.

---

## 4. Adversarial Challenges & Stress-Testing

```markdown
## Challenge Summary
Overall risk assessment: MEDIUM

### [Medium] Challenge 1: Dynamic Controller Microcopy Drift
- Assumption challenged: "Passing all E2E tests guarantees 100% of buttons in the webapp have <= 2 words."
- Attack scenario: Player opens the Character Equipment modal and inspects a weapon; the action button renders "Tháo Vào Túi" (3 words). Player opens World Map; the teleport action renders "Dịch Chuyển Thần Hành" (4 words).
- Blast radius: Visual inconsistency, cramped mobile touch targets, and failure of executive acceptance criteria.
- Mitigation: Streamline the 6 dynamic button strings in `character_equipment.js`, `divine_vault_modal.js`, `meridian_vault.js`, `story_quest_board.js`, and `worldmap_dungeons.js`.

### [Low] Challenge 2: Test Heuristic Coverage Gap
- Assumption challenged: "`get_template_buttons()` catches all modal buttons."
- Attack scenario: Developers add dynamic buttons in controller scripts that bypass `TEMPLATES_DIR` regex checks.
- Blast radius: False positive test passes masking UI regressions.
- Mitigation: Extend `test_ui_typography_i18n_wiki_streamlining_e2e.py` to assert button brevity on dynamic controller files in addition to template files.
```

---

## 5. Verified Claims

| Claim | Method | Result |
|---|---|---|
| Pure sans-serif typography across HTML | Inspected `index.html` lines 9 & 11 | **PASS** (Zero Cinzel, Zero Noto Serif) |
| Pure sans-serif typography across CSS | Inspected `main.css`, `hud_skills.css`, `modals.css` | **PASS** (100% sans-serif variables) |
| Pure sans-serif floating combat numbers | Inspected `vfx_renderer.js:249` | **PASS** (`bold 14px "Be Vietnam Pro", Inter, sans-serif`) |
| 60/60 E2E tests pass with zero skips | `pytest tests/e2e/test_ui_typography_i18n_wiki_streamlining_e2e.py -v` | **PASS** (60 passed in 0.27s) |
| 16/16 Unit tests pass | `python -m unittest tests/unit/test_webapp_localization_engine.py -v` | **PASS** (16 passed in 0.140s) |
| Strict hygiene compliant | `python tools/lint/check_code_and_doc_hygiene.py --strict` | **PASS** (0 hard cap violations) |
| 100% HUD buttons <= 2 words | Inspected `index.html` header, dock, and simulator | **PASS** (All 24 HUD buttons $\le 2$ words) |
| 100% static template catalog buttons <= 2 words | Parsed `template_catalog_*.js` (148 buttons) | **PASS** (148/148 buttons $\le 2$ words) |

---

## 6. Caveats
- No caveats regarding server-side code or build systems; the review focused strictly on Client WebApp UI, typography, microcopy, and i18n catalogs.
- The 6 identified dynamic button labels and bilingual phrases are localized to 6 specific files and require minimal text substitution (< 10 lines of code across the repository).

---

## 7. Conclusion

The core deliverables of M1 (typography modernization, Google Fonts cleanup, Tailwind config de-serifing, canvas combat text cleanup, static template brevity, and E2E unskipping) were completed cleanly and with high technical integrity.
However, in accordance with the adversarial review protocol, the existence of 6 buttons with 3-4 words in dynamic UI controllers and residual bilingual parenthetical strings in `template_catalog_activities.js` and `divine_vault_modal.js` prevents an unqualified APPROVE.

**Verdict**: **`REQUEST_CHANGES`**  
The required remediations are specific, low-risk, and can be resolved by a worker in under 5 minutes.

---

## 8. Verification Method

To verify resolution of these findings:
1. Check that the 6 dynamic button strings in `character_equipment.js`, `divine_vault_modal.js`, `meridian_vault.js`, `story_quest_board.js`, and `worldmap_dungeons.js` are updated to $\le 2$ words.
2. Check that `(Clean Slate Reset)` in `template_catalog_activities.js:230` and parenthetical titles in `divine_vault_modal.js` are removed.
3. Re-run test commands:
   ```bash
   pytest tests/e2e/test_ui_typography_i18n_wiki_streamlining_e2e.py -v
   python -m unittest tests/unit/test_webapp_localization_engine.py -v
   python tools/lint/check_code_and_doc_hygiene.py --strict
   ```
4. Invalidation condition: Any button in the entire `client/webapp/` directory exceeding 2 words or containing bilingual `(English)` parentheses.
