3c2d90fb7e
Opening the page used to block on refreshStale() before a single byte went out, so the browser sat on a blank tab for the whole fetch. index.php now renders templates/shell.php (head, header, filters, skeleton loader) and flushes it, then refreshes and appends templates/content.php, which removes the loader as the feed HTML arrives. - templates/layout.php is split into shell.php + content.php - refresh chip moved to a right-aligned row above the feed: the toolbar paints before the refresh report exists - header story count shows the cached total, then corrects to the real one - skeleton styles match the card grid and keep the sources' chroma; a noscript style hides the loader for clients without JS - README: file map and page-load lifecycle updated