feat: design system overhaul — sidebar, AI chats, settings, brainstorm, color cleanup
All checks were successful
Deploy to Production / Build and Deploy (push) Successful in 12s

- Sidebar: dynamic brand-accent colors, brainstorm section restyled
- AI chat general: popup panel with expand/collapse, hides when contextual AI open
- AI chat contextual: tabs reordered (Actions first), X close button, height fix
- Settings: all tabs restyled, 6 new color presets (sage, terracotta, iron, etc.)
- Global color cleanup: emerald/orange hardcoded → brand-accent dynamic
- Brainstorm page: orange → brand-accent throughout
- PageEntry animation component added to key pages
- Floating AI button: bg-brand-accent instead of hardcoded black
- i18n: all 15 locales updated with new AI/billing keys
- Billing: freemium quota tracking, BYOK, stripe subscription scaffolding
- Admin: integrated into new design
- AGENTS.md + CLAUDE.md project rules added
This commit is contained in:
Antigravity
2026-05-16 12:59:30 +00:00
parent 1fcea6ed7d
commit bd495be965
2284 changed files with 395285 additions and 2327 deletions

View File

@@ -3,6 +3,7 @@
import React, { useEffect, useRef, useState, useCallback } from 'react'
import * as d3 from 'd3'
import { BrainstormSession } from '@/types/brainstorm'
import { useLanguage } from '@/lib/i18n'
interface WaveCanvasProps {
session: BrainstormSession
@@ -31,6 +32,7 @@ export const WaveCanvas: React.FC<WaveCanvasProps> = ({
manualEditTrigger,
playbackIdeas,
}) => {
const { t, language } = useLanguage()
const svgRef = useRef<SVGSVGElement>(null)
const containerRef = useRef<HTMLDivElement>(null)
const nodeRef = useRef<d3.Selection<SVGGElement, any, SVGGElement, unknown> | null>(null)
@@ -376,7 +378,7 @@ export const WaveCanvas: React.FC<WaveCanvasProps> = ({
)
.text((d) =>
d.type === 'root'
? 'SEED'
? t('brainstorm.seedNodeBadge')
: d.title.length > 18
? d.title.substring(0, 18) + '...'
: d.title
@@ -476,7 +478,7 @@ export const WaveCanvas: React.FC<WaveCanvasProps> = ({
return () => {
simulation.stop()
}
}, [sessionId, ideasKey, isDark, toSvgCoords, toScreenCoords, playbackIdeas])
}, [sessionId, ideasKey, isDark, toSvgCoords, toScreenCoords, playbackIdeas, language, t])
useEffect(() => {
if (!nodeRef.current) return
@@ -533,13 +535,13 @@ export const WaveCanvas: React.FC<WaveCanvasProps> = ({
>
<div className="w-[260px] bg-white dark:bg-[#1A1A1A] rounded-2xl shadow-2xl border border-black/10 dark:border-white/10 overflow-hidden">
<div className="px-3.5 pt-3 pb-1 flex items-center gap-2">
<div className="w-5 h-5 rounded-md bg-memento-blue/10 flex items-center justify-center">
<div className="w-5 h-5 rounded-md bg-brand-accent/10 flex items-center justify-center">
<svg width="10" height="10" viewBox="0 0 24 24" fill="none" stroke="#3b82f6" strokeWidth="2.5" strokeLinecap="round">
<path d="M12 5v14M5 12h14" />
</svg>
</div>
<span className="text-[10px] font-bold uppercase tracking-[0.15em] text-foreground/50">
{editingNode.parentId ? 'Réponse' : 'Nouvelle idée'}
{editingNode.parentId ? t('brainstorm.canvasEditTitleReply') : t('brainstorm.canvasEditTitleNewIdea')}
</span>
</div>
<div className="px-3.5 pb-3">
@@ -551,19 +553,19 @@ export const WaveCanvas: React.FC<WaveCanvasProps> = ({
if (e.key === 'Enter' && editText.trim()) handleSubmitIdea()
if (e.key === 'Escape') { setEditingNode(null); setEditText('') }
}}
placeholder={editingNode.parentId ? 'Votre réponse…' : 'Votre idée…'}
className="w-full px-3 py-2.5 text-sm font-serif bg-black/[0.03] dark:bg-white/[0.06] border border-black/[0.06] dark:border-white/[0.12] rounded-xl outline-none focus:border-memento-blue/50 focus:bg-white dark:focus:bg-white/[0.08] transition-all placeholder:text-foreground/25 text-foreground"
placeholder={editingNode.parentId ? t('brainstorm.canvasPlaceholderReply') : t('brainstorm.canvasPlaceholderIdea')}
className="w-full px-3 py-2.5 text-sm font-serif bg-black/[0.03] dark:bg-white/[0.06] border border-black/[0.06] dark:border-white/[0.12] rounded-xl outline-none focus:border-brand-accent/50 focus:bg-white dark:focus:bg-white/[0.08] transition-all placeholder:text-foreground/25 text-foreground"
/>
<div className="flex items-center justify-between mt-1.5 px-0.5">
<div className="flex items-center gap-2.5">
<kbd className="text-[9px] text-foreground/30 font-mono bg-black/[0.04] px-1.5 py-0.5 rounded"></kbd>
<span className="text-[9px] text-foreground/25">enregistrer</span>
<span className="text-[9px] text-foreground/25">{t('brainstorm.canvasShortcutSave')}</span>
<kbd className="text-[9px] text-foreground/30 font-mono bg-black/[0.04] px-1.5 py-0.5 rounded">esc</kbd>
<span className="text-[9px] text-foreground/25">annuler</span>
<span className="text-[9px] text-foreground/25">{t('brainstorm.canvasShortcutCancel')}</span>
</div>
{editingNode.parentId && (
<span className="text-[9px] font-medium text-memento-blue/60 flex items-center gap-0.5">
enfant
<span className="text-[9px] font-medium text-brand-accent/60 flex items-center gap-0.5">
{t('brainstorm.canvasChildBranch')}
</span>
)}
</div>
@@ -577,7 +579,7 @@ export const WaveCanvas: React.FC<WaveCanvasProps> = ({
<div className="absolute bottom-6 left-6 pointer-events-none">
<p className="text-[10px] font-bold tracking-[0.3em] uppercase text-gray-400 dark:text-gray-600 opacity-60">
Double-clic pour ajouter une idée
{t('brainstorm.canvasDoubleClickHint')}
</p>
</div>
</div>