fix(web): design review pass — login contrast, focus labels, soft placeholders

- Login: the brand-panel headline inherited the ink heading colour and was
  near-invisible on the dark green; it is white again.
- Focus mode: sentence-case labels instead of spaced capitals, like the
  rest of the app.
- Article placeholder covers (grid and focus) use a soft green tint rather
  than a saturated block, which was glaring in dark mode.
- Reader header: "date · 3 min" fits on phones ("de lecture" from sm up).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NsXUyMEGFFGVRcHNVfcBLh
This commit is contained in:
Claude committed 2026-10-09 08:11:32 +00:00
1 parent 081420ceb8
commit 387e594221
5 files changed
+12 -12

No files matched your search

+2 -2
View File
@@ -17,8 +17,8 @@ interface ArticleCardProps {
function CoverFallback({ title, feed }: { title: string; feed?: string }) { function CoverFallback({ title, feed }: { title: string; feed?: string }) {
const initial = (feed || title).trim().charAt(0).toUpperCase(); const initial = (feed || title).trim().charAt(0).toUpperCase();
return ( return (
<div className="w-full h-full bg-gradient-to-br from-nature/90 to-nature-dark flex items-center justify-center" aria-hidden="true"> <div className="w-full h-full bg-nature/12 flex items-center justify-center" aria-hidden="true">
<span className="font-serif italic text-on-nature/35 text-7xl leading-none select-none">{initial}</span> <span className="font-serif italic text-nature/45 text-7xl leading-none select-none">{initial}</span>
</div> </div>
); );
} }
+2 -2
View File
@@ -38,7 +38,7 @@ export function AuthShell({ eyebrow, title, subtitle, children }: AuthShellProps
transition={{ duration: 0.7, delay: 0.1 }} transition={{ duration: 0.7, delay: 0.1 }}
className="relative z-10 space-y-6" className="relative z-10 space-y-6"
> >
<h2 className="text-5xl font-serif italic leading-[1.1] text-balance"> <h2 className="text-5xl font-serif italic leading-[1.1] text-balance text-white">
Le calme dans le chaos de l'information. Le calme dans le chaos de l'information.
</h2> </h2>
<p className="text-white/70 font-reading text-lg max-w-sm leading-relaxed"> <p className="text-white/70 font-reading text-lg max-w-sm leading-relaxed">
@@ -46,7 +46,7 @@ export function AuthShell({ eyebrow, title, subtitle, children }: AuthShellProps
</p> </p>
</motion.div> </motion.div>
<p className="relative z-10 text-white/40 text-[10px] uppercase tracking-[0.4em] font-bold"> <p className="relative z-10 text-white/50 text-xs">
FlowReader · Édition 2026 FlowReader · Édition 2026
</p> </p>
</aside> </aside>
+6 -6
View File
@@ -24,19 +24,19 @@ export function FocusCard({ article, isTop = false }: FocusCardProps) {
onError={(e) => (e.currentTarget.style.display = 'none')} onError={(e) => (e.currentTarget.style.display = 'none')}
/> />
) : ( ) : (
<div className="w-full h-full bg-gradient-to-br from-nature to-nature-dark p-8 flex items-end"> <div className="w-full h-full bg-nature/12 p-8 flex items-end">
<span className="text-2xl font-serif italic text-on-nature/95 leading-tight line-clamp-3">{article.feed_title}</span> <span className="text-2xl font-serif italic text-nature leading-tight line-clamp-3">{article.feed_title}</span>
</div> </div>
)} )}
<span className="absolute top-4 right-4 bg-black/55 text-white text-[11px] font-bold uppercase tracking-widest px-3 py-1.5 rounded-full"> <span className="absolute top-4 right-4 bg-black/55 text-white text-xs font-semibold px-3 py-1.5 rounded-full">
{readingTimeLabel(article.reading_time)} {readingTimeLabel(article.reading_time)}
</span> </span>
</div> </div>
{/* Body */} {/* Body */}
<div className="flex-1 p-5 sm:p-6 flex flex-col min-h-0"> <div className="flex-1 p-5 sm:p-6 flex flex-col min-h-0">
<div className="flex items-center justify-between gap-3 mb-3 text-[11px] uppercase tracking-widest font-bold text-paper-muted"> <div className="flex items-center justify-between gap-3 mb-3 text-xs text-paper-muted">
<span className="flex items-center gap-2 text-nature truncate"> <span className="flex items-center gap-2 text-nature font-semibold truncate">
<span className="w-1.5 h-1.5 rounded-full bg-nature shrink-0" aria-hidden="true" /> <span className="w-1.5 h-1.5 rounded-full bg-nature shrink-0" aria-hidden="true" />
<span className="truncate">{article.feed_title || 'Journal'}</span> <span className="truncate">{article.feed_title || 'Journal'}</span>
</span> </span>
@@ -54,7 +54,7 @@ export function FocusCard({ article, isTop = false }: FocusCardProps) {
)} )}
{isTop && ( {isTop && (
<p className="mt-auto pt-3 text-center text-[11px] uppercase tracking-widest font-bold text-paper-muted hidden sm:block"> <p className="mt-auto pt-3 text-center text-xs text-paper-muted hidden sm:block">
← Garder · Lu → · Entrée pour lire ← Garder · Lu → · Entrée pour lire
</p> </p>
)} )}
+1 -1
View File
@@ -144,7 +144,7 @@ export function FocusCardStack({ articles, onEmpty, onExit }: FocusCardStackProp
<div className="relative w-full h-full flex flex-col items-center justify-center gap-6"> <div className="relative w-full h-full flex flex-col items-center justify-center gap-6">
<p className="sr-only" aria-live="polite">{announce}</p> <p className="sr-only" aria-live="polite">{announce}</p>
<span className="inline-block bg-nature-dark/80 px-4 py-2 rounded-full text-white text-[11px] uppercase font-bold tracking-widest"> <span className="inline-block bg-nature-dark/80 px-4 py-2 rounded-full text-white text-xs font-semibold">
{articles.length - currentIndex} restant{articles.length - currentIndex > 1 ? 's' : ''} {articles.length - currentIndex} restant{articles.length - currentIndex > 1 ? 's' : ''}
</span> </span>
+1 -1
View File
@@ -255,7 +255,7 @@ export function Reader({ article: listArticle, next, hasPrev, onClose, onNext, o
<div className="flex-1 min-w-0 text-sm"> <div className="flex-1 min-w-0 text-sm">
<p className="font-semibold text-nature truncate">{listArticle.feed_title || 'Article'}</p> <p className="font-semibold text-nature truncate">{listArticle.feed_title || 'Article'}</p>
<p className="text-paper-muted truncate"> <p className="text-paper-muted truncate">
<time dateTime={date}>{formatLong(date)}</time>, {readingTimeLabel(listArticle.reading_time)} de lecture <time dateTime={date}>{formatLong(date)}</time> · {readingTimeLabel(listArticle.reading_time)}<span className="hidden sm:inline"> de lecture</span>
</p> </p>
</div> </div>
<button <button