Body path now goes: interp_tail → grid_tail → segment[N-2] → ... → head.
The short leg from interpolated to grid-snapped tail is always straight
(same direction), and from grid_tail onward the path strictly follows
the grid — preserving sharp corners while tail stays smooth.
Tail now uses the same approach as head: interpolated in the body path
from its previous position, with ease-in (mirror of head's ease-out).
Ghost circle removed — no longer needed since tail is naturally smooth.
Added EaseInCubic to AnimationHelper. InterpolatePosition now uses
string easing mode instead of bool.
Tail is now part of the main body path (grid-snapped, full thickness,
sharp corners). Smooth movement illusion via fading ghost circle at
the old tail position that fades out during the tick.
Tail is now drawn as a separate DrawLine from interpolated tail position
to the grid-snapped second-to-last segment. Body path (segment[N-2]→head)
stays grid-snapped, preserving sharp corners while tail glides smoothly.
Tail interpolation caused diagonal shortcuts at corners because
the interpolated tail position would drift while the adjacent
segment was already at its new grid position. By keeping only
the head interpolated, L-shaped bends render correctly.
When snake doesn't grow, the last segment (new tail) should interpolate
from the old tail's position (previous[segmentIndex]), not from the
second-to-last segment (previous[segmentIndex-1]) which didn't move.
- Two-timer architecture: game timer + 60fps render timer for smooth interpolation
- Snake body: StreamGeometry path with teal gradient, rounded joins
- Directional head with white eyes and dark pupils
- Food: pulsating glow, highlight, green leaf animation
- Modern dark theme (#0D1117), glassmorphism HUD
- Speed indicator bar, score +N popup
- High score persistence to JSON
- All keyboard shortcuts: Arrows, WASD, Space/P pause, Enter start, R restart, Esc quit
- Window resizable, 640x540 default
New files: AnimationHelper.cs, HighScoreManager.cs, SnakeRenderer.cs