Thème Nocturne clair (Claude Design) à la place du néo-brutaliste

Reprend les jetons de « Loki App.dc.html » : fond gris froid #f7f8fa,
surfaces blanches, accent bleu ardoise #2f4a7a (au lieu de l'orange),
filets 1 px #e3e6eb (au lieu des bordures noires 3 px) et ombres douces
diffuses (au lieu des ombres dures décalées).

- tailwind.config.ts : les NOMS de jetons sont conservés, seules leurs
  valeurs basculent — toute l'interface suit sans réécrire les
  composants. Les jetons historiquement sombres (card-deep, on-dark…)
  deviennent la surface sélectionnée claire et son encre.
- Police unique Inter ; l'ex-« font-pixel » devient le kicker de la
  maquette (petites capitales espacées de 0.14em), donc les libellés
  existants suivent sans modification.
- Conversion mécanique des filets 3 px / 2 px vers 1 px, séparateurs
  épais affinés, logo et avatar refaits selon la maquette (carré teinté
  à filet accent), couleurs « papier » de l'aperçu passées en jetons.
- Texte blanc corrigé partout où il reposait sur une surface devenue
  claire ; conservé sur les fonds accent/warn où il reste lisible.

Vérifié au rendu : body #f7f8fa, encre #1c2536, surface #ffffff, Inter ;
plus aucune trace d'orange, de noir #18181b ni d'ombre dure.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SVay7z3y7q2gEe54ByAE6N
This commit is contained in:
Claude committed 2026-08-03 09:06:46 +00:00
1 parent 174a3d4a35
commit 7615bcfbbb
16 files changed
+254 -215

No files matched your search

+4 -4
View File
@@ -16,10 +16,10 @@ const items: { id: View; label: string; icon: React.ReactNode }[] = [
];
const btn = (on: boolean) =>
`flex h-10 w-10 items-center justify-center border-[3px] ${
`flex h-10 w-10 items-center justify-center border ${
on
? "border-white bg-accent text-white shadow-accent-soft"
: "border-chrome-3 text-on-dark-2 hover:text-white"
: "border-chrome-3 text-on-dark-2 hover:text-ink"
}`;
/** Barre d'activité verticale (60px) sombre à gauche. */
@@ -31,7 +31,7 @@ export function ActivityBar({
onChange: (v: View) => void;
}) {
return (
<div className="flex w-[60px] flex-none flex-col items-center gap-2 border-r-[3px] border-line bg-bar py-3">
<div className="flex w-[60px] flex-none flex-col items-center gap-2 border-r border-line bg-bar py-3">
{items.map((it) => (
<button
key={it.id}
@@ -55,7 +55,7 @@ export function ActivityBar({
<SettingsIcon />
</button>
<div className="font-pixel flex h-[34px] w-[34px] items-center justify-center border-[3px] border-white bg-white text-[11px] text-line">
<div className="font-pixel flex h-[34px] w-[34px] items-center justify-center border border-line bg-line-soft text-[11px] text-ink-3">
M
</div>
</div>
+9 -6
View File
@@ -104,20 +104,23 @@ export const CheckIcon = ({ size = 14, className }: Props) => (
</svg>
);
/** Logo Loki : carré orange à bordure blanche + carré interne (néo-brutaliste). */
/** Logo Loki : carré teinté à filet accent + petit carré accent (maquette). */
export const LokiMark = ({ size = 30 }: { size?: number }) => (
<div
className="flex items-center justify-center bg-accent"
className="grid place-items-center border border-accent bg-accent-ghost"
style={{
width: size,
height: size,
border: "3px solid #fff",
boxShadow: "3px 3px 0 #ff5436",
borderRadius: 7,
borderRadius: Math.round(size * 0.27),
}}
>
<div
style={{ width: size * 0.3, height: size * 0.3, background: "#fff" }}
className="bg-accent"
style={{
width: size * 0.3,
height: size * 0.3,
borderRadius: 2,
}}
/>
</div>
);
+4 -4
View File
@@ -45,15 +45,15 @@ function CodeBlock({ lang, code }: { lang: string; code: string }) {
};
return (
<div className="my-2 overflow-hidden border-[3px] border-line bg-card-deep shadow-hard-sm" style={{ borderRadius: 7 }}>
<div className="flex items-center justify-between border-b-2 border-chrome-2 px-3 py-1.5">
<div className="my-2 overflow-hidden border border-line bg-card-deep shadow-hard-sm" style={{ borderRadius: 7 }}>
<div className="flex items-center justify-between border-b border-chrome-2 px-3 py-1.5">
<span className="font-mono text-[10.5px] uppercase tracking-wide text-on-dark-2">
{lang || "code"}
</span>
<button
type="button"
onClick={copy}
className="flex items-center gap-1 rounded-md px-1.5 py-0.5 text-[11px] text-on-dark-2 transition-colors hover:text-white"
className="flex items-center gap-1 rounded-md px-1.5 py-0.5 text-[11px] text-on-dark-2 transition-colors hover:text-ink"
>
{copied ? <CheckIcon size={13} /> : <CopyIcon size={13} />}
{failed ? "Erreur" : copied ? "Copié" : "Copier"}
@@ -122,7 +122,7 @@ const components: Components = {
),
em: ({ children }) => <em className="italic">{children}</em>,
blockquote: ({ children }) => (
<blockquote className="my-2 border-l-2 border-line-strong pl-3 text-muted">
<blockquote className="my-2 border-l border-line-strong pl-3 text-muted">
{children}
</blockquote>
),
+5 -5
View File
@@ -40,14 +40,14 @@ export function ModelSelector({
onClick={() => setOpen((v) => !v)}
className={
variant === "composer"
? "flex h-8 min-w-0 max-w-[220px] items-center gap-1.5 border-2 border-line bg-accent px-2.5 text-[13px] text-white"
: "flex h-[34px] min-w-0 max-w-[260px] items-center gap-2 border-[3px] border-white bg-accent px-3 text-white shadow-accent-soft"
? "flex h-8 min-w-0 max-w-[220px] items-center gap-1.5 border border-line bg-accent px-2.5 text-[13px] text-white"
: "flex h-[34px] min-w-0 max-w-[260px] items-center gap-2 border border-white bg-accent px-3 text-white shadow-accent-soft"
}
title={selectedModel || undefined}
style={{ borderRadius: 7 }}
>
<span
className={`h-2.5 w-2.5 border-2 border-line ${
className={`h-2.5 w-2.5 border border-line ${
warmingModel === selectedModel
? "bg-accent animate-pulse"
: selectedLoaded
@@ -74,7 +74,7 @@ export function ModelSelector({
{open && (
<div
className={`absolute z-20 w-64 border-[3px] border-line bg-card p-1 shadow-hard ${
className={`absolute z-20 w-64 border border-line bg-card p-1 shadow-hard ${
variant === "composer"
? "bottom-[calc(100%+6px)] left-0"
: "right-0 top-11"
@@ -97,7 +97,7 @@ export function ModelSelector({
}`}
>
<span
className={`h-2 w-2 border-2 border-line ${
className={`h-2 w-2 border border-line ${
m.name === selectedModel ? "bg-accent" : "bg-card"
}`}
/>
+5 -5
View File
@@ -52,7 +52,7 @@ export function ProjectChip() {
<div ref={rootRef} className="relative">
<button
onClick={() => setOpen((o) => !o)}
className="flex h-8 items-center gap-1.5 border-2 border-line bg-base px-2.5 text-[12px] text-ink-2"
className="flex h-8 items-center gap-1.5 border border-line bg-base px-2.5 text-[12px] text-ink-2"
title="Projet de travail de cette session"
>
📁 <span className="max-w-[140px] truncate">{active ?? "workspace"}</span>
@@ -60,7 +60,7 @@ export function ProjectChip() {
{open && (
<div
className="absolute bottom-[calc(100%+6px)] left-0 z-30 w-[240px] border-[3px] border-line bg-card shadow-hard"
className="absolute bottom-[calc(100%+6px)] left-0 z-30 w-[240px] border border-line bg-card shadow-hard"
style={{ borderRadius: 7 }}
>
<button
@@ -75,7 +75,7 @@ export function ProjectChip() {
<button
key={p.name}
onClick={() => choose(p.name)}
className={`block w-full border-t-2 border-line-soft px-3 py-2 text-left text-[13px] text-ink-2 hover:bg-base ${
className={`block w-full border-t border-line-soft px-3 py-2 text-left text-[13px] text-ink-2 hover:bg-base ${
active === p.name ? "bg-base font-bold" : ""
}`}
>
@@ -85,7 +85,7 @@ export function ProjectChip() {
</span>
</button>
))}
<div className="border-t-2 border-line-soft p-2">
<div className="border-t border-line-soft p-2">
{creating ? (
<input
autoFocus
@@ -99,7 +99,7 @@ export function ProjectChip() {
}
}}
placeholder="nom-du-projet"
className="w-full border-2 border-line bg-base px-2 py-1 text-[12px] text-ink outline-none"
className="w-full border border-line bg-base px-2 py-1 text-[12px] text-ink outline-none"
/>
) : (
<button
+8 -8
View File
@@ -55,7 +55,7 @@ export function SessionMenu() {
<div ref={rootRef} className="relative">
<button
onClick={() => setOpen((o) => !o)}
className="flex cursor-pointer items-center gap-2 text-[13px] text-on-dark hover:text-white"
className="flex cursor-pointer items-center gap-2 text-[13px] text-on-dark hover:text-ink"
title="Sessions"
>
<span className="max-w-[220px] truncate">
@@ -66,7 +66,7 @@ export function SessionMenu() {
{open && (
<div
className="absolute left-0 top-[calc(100%+9px)] z-30 w-[300px] border-[3px] border-line bg-chrome-2 shadow-hard"
className="absolute left-0 top-[calc(100%+9px)] z-30 w-[300px] border border-line bg-chrome-2 shadow-hard"
style={{ borderRadius: 7 }}
>
<button
@@ -74,7 +74,7 @@ export function SessionMenu() {
setOpen(false);
await newSession();
}}
className="flex w-full cursor-pointer items-center gap-2 border-b-[3px] border-chrome-3 px-3 py-2.5 text-[13px] font-bold text-accent hover:bg-chrome-3"
className="flex w-full cursor-pointer items-center gap-2 border-b border-chrome-3 px-3 py-2.5 text-[13px] font-bold text-accent hover:bg-chrome-3"
>
<PlusIcon />
Nouvelle session
@@ -97,7 +97,7 @@ export function SessionMenu() {
setOpen(false);
void openSession(s.id);
}}
className={`group cursor-pointer border-b-2 border-chrome-3 px-3 py-2 last:border-b-0 ${
className={`group cursor-pointer border-b border-chrome-3 px-3 py-2 last:border-b-0 ${
active ? "bg-chrome-3" : "hover:bg-chrome-3"
}`}
>
@@ -116,12 +116,12 @@ export function SessionMenu() {
}
}}
onBlur={() => setEditingId(null)}
className="min-w-0 flex-1 border-2 border-line bg-card-deep px-1.5 py-0.5 text-[13px] text-white outline-none"
className="min-w-0 flex-1 border border-line bg-card-deep px-1.5 py-0.5 text-[13px] text-ink outline-none"
/>
) : (
<span
className={`min-w-0 flex-1 truncate text-[13px] ${
active ? "text-white" : "text-on-dark"
active ? "text-ink" : "text-ink-3"
}`}
>
{s.title}
@@ -129,7 +129,7 @@ export function SessionMenu() {
)}
{working && (
<span
className="flex-none border-2 border-line bg-accent px-1 py-0.5 text-[9px] leading-none text-white"
className="flex-none border border-line bg-accent px-1 py-0.5 text-[9px] leading-none text-white"
title="Session en cours de travail"
>
EN COURS
@@ -141,7 +141,7 @@ export function SessionMenu() {
setEditingId(s.id);
setDraft(s.title);
}}
className="hidden flex-none text-[11px] text-on-dark-3 hover:text-white group-hover:block"
className="hidden flex-none text-[11px] text-on-dark-3 hover:text-ink group-hover:block"
title="Renommer la session"
>
✎
+5 -5
View File
@@ -23,11 +23,11 @@ export function ToolCard({ call }: { call: ToolCall }) {
const write = call.name === "write_file" || call.name === "edit_file";
return (
<div className="mb-[11px] overflow-hidden border-[3px] border-line bg-card shadow-hard-sm" style={{ borderRadius: 7 }}>
<div className="mb-[11px] overflow-hidden border border-line bg-card shadow-hard-sm" style={{ borderRadius: 7 }}>
<div className="flex items-center gap-2.5 px-3 py-2.5">
<span
className={`flex h-[26px] w-[26px] items-center justify-center border-2 border-line ${
write ? "bg-accent text-white" : "bg-card-deep text-white"
className={`flex h-[26px] w-[26px] items-center justify-center border border-line ${
write ? "bg-accent text-white" : "bg-card-deep text-ink"
}`}
>
<ToolGlyph name={call.name} />
@@ -37,7 +37,7 @@ export function ToolCard({ call }: { call: ToolCall }) {
<div className="flex-1" />
{running ? (
<span className="flex items-center gap-1.5 text-[13px] text-muted-2">
<span className="h-2.5 w-2.5 animate-spin rounded-full border-2 border-muted-3 border-t-accent" />
<span className="h-2.5 w-2.5 animate-spin rounded-full border border-muted-3 border-t-accent" />
en cours
</span>
) : pending ? (
@@ -53,7 +53,7 @@ export function ToolCard({ call }: { call: ToolCall }) {
)}
</div>
{call.summary && !running && (
<div className="border-t-2 border-line-soft px-3 py-2 text-[13px] text-muted-2">
<div className="border-t border-line-soft px-3 py-2 text-[13px] text-muted-2">
→ {call.summary}
</div>
)}
+5 -5
View File
@@ -16,10 +16,10 @@ export function TopBar() {
}, []);
return (
<div className="flex h-[54px] flex-none items-center gap-3.5 border-b-[3px] border-line bg-bar px-4">
<div className="flex h-[54px] flex-none items-center gap-3.5 border-b border-line bg-bar px-4">
<div className="flex items-center gap-2.5">
<LokiMark />
<div className="font-pixel text-[14px] text-white">LOKI</div>
<div className="font-pixel text-[14px] text-ink">LOKI</div>
<div
className="text-[13px] leading-none text-on-dark-2"
title={version ? `build ${version}` : undefined}
@@ -39,7 +39,7 @@ export function TopBar() {
{/* Stats système temps réel : CPU, RAM, GPU/VRAM */}
{stats && (
<div className="flex h-8 items-center gap-2.5 border-[3px] border-chrome-3 bg-chrome-2 px-[11px] text-[13px] text-on-dark">
<div className="flex h-8 items-center gap-2.5 border border-chrome-3 bg-chrome-2 px-[11px] text-[13px] text-on-dark">
<span>CPU {stats.cpu_pct.toFixed(0)}%</span>
<span className="text-on-dark-3">·</span>
<span>RAM {stats.ram_pct.toFixed(0)}%</span>
@@ -58,11 +58,11 @@ export function TopBar() {
{/* Statut Ollama */}
<div
className="flex h-8 items-center gap-2 border-[3px] border-chrome-3 bg-chrome-2 px-[11px]"
className="flex h-8 items-center gap-2 border border-chrome-3 bg-chrome-2 px-[11px]"
title={connected ? status?.host : status?.error}
>
<span
className={`h-[11px] w-[11px] border-2 border-line ${
className={`h-[11px] w-[11px] border border-line ${
connected ? "bg-ok" : "bg-warn"
}`}
/>