refactor(site): visuels fidèles à l'app réelle + arguments alignés sur le réel
- HeroMockup : sidebar fidèle (Worktrees actif / Sessions + badge / Groups, puis Réglages / Aide / Gitea / Café) + pied langue·notif·déconnexion·version ; dialogue au format DialogPrompt (badge Permission + options numérotées + Deny) ; couleurs d'état alignées sur SessionStateBadge. - ShowcaseSection : a) dashboard worktree-first (rail « À traiter » + RepoSection + WorktreeCard avec états), b) grille fidèle à TerminalCell (badge d'état texte + repo·branche + commande), c) mobile avec DialogPrompt réel + MobileTabBar. - Retrait de la notion d'IDE (titre des fonctionnalités + FAQ) ; FAQ recentrée sur ce que fait réellement l'app.
This commit is contained in:
@@ -4,6 +4,7 @@ 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');
|
||||
@@ -20,10 +21,11 @@ const LINE_COLORS: Record<string, string> = {
|
||||
run: '#7dd3fc',
|
||||
};
|
||||
|
||||
// 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: 'rgba(2,44,34,.6)', fg: '#34d399', dot: '#34d399', pulse: '' },
|
||||
busy: { bg: 'rgba(8,47,73,.7)', fg: '#7dd3fc', dot: '#7dd3fc', pulse: 'pulseSky 2s ease-in-out infinite' },
|
||||
waiting: { bg: 'rgba(69,26,3,.7)', fg: '#fcd34d', dot: '#fcd34d', pulse: 'pulseAmber 2.2s ease-in-out infinite' },
|
||||
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' },
|
||||
};
|
||||
|
||||
const pill = computed(() => PILL[anim.value.sess]);
|
||||
@@ -33,36 +35,14 @@ const termLines = computed(() =>
|
||||
anim.value.lines.map((l) => ({ text: l.text, color: LINE_COLORS[l.k] ?? '#d4d4d8' })),
|
||||
);
|
||||
|
||||
// Options du dialogue de permission — reproduit DialogPrompt (boutons numérotés + Deny).
|
||||
const dlgOptions = computed(() =>
|
||||
DLG_OPTS[locale.value as AppLocale].map((txt, i) => {
|
||||
const highlighted = anim.value.hl === i;
|
||||
const answered = anim.value.ans === i;
|
||||
const row: Record<string, string> = {
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
gap: '9px',
|
||||
padding: '7px 9px',
|
||||
borderRadius: '7px',
|
||||
border: '1px solid transparent',
|
||||
background: 'rgba(9,9,11,.4)',
|
||||
transition: 'background .2s, border-color .2s',
|
||||
};
|
||||
if (highlighted) {
|
||||
row.background = 'rgba(69,26,3,.5)';
|
||||
row.border = '1px solid rgba(217,119,6,.6)';
|
||||
}
|
||||
if (answered) {
|
||||
row.background = 'rgba(2,44,34,.45)';
|
||||
row.border = '1px solid rgba(5,150,105,.6)';
|
||||
}
|
||||
return {
|
||||
num: answered ? '✓' : String(i + 1),
|
||||
text: txt,
|
||||
rowStyle: row,
|
||||
numColor: answered ? '#34d399' : '#fbbf24',
|
||||
textColor: answered ? '#a7f3d0' : highlighted ? '#fde68a' : '#d4d4d8',
|
||||
};
|
||||
}),
|
||||
DLG_OPTS[locale.value as AppLocale].map((txt, i) => ({
|
||||
num: anim.value.ans === i ? '✓' : String(i + 1),
|
||||
text: txt,
|
||||
highlighted: anim.value.hl === i,
|
||||
answered: anim.value.ans === i,
|
||||
})),
|
||||
);
|
||||
</script>
|
||||
|
||||
@@ -79,59 +59,79 @@ const dlgOptions = computed(() =>
|
||||
<span class="ml-2 font-mono text-[11.5px] text-zinc-600">arboretum · localhost:7317</span>
|
||||
</div>
|
||||
|
||||
<div class="flex min-h-[360px]">
|
||||
<!-- sidebar -->
|
||||
<div class="flex min-h-[440px]">
|
||||
<!-- sidebar (fidèle à AppSidebar : Worktrees / Sessions / Groups, puis Réglages / Aide / Gitea / Café) -->
|
||||
<div
|
||||
class="flex w-[168px] flex-none flex-col border-r border-[#1c1c1f] bg-zinc-900/40 px-2.5 py-3"
|
||||
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-1 pb-3">
|
||||
<div class="flex items-center gap-2 px-2 pb-3">
|
||||
<img
|
||||
src="/assets/arboretum-mark.png"
|
||||
alt=""
|
||||
width="20"
|
||||
height="20"
|
||||
class="h-5 w-5 object-contain"
|
||||
width="22"
|
||||
height="22"
|
||||
class="h-[22px] w-[22px] object-contain"
|
||||
/>
|
||||
<span class="font-mono text-[13px] font-semibold text-zinc-200">Arboretum</span>
|
||||
<span class="text-[14px] font-semibold text-zinc-100">Arboretum</span>
|
||||
</div>
|
||||
|
||||
<div
|
||||
class="mb-3 flex items-center gap-2 rounded-lg border border-zinc-800 bg-zinc-950/50 px-[9px] py-[7px]"
|
||||
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="13" height="13" 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-[11.5px] text-zinc-600">{{ t('mSearch') }}</span>
|
||||
<span class="rounded border border-zinc-800 px-[5px] py-px font-mono text-[10px] text-zinc-500">⌘K</span>
|
||||
<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>
|
||||
</div>
|
||||
|
||||
<div class="flex flex-col gap-0.5">
|
||||
<div class="flex items-center gap-[9px] rounded-lg bg-zinc-800 px-[9px] py-[7px] text-zinc-100">
|
||||
<svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><rect width="7" height="9" x="3" y="3" rx="1" /><rect width="7" height="5" x="14" y="3" rx="1" /><rect width="7" height="9" x="14" y="12" rx="1" /><rect width="7" height="5" x="3" y="16" rx="1" /></svg>
|
||||
<span class="text-[12.5px]">{{ t('mDash') }}</span>
|
||||
<!-- nav primaire -->
|
||||
<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"><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="ml-auto inline-flex h-[17px] min-w-[17px] items-center justify-center rounded-full px-[5px] font-mono text-[10px] font-bold"
|
||||
style="background: #f59e0b; color: #1c1300"
|
||||
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-[9px] rounded-lg px-[9px] py-[7px] text-zinc-400">
|
||||
<svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" 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="text-[12.5px]">{{ t('mGroups') }}</span>
|
||||
<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>
|
||||
</div>
|
||||
|
||||
<div class="flex-1"></div>
|
||||
|
||||
<div class="flex flex-col gap-0.5 border-t border-[#1c1c1f] pt-2.5">
|
||||
<div class="flex items-center gap-[9px] rounded-lg px-[9px] py-1.5 text-zinc-400">
|
||||
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" 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="text-[12.5px]">{{ t('mSettings') }}</span>
|
||||
<!-- 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-[9px] rounded-lg px-[9px] py-1.5 text-zinc-400">
|
||||
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><circle cx="12" cy="12" r="10" /><path d="M9.09 9a3 3 0 0 1 5.83 1c0 2-3 3-3 3" /><path d="M12 17h.01" /></svg>
|
||||
<span class="text-[12.5px]">{{ t('mHelp') }}</span>
|
||||
<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="px-[9px] pt-1.5 font-mono text-[10px] text-zinc-700">v0.4.2</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>
|
||||
</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">v1.6.0</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -142,9 +142,9 @@ const dlgOptions = computed(() =>
|
||||
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-400">api · feat/auth</span>
|
||||
<span class="font-mono text-[11.5px] text-zinc-300">api · feat/auth</span>
|
||||
<span
|
||||
class="inline-flex items-center gap-1.5 rounded-full px-[9px] py-[3px] font-mono text-[11px]"
|
||||
class="inline-flex items-center gap-1.5 rounded px-2 py-[3px] font-mono text-[11px]"
|
||||
:style="{ background: pill.bg, color: pill.fg }"
|
||||
>
|
||||
<span
|
||||
@@ -167,24 +167,30 @@ const dlgOptions = computed(() =>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- dialogue de permission -->
|
||||
<!-- dialogue de permission (fidèle à DialogPrompt : badge type + question + options + Deny) -->
|
||||
<div
|
||||
v-if="anim.dlg"
|
||||
class="animate-dlg-in rounded-[10px] border border-[rgba(120,53,15,0.6)] bg-[rgba(69,26,3,0.3)] p-[11px]"
|
||||
class="animate-dlg-in rounded-lg border border-amber-900/60 bg-amber-950/30 p-[11px]"
|
||||
>
|
||||
<div class="mb-[9px] flex items-center gap-2">
|
||||
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="#fbbf24" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3Z" /><path d="M12 9v4" /><path d="M12 17h.01" /></svg>
|
||||
<span class="text-[12.5px] text-zinc-200">{{ t('dlgQ') }}</span>
|
||||
<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>
|
||||
</div>
|
||||
<div class="flex flex-col gap-[5px]">
|
||||
<div v-for="(op, i) in dlgOptions" :key="i" :style="op.rowStyle">
|
||||
<span
|
||||
class="w-[15px] flex-none text-center font-mono text-[11px] font-bold"
|
||||
:style="{ color: op.numColor }"
|
||||
>{{ op.num }}</span
|
||||
>
|
||||
<span class="text-xs" :style="{ color: op.textColor }">{{ op.text }}</span>
|
||||
</div>
|
||||
<div class="flex flex-wrap gap-[6px]">
|
||||
<span
|
||||
v-for="(op, i) in dlgOptions"
|
||||
: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'
|
||||
: op.highlighted
|
||||
? 'border-amber-400 bg-amber-950/50 text-amber-200'
|
||||
: 'border-zinc-700 bg-zinc-800 text-zinc-200'"
|
||||
>
|
||||
<span class="font-mono" :class="op.answered ? 'text-emerald-400' : 'text-amber-400'">{{ 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>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,67 +1,115 @@
|
||||
<script setup lang="ts">
|
||||
import { computed } from 'vue';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
const { t } = useI18n();
|
||||
import { DLG_OPTS } from '../i18n/content';
|
||||
import type { AppLocale } from '../i18n';
|
||||
|
||||
const { t, locale } = useI18n();
|
||||
|
||||
// Options du dialogue (réutilisées pour le rail « À traiter » et la vue mobile).
|
||||
const dlgOpts = computed(() => DLG_OPTS[locale.value as AppLocale]);
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<section id="showcase" class="mx-auto flex max-w-[1200px] scroll-mt-[84px] flex-col gap-[92px] px-6">
|
||||
<!-- a) dashboard + needs attention -->
|
||||
<!-- a) dashboard worktree-first : rail « À traiter » + section de repo (fidèle à AttentionSection + RepoSection) -->
|
||||
<div v-reveal class="flex flex-wrap items-center gap-12">
|
||||
<div class="min-w-[280px] flex-[1_1_380px]">
|
||||
<div class="min-w-[280px] flex-[1_1_360px]">
|
||||
<div class="mb-3 font-mono text-xs uppercase tracking-[0.12em] text-emerald-400">{{ t('scAKicker') }}</div>
|
||||
<h2 class="m-0 mb-4 text-[clamp(26px,3vw,34px)] font-semibold leading-[1.15] tracking-[-0.025em] text-zinc-50">
|
||||
{{ t('scATitle') }}
|
||||
</h2>
|
||||
<p class="m-0 text-[16.5px] leading-[1.6] text-zinc-400">{{ t('scABody') }}</p>
|
||||
</div>
|
||||
<div class="min-w-[280px] flex-[1_1_420px]">
|
||||
<div class="overflow-hidden rounded-xl border border-zinc-800 bg-[#0c0c0e] shadow-card">
|
||||
<div class="flex items-center gap-[9px] border-b border-[#1c1c1f] bg-[rgba(69,26,3,0.18)] px-[15px] py-3">
|
||||
<svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="#fcd34d" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3Z" /><path d="M12 9v4" /><path d="M12 17h.01" /></svg>
|
||||
<span class="text-sm font-semibold text-zinc-50">{{ t('mAttn') }}</span>
|
||||
<span class="ml-auto rounded-full bg-amber-300/[0.12] px-[9px] py-0.5 font-mono text-[11px] text-amber-300">2</span>
|
||||
<div class="flex min-w-[280px] flex-[1_1_440px] flex-col gap-3">
|
||||
<!-- rail « À traiter » -->
|
||||
<div class="flex flex-col gap-2 rounded-xl border border-amber-900/50 bg-amber-950/20 p-3 shadow-card">
|
||||
<div class="flex items-center gap-2">
|
||||
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="#fbbf24" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3Z" /><path d="M12 9v4" /><path d="M12 17h.01" /></svg>
|
||||
<h3 class="text-sm font-semibold text-amber-200">{{ t('mAttn') }}</h3>
|
||||
<span class="rounded-full bg-amber-500/20 px-1.5 text-[11px] font-semibold text-amber-300">1</span>
|
||||
</div>
|
||||
<div class="flex flex-col gap-2 p-2.5">
|
||||
<div class="flex items-center gap-3 rounded-[9px] border border-[rgba(120,53,15,0.55)] bg-[rgba(69,26,3,0.3)] px-[13px] py-[11px]">
|
||||
<span class="h-2 w-2 flex-none animate-pulse-amber rounded-full bg-amber-300"></span>
|
||||
<div class="min-w-0 flex-1">
|
||||
<div class="font-mono text-[13px] text-zinc-200">api · feat/auth</div>
|
||||
<div class="text-xs text-[#d4a55a]">Approve change to login.ts?</div>
|
||||
</div>
|
||||
<button type="button" class="flex-none rounded-[7px] border border-amber-300/30 bg-amber-300/[0.12] px-3 py-[5px] text-xs font-semibold text-amber-300">Answer</button>
|
||||
<span class="truncate font-mono text-xs text-amber-300/80">~/code/arboretum/api</span>
|
||||
<!-- DialogPrompt -->
|
||||
<div class="rounded-lg border border-amber-900/60 bg-amber-950/30 p-2.5">
|
||||
<div class="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>
|
||||
</div>
|
||||
<div class="flex items-center gap-3 rounded-[9px] border border-[rgba(120,53,15,0.55)] bg-[rgba(69,26,3,0.3)] px-[13px] py-[11px]">
|
||||
<span class="h-2 w-2 flex-none animate-pulse-amber rounded-full bg-amber-300"></span>
|
||||
<div class="min-w-0 flex-1">
|
||||
<div class="font-mono text-[13px] text-zinc-200">web · checkout</div>
|
||||
<div class="text-xs text-[#d4a55a]">Run the failing test again?</div>
|
||||
</div>
|
||||
<button type="button" class="flex-none rounded-[7px] border border-amber-300/30 bg-amber-300/[0.12] px-3 py-[5px] text-xs font-semibold text-amber-300">Answer</button>
|
||||
<div class="mt-2 flex flex-wrap gap-1.5">
|
||||
<span
|
||||
v-for="(op, i) in dlgOpts"
|
||||
:key="i"
|
||||
class="inline-flex items-center gap-1.5 rounded-lg border border-zinc-700 bg-zinc-800 px-2.5 py-1.5 text-xs font-medium text-zinc-200"
|
||||
>
|
||||
<span class="font-mono text-amber-400">{{ i + 1 }}</span> {{ op }}
|
||||
</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>
|
||||
</div>
|
||||
<div class="mx-0.5 my-[3px] h-px bg-[#1c1c1f]"></div>
|
||||
<div class="flex items-center gap-3 rounded-[9px] px-[13px] py-[9px]">
|
||||
<span class="h-2 w-2 flex-none animate-pulse-sky rounded-full bg-sky-300"></span>
|
||||
<div class="min-w-0 flex-1 font-mono text-[13px] text-zinc-400">db · refactor</div>
|
||||
<span class="flex-none font-mono text-[11px] text-sky-300">{{ t('busy') }}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- section de repo : worktrees + état de session -->
|
||||
<div class="flex flex-col gap-2 rounded-xl border border-zinc-800 bg-zinc-900/50 p-3 shadow-card">
|
||||
<header class="flex flex-wrap items-center gap-2">
|
||||
<h3 class="font-semibold text-zinc-100">arboretum</h3>
|
||||
<span class="truncate font-mono text-xs text-zinc-500">~/code/arboretum</span>
|
||||
<span class="ml-auto inline-flex items-center gap-1.5 rounded-lg border border-zinc-700 bg-zinc-800 px-2 py-1 text-xs font-medium text-zinc-200">
|
||||
<svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M5 12h14" /><path d="M12 5v14" /></svg>
|
||||
{{ t('mStart') }}
|
||||
</span>
|
||||
</header>
|
||||
|
||||
<!-- worktree : branche principale, session au repos -->
|
||||
<div class="rounded border border-zinc-800 bg-zinc-900/40 p-2">
|
||||
<div class="flex items-center gap-2">
|
||||
<span class="font-mono text-sm text-zinc-200">main</span>
|
||||
<span class="inline-flex items-center rounded bg-zinc-800 px-1.5 py-0.5 text-[11px] font-medium text-zinc-400">{{ t('mMain') }}</span>
|
||||
<span class="ml-auto text-xs text-zinc-600">{{ t('mClean') }}</span>
|
||||
</div>
|
||||
<div class="flex items-center gap-3 rounded-[9px] px-[13px] py-[9px]">
|
||||
<span class="h-2 w-2 flex-none rounded-full bg-emerald-400"></span>
|
||||
<div class="min-w-0 flex-1 font-mono text-[13px] text-zinc-400">docs · main</div>
|
||||
<span class="flex-none font-mono text-[11px] text-emerald-400">{{ t('idle') }}</span>
|
||||
<p class="truncate font-mono text-xs text-zinc-500">~/code/arboretum</p>
|
||||
<div class="mt-1 flex items-center gap-2">
|
||||
<span class="inline-flex items-center gap-1 rounded bg-zinc-800/60 px-1.5 py-0.5">
|
||||
<span class="inline-flex items-center gap-1 rounded bg-emerald-950 px-1.5 py-0.5 text-[11px] font-medium text-emerald-400">
|
||||
<span class="h-1.5 w-1.5 rounded-full bg-emerald-400"></span>{{ t('idle') }}
|
||||
</span>
|
||||
<span class="font-mono text-[11px] text-zinc-400">claude</span>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- worktree : branche de feature, session occupée -->
|
||||
<div class="rounded border border-zinc-800 bg-zinc-900/40 p-2">
|
||||
<div class="flex items-center gap-2">
|
||||
<span class="font-mono text-sm text-zinc-200">feat/auth</span>
|
||||
<span class="ml-auto flex items-center gap-2 text-xs text-zinc-500">
|
||||
<span>↑2</span>
|
||||
<span class="text-amber-400">● {{ t('mDirty') }}</span>
|
||||
</span>
|
||||
</div>
|
||||
<p class="truncate font-mono text-xs text-zinc-500">~/code/arboretum/.wt/feat-auth</p>
|
||||
<div class="mt-1 flex items-center gap-2">
|
||||
<span class="inline-flex items-center gap-1 rounded bg-zinc-800/60 px-1.5 py-0.5">
|
||||
<span class="inline-flex items-center gap-1 rounded bg-sky-950 px-1.5 py-0.5 text-[11px] font-medium text-sky-300">
|
||||
<span class="h-1.5 w-1.5 animate-pulse-sky rounded-full bg-sky-300"></span>{{ t('busy') }}
|
||||
</span>
|
||||
<span class="font-mono text-[11px] text-zinc-400">claude</span>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- b) multi-terminal grid -->
|
||||
<!-- b) grille multi-terminaux (fidèle à TerminalCell : badge d'état + titre repo · branche + commande) -->
|
||||
<div v-reveal class="flex flex-wrap-reverse items-center gap-12">
|
||||
<div class="min-w-[280px] flex-[1_1_420px]">
|
||||
<div class="min-w-[280px] flex-[1_1_440px]">
|
||||
<div class="grid grid-cols-2 gap-2.5 overflow-hidden rounded-xl border border-zinc-800 bg-[#0c0c0e] p-3 shadow-card">
|
||||
<div class="overflow-hidden rounded-[9px] 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-[11px] text-zinc-400">api · feat/auth</span>
|
||||
<span class="h-1.5 w-1.5 animate-pulse-sky rounded-full bg-sky-300"></span>
|
||||
<div class="overflow-hidden rounded-lg border border-zinc-800 bg-[#09090b]">
|
||||
<div class="flex items-center gap-2 border-b border-zinc-800 px-2 py-1.5">
|
||||
<span class="inline-flex items-center gap-1 rounded bg-sky-950 px-1.5 py-0.5 text-[10px] font-medium text-sky-300"><span class="h-1.5 w-1.5 animate-pulse-sky rounded-full bg-sky-300"></span>{{ t('busy') }}</span>
|
||||
<span class="truncate font-mono text-[11px] text-zinc-300">api · feat/auth</span>
|
||||
<span class="ml-auto shrink-0 font-mono text-[11px] text-zinc-500">claude</span>
|
||||
</div>
|
||||
<div class="p-[11px] font-mono text-[11px] leading-[1.75] text-zinc-300">
|
||||
<div class="text-emerald-400">● Edit session.ts</div>
|
||||
@@ -70,10 +118,11 @@ const { t } = useI18n();
|
||||
<div class="text-zinc-500">refactoring guards…</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="overflow-hidden rounded-[9px] 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-[11px] text-zinc-400">web · fix/cart</span>
|
||||
<span class="h-1.5 w-1.5 rounded-full bg-emerald-400"></span>
|
||||
<div class="overflow-hidden rounded-lg border border-zinc-800 bg-[#09090b]">
|
||||
<div class="flex items-center gap-2 border-b border-zinc-800 px-2 py-1.5">
|
||||
<span class="inline-flex items-center gap-1 rounded bg-emerald-950 px-1.5 py-0.5 text-[10px] font-medium text-emerald-400"><span class="h-1.5 w-1.5 rounded-full bg-emerald-400"></span>{{ t('idle') }}</span>
|
||||
<span class="truncate font-mono text-[11px] text-zinc-300">web · fix/cart</span>
|
||||
<span class="ml-auto shrink-0 font-mono text-[11px] text-zinc-500">claude</span>
|
||||
</div>
|
||||
<div class="p-[11px] font-mono text-[11px] leading-[1.75] text-zinc-300">
|
||||
<div class="text-emerald-400">✓ all tests passing</div>
|
||||
@@ -84,10 +133,11 @@ const { t } = useI18n();
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="overflow-hidden rounded-[9px] 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-[11px] text-zinc-400">db · refactor</span>
|
||||
<span class="h-1.5 w-1.5 animate-pulse-sky rounded-full bg-sky-300"></span>
|
||||
<div class="overflow-hidden rounded-lg border border-zinc-800 bg-[#09090b]">
|
||||
<div class="flex items-center gap-2 border-b border-zinc-800 px-2 py-1.5">
|
||||
<span class="inline-flex items-center gap-1 rounded bg-sky-950 px-1.5 py-0.5 text-[10px] font-medium text-sky-300"><span class="h-1.5 w-1.5 animate-pulse-sky rounded-full bg-sky-300"></span>{{ t('busy') }}</span>
|
||||
<span class="truncate font-mono text-[11px] text-zinc-300">db · refactor</span>
|
||||
<span class="ml-auto shrink-0 font-mono text-[11px] text-zinc-500">claude</span>
|
||||
</div>
|
||||
<div class="p-[11px] font-mono text-[11px] leading-[1.75] text-zinc-300">
|
||||
<div class="text-emerald-400">● Write migration</div>
|
||||
@@ -95,20 +145,21 @@ const { t } = useI18n();
|
||||
<div class="text-zinc-500">applying to schema…</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="overflow-hidden rounded-[9px] 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-[11px] text-zinc-400">docs · api</span>
|
||||
<span class="h-1.5 w-1.5 animate-pulse-sky rounded-full bg-sky-300"></span>
|
||||
<div class="overflow-hidden rounded-lg border border-zinc-800 bg-[#09090b]">
|
||||
<div class="flex items-center gap-2 border-b border-zinc-800 px-2 py-1.5">
|
||||
<span class="inline-flex items-center gap-1 rounded bg-amber-950 px-1.5 py-0.5 text-[10px] font-medium text-amber-300"><span class="h-1.5 w-1.5 animate-pulse-amber rounded-full bg-amber-300"></span>{{ t('waiting') }}</span>
|
||||
<span class="truncate font-mono text-[11px] text-zinc-300">docs · api</span>
|
||||
<span class="ml-auto shrink-0 font-mono text-[11px] text-zinc-500">claude</span>
|
||||
</div>
|
||||
<div class="p-[11px] font-mono text-[11px] leading-[1.75] text-zinc-300">
|
||||
<div class="text-emerald-400">● Read README.md</div>
|
||||
<div class="text-zinc-500">## Quick start</div>
|
||||
<div class="text-zinc-500">writing examples…</div>
|
||||
<div class="text-amber-300">Permission required</div>
|
||||
<div class="text-zinc-500">waiting for input…</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="min-w-[280px] flex-[1_1_380px]">
|
||||
<div class="min-w-[280px] flex-[1_1_360px]">
|
||||
<div class="mb-3 font-mono text-xs uppercase tracking-[0.12em] text-emerald-400">{{ t('scBKicker') }}</div>
|
||||
<h2 class="m-0 mb-4 text-[clamp(26px,3vw,34px)] font-semibold leading-[1.15] tracking-[-0.025em] text-zinc-50">
|
||||
{{ t('scBTitle') }}
|
||||
@@ -117,7 +168,7 @@ const { t } = useI18n();
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- c) mobile -->
|
||||
<!-- c) mobile : push + réponse au dialogue (fidèle à DialogPrompt) + barre d'onglets -->
|
||||
<div v-reveal class="flex flex-wrap items-center gap-12">
|
||||
<div class="min-w-[280px] flex-[1_1_380px]">
|
||||
<div class="mb-3 font-mono text-xs uppercase tracking-[0.12em] text-emerald-400">{{ t('scCKicker') }}</div>
|
||||
@@ -127,11 +178,12 @@ const { t } = useI18n();
|
||||
<p class="m-0 text-[16.5px] leading-[1.6] text-zinc-400">{{ t('scCBody') }}</p>
|
||||
</div>
|
||||
<div class="flex min-w-[280px] flex-[1_1_320px] justify-center">
|
||||
<div class="relative w-[288px] overflow-hidden rounded-[40px] border-[9px] border-zinc-900 bg-zinc-950 shadow-phone">
|
||||
<div class="relative w-[300px] overflow-hidden rounded-[40px] border-[9px] border-zinc-900 bg-zinc-950 shadow-phone">
|
||||
<div class="flex h-[30px] items-center justify-center">
|
||||
<div class="h-1.5 w-[90px] rounded-full bg-zinc-800"></div>
|
||||
</div>
|
||||
<div class="px-[13px] pb-[22px]">
|
||||
<div class="px-3 pb-[64px]">
|
||||
<!-- toast push -->
|
||||
<div class="flex items-start gap-[11px] rounded-[15px] border border-[rgba(120,53,15,0.5)] bg-[#0c0c0e] p-[13px] shadow-toast-sm">
|
||||
<span class="inline-flex h-[30px] w-[30px] flex-none items-center justify-center rounded-lg bg-emerald-500/[0.14]">
|
||||
<img src="/assets/arboretum-mark.png" alt="" width="18" height="18" class="h-[18px] w-[18px] object-contain" />
|
||||
@@ -145,24 +197,54 @@ const { t } = useI18n();
|
||||
<div class="text-xs leading-[1.45] text-zinc-400">{{ t('toastBody') }}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mt-[14px] overflow-hidden rounded-[15px] border border-zinc-800 bg-zinc-950">
|
||||
<div class="flex items-center gap-2 border-b border-[#1c1c1f] px-[13px] py-[11px]">
|
||||
<span class="h-[7px] w-[7px] animate-pulse-amber rounded-full bg-amber-300"></span>
|
||||
<span class="font-mono text-[11px] text-zinc-300">feat/auth</span>
|
||||
|
||||
<!-- carte « À traiter » + DialogPrompt -->
|
||||
<div class="mt-[14px] flex flex-col gap-2 rounded-[15px] border border-amber-900/50 bg-amber-950/20 p-2.5">
|
||||
<div class="flex items-center gap-2">
|
||||
<svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="#fbbf24" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3Z" /><path d="M12 9v4" /><path d="M12 17h.01" /></svg>
|
||||
<span class="text-[13px] font-semibold text-amber-200">{{ t('mAttn') }}</span>
|
||||
<span class="rounded-full bg-amber-500/20 px-1.5 text-[11px] font-semibold text-amber-300">1</span>
|
||||
</div>
|
||||
<div class="p-[13px]">
|
||||
<div class="text-[13px] leading-[1.5] text-zinc-300">{{ t('dlgQ') }}</div>
|
||||
<div class="mt-2 rounded-lg border border-[#1c1c1f] bg-[#0c0c0e] p-[9px] font-mono text-[11px] leading-[1.6] text-zinc-500">
|
||||
<div class="text-emerald-400">+ verifyToken(req)</div>
|
||||
<div class="text-red-400">- skipAuth()</div>
|
||||
</div>
|
||||
<div class="mt-[13px] flex gap-2">
|
||||
<button type="button" class="flex-1 rounded-lg bg-emerald-600 py-2.5 text-[13px] font-semibold text-white">{{ t('approve') }}</button>
|
||||
<button type="button" class="flex-1 rounded-lg border border-zinc-800 bg-transparent py-2.5 text-[13px] font-medium text-zinc-300">{{ t('reject') }}</button>
|
||||
<span class="font-mono text-[11px] text-amber-300/80">api · feat/auth</span>
|
||||
<div class="rounded-lg border border-amber-900/60 bg-amber-950/30 p-2.5">
|
||||
<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>
|
||||
<div class="mt-1.5 text-[13px] leading-[1.4] text-amber-100">{{ t('dlgQ') }}</div>
|
||||
<div class="mt-2 flex flex-col gap-1.5">
|
||||
<span
|
||||
v-for="(op, i) in dlgOpts"
|
||||
:key="i"
|
||||
class="flex items-center gap-2 rounded-lg border border-zinc-700 bg-zinc-800 px-2.5 py-2 text-[13px] font-medium text-zinc-200"
|
||||
>
|
||||
<span class="font-mono text-amber-400">{{ i + 1 }}</span> {{ op }}
|
||||
</span>
|
||||
<span class="rounded-lg border border-red-900 bg-red-950 px-2.5 py-2 text-center text-[13px] font-medium text-red-300">{{ t('mDeny') }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- barre d'onglets mobile (fidèle à MobileTabBar) -->
|
||||
<div class="absolute inset-x-0 bottom-0 flex border-t border-zinc-800 bg-zinc-950/95 backdrop-blur">
|
||||
<div class="flex flex-1 flex-col items-center gap-0.5 py-2 text-zinc-500">
|
||||
<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>
|
||||
<span class="text-[10px]">{{ t('mWorktrees') }}</span>
|
||||
</div>
|
||||
<div class="relative flex flex-1 flex-col items-center gap-0.5 py-2 text-emerald-400">
|
||||
<span class="relative">
|
||||
<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 class="absolute -right-1.5 -top-1.5 flex h-3.5 min-w-3.5 items-center justify-center rounded-full bg-amber-500 px-1 text-[9px] font-semibold text-amber-950">1</span>
|
||||
</span>
|
||||
<span class="text-[10px]">{{ t('mSessions') }}</span>
|
||||
</div>
|
||||
<div class="flex flex-1 flex-col items-center gap-0.5 py-2 text-zinc-500">
|
||||
<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>
|
||||
<span class="text-[10px]">{{ t('mGroups') }}</span>
|
||||
</div>
|
||||
<div class="flex flex-1 flex-col items-center gap-0.5 py-2 text-zinc-500">
|
||||
<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="4" x2="20" y1="12" y2="12" /><line x1="4" x2="20" y1="6" y2="6" /><line x1="4" x2="20" y1="18" y2="18" /></svg>
|
||||
<span class="text-[10px]">{{ t('mMore') }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user