fix(web): open articles as a card, drop search, unstick stale app shell

- Service worker activates new versions immediately (skipWaiting +
  clientsClaim). In prompt mode a waiting worker kept serving the previous
  build to tabs that never send SKIP_WAITING, so the old UI hit the new API
  and showed "Aucun contenu disponible" on every article. Pages already
  controlled get a reload toast; lazy chunks missing after a deploy reload
  once.
- Reader opens as a large card above the dimmed grid: close with ✕, Escape
  or a click beside it; previous/next arrows on the sides (desktop) and a
  bottom bar with the next title (all sizes).
- Remove search, the focus banner and decorative headers; plain sentence-
  case labels instead of tracked capitals; quieter dashboard header.
- Fix horizontal overflow of cards and reader navigation on phones.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Antigravity AgentandClaude Opus 5.5 committed 2026-10-09 08:26:25 +02:00
1 parent b24a9806d5
commit ed83525d26
12 files changed
+316 -375

No files matched your search

+4 -3
View File
@@ -1,11 +1,12 @@
import { lazy, Suspense, useState } from 'react';
import { Suspense, useState } from 'react';
import { lazyNamed } from '../lib/lazy';
import { Sidebar } from '../components/Sidebar';
import { MobileTopBar } from '../components/MobileTopBar';
import { DashboardPage } from '../pages/DashboardPage';
import { useWebsocket } from '../hooks/useWebsocket';
// Focus mode carries the gesture/animation code: load it only when used.
const FocusPage = lazy(() => import('../pages/FocusPage').then((m) => ({ default: m.FocusPage })));
const FocusPage = lazyNamed(() => import('../pages/FocusPage'), 'FocusPage');
export function RootLayout() {
const [selectedFeedId, setSelectedFeedId] = useState<string | null>(null);
@@ -35,7 +36,7 @@ export function RootLayout() {
/>
)}
{/* Kept mounted in focus mode so the list keeps its scroll position. */}
<DashboardPage selectedFeedId={selectedFeedId} onEnterFocus={() => setIsFocusMode(true)} hidden={isFocusMode} />
<DashboardPage selectedFeedId={selectedFeedId} hidden={isFocusMode} />
</div>
{isFocusMode && (