feat(site,docs): aligne le site vitrine et la doc sur l'app « Emerald »

Site (packages/site) : adopte le design system Emerald (polices Inter +
JetBrains Mono variables, tokens sémantiques, thème clair/sombre + bascule)
et met les mockups à jour sur l'app réelle.

- style.css : tokens Emerald (@theme sombre + override html[data-theme=light]) ;
  lib/theme.ts + ThemeToggle.vue + anti-FOUC index.html ; sweep des couleurs
  brutes vers les tokens dans toutes les sections.
- Mockups fidèles à l'IDE multi-projet : HeroMockup (rail ActivityBar au lieu
  de la sidebar large + v obsolète retirée), ShowcaseSection (supervision au
  lieu du dashboard worktree-first, onglets mobiles réels), WorkspaceShowcase
  (diff-add/del, bouton commit accent-solid) ; framing « worktree-first »
  résiduel levé (i18n).
- og-cover.png rafraîchi (carte Emerald).

Docs : README.md + README.fr.md (retrait « Status: MVP », ajout du langage
Emerald + thème clair/sombre/système, VSIX 0.2.0 -> 0.3.0, section Screenshots),
vscode README (VSIX 0.3.0), brand README (thème clair), CHANGELOG daemon 3.2.0.
Captures IDE sombre + clair (brand/screenshot-ide-*.png).
This commit is contained in:
2026-07-20 22:48:59 +02:00
parent 063f5e928b
commit adc53b413e
37 changed files with 887 additions and 519 deletions
+109 -126
View File
@@ -4,35 +4,47 @@ import { useI18n } from 'vue-i18n';
import { useHeroTimeline, type SessionState } from '../composables/useHeroTimeline';
import { DLG_OPTS } from '../i18n/content';
import type { AppLocale } from '../i18n';
import IconGitea from './icons/IconGitea.vue';
const { t, locale } = useI18n();
const { anim } = useHeroTimeline('hero-stage');
// Couleurs des lignes de terminal par type (porté de renderVals.C).
// Couleurs des lignes de terminal par type, tokenisées (suivent le thème clair/sombre).
const LINE_COLORS: Record<string, string> = {
cmd: '#52525b',
tool: '#a1a1aa',
edit: '#34d399',
add: '#34d399',
del: '#f87171',
ok: '#34d399',
warn: '#fcd34d',
run: '#7dd3fc',
cmd: 'var(--color-fg-subtle)',
tool: 'var(--color-fg-muted)',
edit: 'var(--color-accent)',
add: 'var(--color-accent)',
del: 'var(--color-danger)',
ok: 'var(--color-accent)',
warn: 'var(--color-warn)',
run: 'var(--color-info)',
};
// Couleurs alignées sur SessionStateBadge de l'app (zinc/emerald/amber/sky de Tailwind).
const PILL: Record<SessionState, { bg: string; fg: string; dot: string; pulse: string }> = {
idle: { bg: '#022c22', fg: '#34d399', dot: '#34d399', pulse: '' },
busy: { bg: '#082f49', fg: '#7dd3fc', dot: '#7dd3fc', pulse: 'pulseSky 2s ease-in-out infinite' },
waiting: { bg: '#451a03', fg: '#fcd34d', dot: '#fcd34d', pulse: 'pulseAmber 2.2s ease-in-out infinite' },
// Pastille d'état, alignée sur SessionStateBadge + lib/status-tokens de l'app
// (waiting -> warn, busy -> info, idle -> accent), via color-mix pour le fond teinté.
const PILL: Record<SessionState, { bg: string; fg: string; pulse: string }> = {
idle: {
bg: 'color-mix(in oklab, var(--color-accent) 15%, transparent)',
fg: 'var(--color-accent)',
pulse: '',
},
busy: {
bg: 'color-mix(in oklab, var(--color-info) 15%, transparent)',
fg: 'var(--color-info)',
pulse: 'pulseSky 2s ease-in-out infinite',
},
waiting: {
bg: 'color-mix(in oklab, var(--color-warn) 15%, transparent)',
fg: 'var(--color-warn)',
pulse: 'pulseAmber 2.2s ease-in-out infinite',
},
};
const pill = computed(() => PILL[anim.value.sess]);
const sessText = computed(() => t(anim.value.sess));
const termLines = computed(() =>
anim.value.lines.map((l) => ({ text: l.text, color: LINE_COLORS[l.k] ?? '#d4d4d8' })),
anim.value.lines.map((l) => ({ text: l.text, color: LINE_COLORS[l.k] ?? 'var(--color-fg-muted)' })),
);
// Options du dialogue de permission : reproduit DialogPrompt (boutons numérotés + Deny).
@@ -48,137 +60,108 @@ const dlgOptions = computed(() =>
<template>
<div id="hero-stage" class="relative min-w-[300px] flex-[1_1_480px]">
<div
class="relative overflow-hidden rounded-[14px] border border-zinc-800 bg-zinc-950 shadow-hero"
>
<div class="relative overflow-hidden rounded-[14px] border border-border bg-surface-0 shadow-hero">
<!-- barre de fenêtre -->
<div class="flex items-center gap-2 border-b border-[#1c1c1f] bg-[#0c0c0e] px-[14px] py-[11px]">
<span class="h-2.5 w-2.5 rounded-full bg-zinc-700"></span>
<span class="h-2.5 w-2.5 rounded-full bg-zinc-700"></span>
<span class="h-2.5 w-2.5 rounded-full bg-zinc-700"></span>
<span class="ml-2 font-mono text-[11.5px] text-zinc-600">arboretum · localhost:7317</span>
<div class="flex items-center gap-2 border-b border-border-soft bg-surface-1 px-[14px] py-[11px]">
<span class="h-2.5 w-2.5 rounded-full bg-danger"></span>
<span class="h-2.5 w-2.5 rounded-full bg-warn"></span>
<span class="h-2.5 w-2.5 rounded-full bg-accent"></span>
<span class="ml-2 font-mono text-[11.5px] text-fg-subtle">arboretum · localhost:7317</span>
</div>
<div class="flex min-h-[440px]">
<!-- sidebar (fidèle à AppSidebar : Worktrees / Sessions / Groups, puis Réglages / Aide / Gitea / Café) -->
<div
class="flex w-[190px] flex-none flex-col border-r border-[#1c1c1f] bg-zinc-900/40 px-2 py-3"
>
<div class="flex items-center gap-2 px-2 pb-3">
<img
src="/assets/arboretum-mark.png"
alt=""
width="22"
height="22"
class="h-[22px] w-[22px] object-contain"
/>
<span class="text-[14px] font-semibold text-zinc-100">Arboretum</span>
<!-- rail ActivityBar (fidèle à ActivityBar.vue : icônes explorer / git / sessions / groups) -->
<div class="flex w-12 flex-none flex-col items-center gap-1 border-r border-border bg-surface-1 py-2">
<!-- explorer (actif) -->
<div class="relative flex h-9 w-9 items-center justify-center rounded-[9px] bg-surface-2 text-accent">
<span class="absolute top-1/2 left-0 h-5 w-0.5 -translate-y-1/2 rounded-full bg-accent"></span>
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><rect width="18" height="18" x="3" y="3" rx="2" /><path d="M3 9h18" /><path d="M9 21V9" /></svg>
</div>
<div
class="mb-2 flex items-center gap-2 rounded-lg border border-zinc-800 bg-zinc-950/40 px-2.5 py-1.5"
>
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="#52525b" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><circle cx="11" cy="11" r="8" /><path d="m21 21-4.3-4.3" /></svg>
<span class="flex-1 text-[12px] text-zinc-500">{{ t('mSearch') }}</span>
<span class="rounded border border-zinc-700 px-[5px] py-px font-mono text-[10px] text-zinc-500">⌘K</span>
<!-- git -->
<div class="flex h-9 w-9 items-center justify-center rounded-[9px] text-fg-subtle">
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><line x1="6" x2="6" y1="3" y2="15" /><circle cx="18" cy="6" r="3" /><circle cx="6" cy="18" r="3" /><path d="M18 9a9 9 0 0 1-9 9" /></svg>
</div>
<!-- nav primaire (fidèle à AppSidebar : IDE actif, puis Worktrees / Sessions / Groups) -->
<div class="flex flex-col gap-1">
<div class="flex items-center gap-2.5 rounded-lg bg-zinc-800 px-2.5 py-1.5 text-zinc-100">
<svg width="17" height="17" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><rect width="18" height="18" x="3" y="3" rx="2" /><path d="M3 9h18" /><path d="M9 21V9" /></svg>
<span class="flex-1 text-[12.5px] font-medium">{{ t('mIde') }}</span>
</div>
<div class="flex items-center gap-2.5 rounded-lg px-2.5 py-1.5 text-zinc-400">
<svg width="17" height="17" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><line x1="6" x2="6" y1="3" y2="15" /><circle cx="18" cy="6" r="3" /><circle cx="6" cy="18" r="3" /><path d="M18 9a9 9 0 0 1-9 9" /></svg>
<span class="flex-1 text-[12.5px] font-medium">{{ t('mWorktrees') }}</span>
</div>
<div class="flex items-center gap-2.5 rounded-lg px-2.5 py-1.5 text-zinc-400">
<svg width="17" height="17" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="m7 11 2-2-2-2" /><path d="M11 13h4" /><rect width="18" height="18" x="3" y="3" rx="2" ry="2" /></svg>
<span class="flex-1 text-[12.5px] font-medium">{{ t('mSessions') }}</span>
<span
v-show="anim.att > 0"
class="rounded-full bg-amber-500/20 px-1.5 text-[11px] font-semibold text-amber-300"
>{{ anim.att }}</span
>
</div>
<div class="flex items-center gap-2.5 rounded-lg px-2.5 py-1.5 text-zinc-400">
<svg width="17" height="17" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M2.97 12.92A2 2 0 0 0 2 14.63v3.24a2 2 0 0 0 .97 1.71l3 1.8a2 2 0 0 0 2.06 0L12 19v-5.5l-5-3-4.03 2.42Z" /><path d="M7 16.5 12 13.5" /><path d="M12 13.5V19l3.97 2.38a2 2 0 0 0 2.06 0l3-1.8a2 2 0 0 0 .97-1.71v-3.24a2 2 0 0 0-.97-1.71L17 10.5l-5 3Z" /><path d="m17 16.5 4.74-2.85" /><path d="M7.97 4.42A2 2 0 0 0 7 6.13v4.37l5 3 5-3V6.13a2 2 0 0 0-.97-1.71l-3-1.8a2 2 0 0 0-2.06 0z" /></svg>
<span class="flex-1 text-[12.5px] font-medium">{{ t('mGroups') }}</span>
</div>
<!-- sessions (+ badge attention) -->
<div class="relative flex h-9 w-9 items-center justify-center rounded-[9px] text-fg-subtle">
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="m7 11 2-2-2-2" /><path d="M11 13h4" /><rect width="18" height="18" x="3" y="3" rx="2" ry="2" /></svg>
<span v-show="anim.att > 0" class="absolute top-1 right-1 flex h-3.5 min-w-3.5 items-center justify-center rounded-full bg-warn px-1 text-[9px] font-semibold text-zinc-950">{{ anim.att }}</span>
</div>
<!-- groups -->
<div class="flex h-9 w-9 items-center justify-center rounded-[9px] text-fg-subtle">
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M2.97 12.92A2 2 0 0 0 2 14.63v3.24a2 2 0 0 0 .97 1.71l3 1.8a2 2 0 0 0 2.06 0L12 19v-5.5l-5-3-4.03 2.42Z" /><path d="M7 16.5 12 13.5" /><path d="M12 13.5V19l3.97 2.38a2 2 0 0 0 2.06 0l3-1.8a2 2 0 0 0 .97-1.71v-3.24a2 2 0 0 0-.97-1.71L17 10.5l-5 3Z" /><path d="m17 16.5 4.74-2.85" /><path d="M7.97 4.42A2 2 0 0 0 7 6.13v4.37l5 3 5-3V6.13a2 2 0 0 0-.97-1.71l-3-1.8a2 2 0 0 0-2.06 0z" /></svg>
</div>
<div class="flex-1"></div>
<!-- nav secondaire -->
<div class="flex flex-col gap-1">
<div class="flex items-center gap-2.5 rounded-lg px-2.5 py-1.5 text-zinc-400">
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M12.22 2h-.44a2 2 0 0 0-2 2v.18a2 2 0 0 1-1 1.73l-.43.25a2 2 0 0 1-2 0l-.15-.08a2 2 0 0 0-2.73.73l-.22.38a2 2 0 0 0 .73 2.73l.15.1a2 2 0 0 1 1 1.72v.51a2 2 0 0 1-1 1.74l-.15.09a2 2 0 0 0-.73 2.73l.22.38a2 2 0 0 0 2.73.73l.15-.08a2 2 0 0 1 2 0l.43.25a2 2 0 0 1 1 1.73V20a2 2 0 0 0 2 2h.44a2 2 0 0 0 2-2v-.18a2 2 0 0 1 1-1.73l.43-.25a2 2 0 0 1 2 0l.15.08a2 2 0 0 0 2.73-.73l.22-.39a2 2 0 0 0-.73-2.73l-.15-.08a2 2 0 0 1-1-1.74v-.5a2 2 0 0 1 1-1.74l.15-.09a2 2 0 0 0 .73-2.73l-.22-.38a2 2 0 0 0-2.73-.73l-.15.08a2 2 0 0 1-2 0l-.43-.25a2 2 0 0 1-1-1.73V4a2 2 0 0 0-2-2z" /><circle cx="12" cy="12" r="3" /></svg>
<span class="flex-1 text-[12.5px] font-medium">{{ t('mSettings') }}</span>
</div>
<div class="flex items-center gap-2.5 rounded-lg px-2.5 py-1.5 text-zinc-400">
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><circle cx="12" cy="12" r="10" /><path d="m4.93 4.93 4.24 4.24" /><path d="m14.83 9.17 4.24-4.24" /><path d="m14.83 14.83 4.24 4.24" /><path d="m9.17 14.83-4.24 4.24" /><circle cx="12" cy="12" r="4" /></svg>
<span class="flex-1 text-[12.5px] font-medium">{{ t('mHelp') }}</span>
</div>
<div class="flex items-center gap-2.5 rounded-lg px-2.5 py-1.5 text-zinc-400">
<IconGitea :size="16" />
<span class="flex-1 text-[12.5px] font-medium">{{ t('mGitea') }}</span>
</div>
<div class="flex items-center gap-2.5 rounded-lg px-2.5 py-1.5 text-zinc-400">
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M10 2v2" /><path d="M14 2v2" /><path d="M16 8a1 1 0 0 1 1 1v8a4 4 0 0 1-4 4H7a4 4 0 0 1-4-4V9a1 1 0 0 1 1-1h14a4 4 0 1 1 0 8h-1" /><path d="M6 2v2" /></svg>
<span class="flex-1 text-[12.5px] font-medium">{{ t('coffee') }}</span>
</div>
<!-- bas : thème / réglages / aide -->
<div class="flex h-9 w-9 items-center justify-center rounded-[9px] text-fg-subtle">
<svg width="17" height="17" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79Z" /></svg>
</div>
<div class="flex h-9 w-9 items-center justify-center rounded-[9px] text-fg-subtle">
<svg width="17" height="17" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><circle cx="12" cy="12" r="3" /><path d="M12.22 2h-.44a2 2 0 0 0-2 2v.18a2 2 0 0 1-1 1.73l-.43.25a2 2 0 0 1-2 0l-.15-.08a2 2 0 0 0-2.73.73l-.22.38a2 2 0 0 0 .73 2.73l.15.1a2 2 0 0 1 1 1.72v.51a2 2 0 0 1-1 1.74l-.15.09a2 2 0 0 0-.73 2.73l.22.38a2 2 0 0 0 2.73.73l.15-.08a2 2 0 0 1 2 0l.43.25a2 2 0 0 1 1 1.73V20a2 2 0 0 0 2 2h.44a2 2 0 0 0 2-2v-.18a2 2 0 0 1 1-1.73l.43-.25a2 2 0 0 1 2 0l.15.08a2 2 0 0 0 2.73-.73l.22-.39a2 2 0 0 0-.73-2.73l-.15-.08a2 2 0 0 1-1-1.74v-.5a2 2 0 0 1 1-1.74l.15-.09a2 2 0 0 0 .73-2.73l-.22-.38a2 2 0 0 0-2.73-.73l-.15.08a2 2 0 0 1-2 0l-.43-.25a2 2 0 0 1-1-1.73V4a2 2 0 0 0-2-2z" /></svg>
</div>
</div>
<!-- pied : langue · notifications · déconnexion + version (fidèle à AppShellFooter) -->
<div class="mt-2 flex items-center gap-2 border-t border-[#1c1c1f] px-1 pt-2.5">
<span class="rounded border border-zinc-700 px-1.5 py-px font-mono text-[10px] text-zinc-400">{{ locale.toUpperCase() }}</span>
<svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="#34d399" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M10.268 21a2 2 0 0 0 3.464 0" /><path d="M3.262 15.326A1 1 0 0 0 4 17h16a1 1 0 0 0 .74-1.673C19.41 13.956 18 12.499 18 8A6 6 0 0 0 6 8c0 4.499-1.411 5.956-2.738 7.326" /></svg>
<svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="#71717a" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M9 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4" /><polyline points="16 17 21 12 16 7" /><line x1="21" x2="9" y1="12" y2="12" /></svg>
<span class="ml-auto font-mono text-[10px] text-zinc-600">v2.0.0</span>
<!-- panneau Projects (fidèle à ProjectTree : arbre projet -> worktree -> session) -->
<div class="flex w-[176px] flex-none flex-col border-r border-border bg-surface-1 py-2">
<div class="label-mono px-3 pb-2">{{ t('mProjects') }}</div>
<div class="flex flex-col gap-px px-1 text-[12px]">
<div class="flex items-center gap-1.5 rounded px-2 py-1 text-fg-muted">
<svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="m6 9 6 6 6-6" /></svg>
<svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M4 3h16a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2Z" /><circle cx="12" cy="10" r="2" /><path d="M12 12v4" /></svg>
<span class="truncate">api</span>
</div>
<div class="flex items-center gap-1.5 rounded bg-surface-2 px-2 py-1 pl-5 text-fg">
<svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="var(--color-accent)" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><line x1="6" x2="6" y1="3" y2="15" /><circle cx="18" cy="6" r="3" /><circle cx="6" cy="18" r="3" /><path d="M18 9a9 9 0 0 1-9 9" /></svg>
<span class="truncate font-mono text-accent">feat/auth</span>
</div>
<div class="flex items-center gap-1.5 rounded px-2 py-0.5 pl-9 text-[11px] text-fg-muted">
<span class="h-1.5 w-1.5 flex-none rounded-full" :style="{ background: pill.fg, animation: pill.pulse }"></span>
<span class="truncate font-mono">claude</span>
</div>
<div class="flex items-center gap-1.5 rounded px-2 py-1 text-fg-muted">
<svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="m9 18 6-6-6-6" /></svg>
<svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M4 3h16a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2Z" /><circle cx="12" cy="10" r="2" /><path d="M12 12v4" /></svg>
<span class="truncate">web</span>
</div>
<div class="flex items-center gap-1.5 rounded px-2 py-1 text-fg-muted">
<svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="m9 18 6-6-6-6" /></svg>
<svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M4 3h16a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2Z" /><circle cx="12" cy="10" r="2" /><path d="M12 12v4" /></svg>
<span class="truncate">docs</span>
</div>
</div>
</div>
<!-- main -->
<div class="flex min-w-0 flex-1 flex-col gap-[11px] p-[13px]">
<div class="flex min-w-0 flex-1 flex-col gap-[11px] bg-surface-0 p-[13px]">
<!-- terminal pane -->
<div
class="flex min-h-0 flex-1 flex-col overflow-hidden rounded-[10px] border border-zinc-800 bg-zinc-950"
>
<div class="flex items-center justify-between border-b border-[#1c1c1f] px-[11px] py-2">
<span class="font-mono text-[11.5px] text-zinc-300">api · feat/auth</span>
<div class="flex min-h-0 flex-1 flex-col overflow-hidden rounded-[10px] border border-border bg-surface-0">
<div class="flex items-center justify-between border-b border-border-soft px-[11px] py-2">
<span class="font-mono text-[11.5px] text-fg-muted">api · feat/auth</span>
<span
class="inline-flex items-center gap-1.5 rounded px-2 py-[3px] font-mono text-[11px]"
class="inline-flex items-center gap-1.5 rounded-full px-2 py-[3px] font-mono text-[11px]"
:style="{ background: pill.bg, color: pill.fg }"
>
<span
class="h-1.5 w-1.5 flex-none rounded-full"
:style="{ background: pill.dot, animation: pill.pulse }"
></span>
<span class="h-1.5 w-1.5 flex-none rounded-full" :style="{ background: pill.fg, animation: pill.pulse }"></span>
{{ sessText }}
</span>
</div>
<div
class="flex min-h-[150px] flex-1 flex-col justify-end overflow-hidden p-[11px] font-mono text-xs leading-[1.7] text-zinc-300"
>
<div class="flex min-h-[150px] flex-1 flex-col justify-end overflow-hidden p-[11px] font-mono text-xs leading-[1.7] text-fg-muted">
<div v-for="(ln, i) in termLines" :key="i" :style="{ color: ln.color, whiteSpace: 'pre' }">
{{ ln.text }}
</div>
<div v-if="anim.cur">
<span class="text-emerald-400">$</span>
<span class="ml-1 inline-block h-[13px] w-[7px] animate-blink align-middle bg-zinc-200"></span>
<span class="text-accent">$</span>
<span class="ml-1 inline-block h-[13px] w-[7px] animate-blink bg-fg align-middle"></span>
</div>
</div>
</div>
<!-- dialogue de permission (fidèle à DialogPrompt : badge type + question + options + Deny) -->
<div
v-if="anim.dlg"
class="animate-dlg-in rounded-lg border border-amber-900/60 bg-amber-950/30 p-[11px]"
>
<!-- dialogue de permission (fidèle à DialogPrompt) -->
<div v-if="anim.dlg" class="animate-dlg-in rounded-lg border border-warn/40 bg-warn/10 p-[11px]">
<div class="mb-2 flex items-center gap-2">
<span class="inline-flex items-center rounded bg-amber-900 px-1.5 py-0.5 text-[11px] font-medium text-amber-200">{{ t('mPermission') }}</span>
<span class="text-[12.5px] text-amber-100">{{ t('dlgQ') }}</span>
<span class="inline-flex items-center rounded-full bg-warn/15 px-1.5 py-0.5 font-mono text-[11px] text-warn">{{ t('mPermission') }}</span>
<span class="text-[12.5px] text-fg">{{ t('dlgQ') }}</span>
</div>
<div class="flex flex-wrap gap-[6px]">
<span
@@ -186,15 +169,15 @@ const dlgOptions = computed(() =>
:key="i"
class="inline-flex items-center gap-1.5 rounded-lg border px-2.5 py-1.5 text-xs font-medium transition-colors"
:class="op.answered
? 'border-emerald-500/70 bg-emerald-950/50 text-emerald-300'
? 'border-accent/70 bg-accent/15 text-accent'
: op.highlighted
? 'border-amber-400 bg-amber-950/50 text-amber-200'
: 'border-zinc-700 bg-zinc-800 text-zinc-200'"
? 'border-warn bg-warn/15 text-warn'
: 'border-border bg-surface-2 text-fg'"
>
<span class="font-mono" :class="op.answered ? 'text-emerald-400' : 'text-amber-400'">{{ op.num }}</span>
<span class="font-mono" :class="op.answered ? 'text-accent' : 'text-warn'">{{ op.num }}</span>
{{ op.text }}
</span>
<span class="inline-flex items-center rounded-lg border border-red-900 bg-red-950 px-2.5 py-1.5 text-xs font-medium text-red-300">{{ t('mDeny') }}</span>
<span class="inline-flex items-center rounded-lg border border-danger/40 bg-danger/10 px-2.5 py-1.5 text-xs font-medium text-danger">{{ t('mDeny') }}</span>
</div>
</div>
</div>
@@ -204,18 +187,18 @@ const dlgOptions = computed(() =>
<!-- toast push -->
<div
v-if="anim.toast"
class="animate-toast-in absolute bottom-[14px] right-[14px] flex w-[248px] items-start gap-2.5 rounded-[11px] border border-[rgba(120,53,15,0.5)] bg-[#0c0c0e] p-3 shadow-toast"
class="animate-toast-in absolute right-[14px] bottom-[14px] flex w-[248px] items-start gap-2.5 rounded-[11px] border border-border bg-surface-1 p-3 shadow-toast"
>
<span class="inline-flex h-[30px] w-[30px] flex-none items-center justify-center rounded-lg bg-emerald-500/15">
<span class="inline-flex h-[30px] w-[30px] flex-none items-center justify-center rounded-lg bg-accent/15">
<img src="/assets/arboretum-mark.png" alt="" width="18" height="18" class="h-[18px] w-[18px] object-contain" />
</span>
<div class="min-w-0 flex-1">
<div class="flex items-center justify-between">
<span class="font-mono text-[11px] text-emerald-400">Arboretum</span>
<span class="text-[10px] text-zinc-600">now</span>
<span class="font-mono text-[11px] text-accent">Arboretum</span>
<span class="text-[10px] text-fg-subtle">now</span>
</div>
<div class="mt-[3px] text-[13px] font-semibold text-zinc-100">{{ t('toastTitle') }}</div>
<div class="mt-px text-[11.5px] leading-[1.4] text-zinc-400">{{ t('toastBody') }}</div>
<div class="mt-[3px] text-[13px] font-semibold text-fg">{{ t('toastTitle') }}</div>
<div class="mt-px text-[11.5px] leading-[1.4] text-fg-muted">{{ t('toastBody') }}</div>
</div>
</div>
</div>