## 2026-10-01T02:46:12Z
You are worker_m2_1_gen3.
Your working directory is: c:\Projects\FreeExile\.agents\teamwork\worker_m2_1_gen3
You must read ORIGINAL_REQUEST.md at: c:\Projects\FreeExile\.agents\teamwork\ORIGINAL_REQUEST.md (under section ## 2026-10-01T00:31:10Z).

MANDATORY INTEGRITY WARNING:
DO NOT CHEAT. All implementations must be genuine. DO NOT hardcode test results, create dummy/facade implementations, or circumvent the intended task. A auditor will independently verify your work. Integrity violations WILL be detected and your work WILL be rejected.

Scope & Implementation Assignment:
Implement Milestone 2: Character Animation & Visceral Combat Feel Engine per PROJECT.md, SCOPE.md, and the 3 Explorer handoff reports:
- Explorer 1: `c:\Projects\FreeExile\.agents\teamwork\explorer_m2_1_gen3\handoff.md` (5-phase kinetic machine & weapon archetypes)
- Explorer 2: `c:\Projects\FreeExile\.agents\teamwork\explorer_m2_2_gen3\handoff.md` (hit-stop, camera shake, damage number pool)
- Explorer 3: `c:\Projects\FreeExile\.agents\teamwork\explorer_m2_3_gen3\handoff.md` (dodge roll, animation cancelling, ghost trails)

Write Ownership:
You own and modify:
- `client/webapp/js/engine/animation_engine.js` (Must stay <= 350 lines soft cap / <= 500 hard cap)
- `client/webapp/js/engine/combat_feel_engine.js` (Must stay <= 350 lines soft cap / <= 500 hard cap)
- `client/webapp/js/engine/combat_skills.js` (CRITICAL: currently 472 lines, MUST STAY <= 500 lines hard cap!)
- `client/webapp/js/engine/canvas_renderer.js` (Must stay <= 350 lines soft cap / <= 500 hard cap)
- `client/webapp/js/data/weapon_swing_catalog.js` (Must stay <= 700 lines soft cap)
- `tests/unit/test_m2_animation_and_combat_feel.py` (new unit tests verifying M2)

Key Implementation Details:
1. `animation_engine.js`:
   - In `HERO_TRACKS.animations`, add archetype clips: `attack_thrust`, `attack_slam`, `attack_bolt` mapping frames cleanly.
   - In `updateAnimation(state, dt)` / `playAnimation`, continuously compute `state.kineticPhase`:
     * `'hit_stop'` when `state.isHitStopped` is true.
     * When current animation is attack: `'wind_up'` before `hit_frame`, `'impact'` at `hit_frame`, `'recovery'` after `hit_frame`.
     * When moving: `'run'`.
     * Otherwise: `'idle'`.
2. `combat_feel_engine.js`:
   - Fix `isHitStopped(dt = 0.016)` to guard against undefined / NaN `dt`.
   - Update `DamageNumberSlot` pop-in bounce scale:
     * Standard: 1.6x down to 1.0x in first 20% of lifetime (`1.6 - p * 0.6`).
     * Crit: 2.0x down to 1.2x in first 20% of lifetime (`2.0 - p * 0.8`).
   - Clamp screen shake intensity to [2.5, 8.5] and duration to [0.12, 0.45]s.
   - Synchronize with global `screenShake` in `iso_math.js` / window.
3. `combat_skills.js` (Keep changes ultra-lean to stay under 500 lines):
   - In `doDodge()`, add animation cancelling: if player is in wind-up/attacking, cancel attack immediately (`player.animState = 'dodge'`, reset attack timers).
   - In attack executions, trigger hit-stop on impact (`combatFeelEngine.triggerHitStop(3, 0.05)`) and weapon swing visual (`weaponSwingRenderer.triggerSwing(...)`).
4. `canvas_renderer.js`:
   - Wire `combatFeelEngine.update(dt)` and `combatFeelEngine.renderDamageNumbers(ctx)` into loop.
   - Wire `weaponSwingRenderer.render(ctx, player)` or update calls.

Verification Requirements:
1. Run `pytest tests/unit/ -v` (all existing unit tests + any new M2 tests pass 100%).
2. Run `pytest tests/e2e/test_poe2_ui_animation_vfx_e2e.py -v` (expect all M2 tests to pass, 0 failed).
3. Run `python tools/lint/check_code_and_doc_hygiene.py --strict` (0 hard cap violations).
4. Write handoff report in `c:\Projects\FreeExile\.agents\teamwork\worker_m2_1_gen3\handoff.md` and send completion message.
