- New token_manager.js: silent refresh timer (80% lifetime) + global
fetch 401 interceptor with one-shot retry.
- dnfs.py /whoami now returns iat, created_at, keep_time for expiry
estimation.
- Dnfs.html loads token_manager.js before dnfs.js (zero change to dnfs.js).
- Graceful fallback: stale tokens without new fields, refresh failures,
and /refresh_token 401 itself all degrade to the existing 401→login flow.