feat(design-system): reskin Charcoal — tokens dark-default + sidebar navy permanent
- Remplacement intégral index.css par palette Charcoal (DESIGN_SYSTEM.md v2.0)
- Dark = thème par défaut, .light = override via @custom-variant light
- Sidebar navy #0C1528 permanent (identique dark+light)
- Script anti-FOUC inline dans index.html
- Layout : radial-gradient sur <main>, sidebar 230px, max-w-[1100px]
- Renommage tokens Boréal→Charcoal sur ~45 composants
- Inversion dark: → baseline + light: sur primitives shadcn
- Fix logo blanc forcé dans sidebar
- ADR 006 mis à jour
Typecheck: OK · Tests: 122/122 ✅
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
407d1bd134
commit
b68f160bce
61 changed files with 1269 additions and 726 deletions
|
|
@ -44,10 +44,10 @@ export function MonProfilPreparation({ plan }: Props) {
|
|||
if (isLoading || isError || !data) {
|
||||
return (
|
||||
<Card variant="default" className="p-4">
|
||||
<p className="text-[11px] font-semibold uppercase tracking-widest text-ink-5">
|
||||
<p className="text-[11px] font-semibold uppercase tracking-widest text-ink-tertiary">
|
||||
Mon profil de préparation
|
||||
</p>
|
||||
<p className="mt-2 text-sm text-ink-4">
|
||||
<p className="mt-2 text-sm text-ink-secondary">
|
||||
{isError ? 'Profil temporairement indisponible.' : 'Chargement…'}
|
||||
</p>
|
||||
</Card>
|
||||
|
|
@ -58,14 +58,14 @@ export function MonProfilPreparation({ plan }: Props) {
|
|||
const remaining = Math.max(0, data.minimum - data.current)
|
||||
return (
|
||||
<Card variant="default" className="space-y-2 p-4">
|
||||
<p className="text-[11px] font-semibold uppercase tracking-widest text-ink-5">
|
||||
<p className="text-[11px] font-semibold uppercase tracking-widest text-ink-tertiary">
|
||||
Mon profil de préparation
|
||||
</p>
|
||||
<p className="text-sm text-ink-2">
|
||||
<p className="text-sm text-ink-primary">
|
||||
Encore <span className="font-semibold tabular-nums">{remaining}</span>{' '}
|
||||
{remaining > 1 ? 'simulations' : 'simulation'} pour débloquer votre profil.
|
||||
</p>
|
||||
<p className="text-xs text-ink-4 tabular-nums">
|
||||
<p className="text-xs text-ink-secondary tabular-nums">
|
||||
{data.current}/{data.minimum} simulations corrigées
|
||||
</p>
|
||||
</Card>
|
||||
|
|
@ -80,27 +80,27 @@ export function MonProfilPreparation({ plan }: Props) {
|
|||
<Card variant="raised" className="space-y-3 p-4">
|
||||
<div className="flex items-start justify-between gap-3">
|
||||
<div className="space-y-1">
|
||||
<p className="text-[11px] font-semibold uppercase tracking-widest text-ink-5">
|
||||
<p className="text-[11px] font-semibold uppercase tracking-widest text-ink-tertiary">
|
||||
Indice de préparation
|
||||
</p>
|
||||
<p className="tabular-nums text-ink-1">
|
||||
<p className="tabular-nums text-ink-primary">
|
||||
<span className="text-3xl font-bold">{data.preparation_index.score}</span>
|
||||
<span className="text-lg font-medium text-ink-4">/100</span>
|
||||
<span className="text-lg font-medium text-ink-secondary">/100</span>
|
||||
</p>
|
||||
</div>
|
||||
<p className="max-w-[180px] text-right text-xs text-ink-3">
|
||||
<p className="max-w-[180px] text-right text-xs text-ink-secondary">
|
||||
{data.preparation_index.message}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="h-1.5 overflow-hidden rounded-full bg-canvas-2">
|
||||
<div className="h-1.5 overflow-hidden rounded-full bg-surface">
|
||||
<div
|
||||
className={`h-full transition-all duration-300 ${color}`}
|
||||
style={{ width: `${pct}%` }}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<p className="text-sm text-ink-2">
|
||||
<p className="text-sm text-ink-primary">
|
||||
{patternsCount === 0
|
||||
? 'Aucune erreur récurrente identifiée — continuez !'
|
||||
: `${patternsCount} ${patternsCount > 1 ? 'erreurs récurrentes identifiées' : 'erreur récurrente identifiée'}.`}
|
||||
|
|
|
|||
|
|
@ -9,9 +9,9 @@ import { Button } from '@/shared/components/ui/button'
|
|||
|
||||
export function PaywallBanner() {
|
||||
return (
|
||||
<div className="rounded-lg border border-expria-100 bg-expria-50 p-4 dark:border-expria/20">
|
||||
<p className="text-sm font-semibold text-ink-1">Passez à Standard pour débloquer :</p>
|
||||
<ul className="mt-2 space-y-1 text-sm text-ink-3" role="list">
|
||||
<div className="rounded-lg border border-brand-100 bg-brand-soft p-4 dark:border-brand/20">
|
||||
<p className="text-sm font-semibold text-ink-primary">Passez à Standard pour débloquer :</p>
|
||||
<ul className="mt-2 space-y-1 text-sm text-ink-secondary" role="list">
|
||||
<li>Simulations illimitées</li>
|
||||
<li>Rapport détaillé par critère</li>
|
||||
<li>Historique de vos productions</li>
|
||||
|
|
|
|||
|
|
@ -36,13 +36,13 @@ function getDisplayName(
|
|||
function DashboardSkeleton() {
|
||||
return (
|
||||
<div className="space-y-6" aria-busy="true" aria-label="Chargement du tableau de bord">
|
||||
<div className="h-8 w-48 animate-pulse rounded-md bg-canvas-2" />
|
||||
<div className="h-8 w-48 animate-pulse rounded-md bg-surface" />
|
||||
<div className="grid grid-cols-2 gap-4">
|
||||
<div className="h-24 animate-pulse rounded-lg bg-canvas-2" />
|
||||
<div className="h-24 animate-pulse rounded-lg bg-canvas-2" />
|
||||
<div className="h-24 animate-pulse rounded-lg bg-surface" />
|
||||
<div className="h-24 animate-pulse rounded-lg bg-surface" />
|
||||
</div>
|
||||
<div className="h-9 animate-pulse rounded-md bg-canvas-2" />
|
||||
<div className="h-16 animate-pulse rounded-lg bg-canvas-2" />
|
||||
<div className="h-9 animate-pulse rounded-md bg-surface" />
|
||||
<div className="h-16 animate-pulse rounded-lg bg-surface" />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
|
@ -78,7 +78,7 @@ export function DashboardPage() {
|
|||
<div className="space-y-6">
|
||||
{/* Salutation */}
|
||||
<section className="flex flex-wrap items-center gap-3">
|
||||
<h1 className="text-2xl font-semibold text-ink-1">Bonjour, {displayName}</h1>
|
||||
<h1 className="text-2xl font-semibold text-ink-primary">Bonjour, {displayName}</h1>
|
||||
<Badge variant="plan" planValue={data.plan}>
|
||||
{PLAN_LABELS[data.plan]}
|
||||
</Badge>
|
||||
|
|
@ -89,15 +89,15 @@ export function DashboardPage() {
|
|||
|
||||
{/* Métriques */}
|
||||
<section className="grid grid-cols-2 gap-4" aria-label="Métriques de préparation">
|
||||
<div className="rounded-lg border border-line bg-surface p-4">
|
||||
<p className="text-xs text-ink-4">Simulations restantes</p>
|
||||
<p className="mt-1 text-2xl font-semibold text-ink-1">
|
||||
<div className="rounded-lg border border-border bg-surface p-4">
|
||||
<p className="text-xs text-ink-secondary">Simulations restantes</p>
|
||||
<p className="mt-1 text-2xl font-semibold text-ink-primary">
|
||||
{data.simulations_remaining === null ? 'Illimitées' : data.simulations_remaining}
|
||||
</p>
|
||||
</div>
|
||||
<div className="rounded-lg border border-line bg-surface p-4">
|
||||
<p className="text-xs text-ink-4">Niveau NCLC estimé</p>
|
||||
<p className="mt-1 text-2xl font-semibold text-ink-1">—</p>
|
||||
<div className="rounded-lg border border-border bg-surface p-4">
|
||||
<p className="text-xs text-ink-secondary">Niveau NCLC estimé</p>
|
||||
<p className="mt-1 text-2xl font-semibold text-ink-primary">—</p>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
|
|
@ -113,8 +113,8 @@ export function DashboardPage() {
|
|||
|
||||
{/* Dernières simulations */}
|
||||
<section aria-label="Dernières simulations">
|
||||
<h2 className="text-base font-semibold text-ink-1">Dernières simulations</h2>
|
||||
<p className="mt-2 text-sm text-ink-4">Aucune simulation pour l'instant.</p>
|
||||
<h2 className="text-base font-semibold text-ink-primary">Dernières simulations</h2>
|
||||
<p className="mt-2 text-sm text-ink-secondary">Aucune simulation pour l'instant.</p>
|
||||
</section>
|
||||
|
||||
{/* Mon profil de préparation — Premium uniquement (gate via hasAccess) */}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue