diff --git a/frontend/src/app/components/Layout/AppShell.tsx b/frontend/src/app/components/Layout/AppShell.tsx index 117e58fc..1fa4994e 100644 --- a/frontend/src/app/components/Layout/AppShell.tsx +++ b/frontend/src/app/components/Layout/AppShell.tsx @@ -33,7 +33,6 @@ import CircularProgress from '@mui/material/CircularProgress'; // Settings modal lazy-loaded so its 2.3K LOC + Stripe/OAuth helpers don't ship on first paint. const Settings = React.lazy(() => import('@/app/pages/Settings/Settings')); import DynamicIsland from '@/app/components/DynamicIsland'; -import OnboardingSidebarEntry from '@/app/components/Onboarding/OnboardingSidebarEntry'; import Dashboard from '@/app/pages/Dashboard/Dashboard'; import DashboardHost from '@/app/components/Layout/DashboardHost'; import { useLastDashboardId } from '@/shared/hooks/useLastDashboardId'; @@ -987,8 +986,6 @@ const AppShell: React.FC = () => { - - { + const c = useClaudeTokens(); + const progress = useOnboardingProgress(); + const [hovered, setHovered] = useState(false); + + const total = STEPS.length; + const done = progress.completedSteps.length; + // Hide while the cursor is driving a step, same as the panel does. + const show = + progress.initialized && + progress.panelMode === 'docked' && + !progress.running && + done < total; + const pct = total > 0 ? (done / total) * 100 : 0; + + const reopen = () => { + report('panel_reopened', { from: 'docked_tab' }); + progress.setPanelMode('expanded'); + }; + + return ( + + + {show && ( + + setHovered(true)} + onMouseLeave={() => setHovered(false)} + onClick={reopen} + onKeyDown={(e) => { + if (e.key === 'Enter' || e.key === ' ') { + e.preventDefault(); + reopen(); + } + }} + sx={{ + display: 'flex', + alignItems: 'center', + gap: hovered ? 0.7 : 0, + cursor: 'pointer', + bgcolor: c.bg.surface, + border: `1px solid ${c.border.subtle}`, + borderRight: 'none', + borderTopLeftRadius: 9, + borderBottomLeftRadius: 9, + pl: hovered ? 1 : 0.5, + pr: 0.5, + py: 0.5, + boxShadow: hovered ? c.shadow.md : '-1px 0 5px rgba(0,0,0,0.07)', + transition: + 'gap 0.18s ease, padding 0.18s ease, box-shadow 0.18s ease, background 0.15s', + '&:hover': { bgcolor: c.bg.elevated ?? c.bg.surface }, + }} + > + + { + e.stopPropagation(); + report('panel_dismissed', { from: 'docked_tab' }); + progress.setPanelMode('hidden'); + }} + sx={{ + p: 0.1, + color: c.text.tertiary, + '&:hover': { color: c.text.primary }, + }} + > + + + + + + Finish setup + + + + + + + + + )} + + + ); +}; + +export default OnboardingDockedTab; diff --git a/frontend/src/app/components/Onboarding/OnboardingRoot.tsx b/frontend/src/app/components/Onboarding/OnboardingRoot.tsx index 4180050a..19b744b2 100644 --- a/frontend/src/app/components/Onboarding/OnboardingRoot.tsx +++ b/frontend/src/app/components/Onboarding/OnboardingRoot.tsx @@ -17,6 +17,7 @@ import AgenticCursor, { type AgenticCursorHandle } from './ac/AgenticCursor'; import { onboardingDirector } from './OnboardingDirector'; import { STEPS } from './steps'; import OnboardingPanel from './OnboardingPanel'; +import OnboardingDockedTab from './OnboardingDockedTab'; import { onboardingBus } from './eventBus'; import { report } from './telemetry'; @@ -217,6 +218,7 @@ const OnboardingRoot: React.FC = () => { <> + ); }; diff --git a/frontend/src/app/components/Onboarding/OnboardingSidebarEntry.tsx b/frontend/src/app/components/Onboarding/OnboardingSidebarEntry.tsx deleted file mode 100644 index c8292c70..00000000 --- a/frontend/src/app/components/Onboarding/OnboardingSidebarEntry.tsx +++ /dev/null @@ -1,122 +0,0 @@ -// Docked onboarding home: a compact row at the bottom of the sidebar that springs the tour back open. - -import React, { useState } from 'react'; -import { motion, AnimatePresence } from 'framer-motion'; -import { - Box, - ListItemButton, - ListItemIcon, - ListItemText, - IconButton, - Typography, - CircularProgress, -} from '@mui/material'; -import ChevronRightIcon from '@mui/icons-material/ChevronRight'; -import CloseIcon from '@mui/icons-material/Close'; -import { useClaudeTokens } from '@/shared/styles/ThemeContext'; -import { useOnboardingProgress } from './hooks/useOnboardingProgress'; -import { STEPS } from './steps'; -import { report } from './telemetry'; - -const OnboardingSidebarEntry: React.FC = () => { - const c = useClaudeTokens(); - const progress = useOnboardingProgress(); - const [hovered, setHovered] = useState(false); - - const total = STEPS.length; - const done = progress.completedSteps.length; - const show = - progress.initialized && progress.panelMode === 'docked' && done < total; - const pct = total > 0 ? (done / total) * 100 : 0; - - return ( - - {show && ( - - - setHovered(true)} - onMouseLeave={() => setHovered(false)} - onClick={() => { - report('panel_reopened', { from: 'sidebar' }); - progress.setPanelMode('expanded'); - }} - sx={{ - borderRadius: 1.5, - py: 0.6, - px: 1.25, - bgcolor: `${c.accent.primary}0C`, - '&:hover': { bgcolor: `${c.accent.primary}1A` }, - transition: 'background-color 0.15s', - }} - > - - - - - - {hovered ? ( - { - e.stopPropagation(); - report('panel_dismissed', { from: 'sidebar' }); - progress.setPanelMode('hidden'); - }} - sx={{ - p: 0.2, - color: c.text.tertiary, - '&:hover': { color: c.text.primary }, - }} - > - - - ) : ( - - - {done}/{total} - - - - )} - - - - )} - - ); -}; - -export default OnboardingSidebarEntry; diff --git a/frontend/src/shared/styles/claudeTokens.ts b/frontend/src/shared/styles/claudeTokens.ts index a1a6f5f7..21daff46 100644 --- a/frontend/src/shared/styles/claudeTokens.ts +++ b/frontend/src/shared/styles/claudeTokens.ts @@ -56,7 +56,7 @@ export const lightTokens: ClaudeTokens = { }, user: { bubble: '#DDD9CE' }, font: { - sans: '"Anthropic Sans", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif', + sans: '"Anthropic Sans", ui-serif, Georgia, Cambria, "Times New Roman", Times, serif', mono: 'ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace', }, transition: 'all 150ms cubic-bezier(0.165, 0.85, 0.45, 1)', @@ -107,7 +107,7 @@ export const darkTokens: ClaudeTokens = { }, user: { bubble: '#393937' }, font: { - sans: '"Anthropic Sans", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif', + sans: '"Anthropic Sans", ui-serif, Georgia, Cambria, "Times New Roman", Times, serif', mono: 'ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace', }, transition: 'all 150ms cubic-bezier(0.165, 0.85, 0.45, 1)',