fix: make Reduced motion gate overlays, standardize the tab band, and polish fleet/snapshots (#1504)

* fix: address review feedback on motion, fleet band, and snapshots

- Reduced motion now also skips the animate-ui overlay open/close animations
  (dialog, sheet, popover, dropdown-menu) via a shared useReducedTransition that
  zeroes the transition when reduced motion is active; MotionConfig alone only
  neutralized transform/layout, leaving the opacity/blur fade.
- Fleet tab band: flatten the list's own pill band so the tabs sit in a single
  full-width band instead of a nested second band.
- Fleet Overview: label the node-update button "Node Update"; the add-node
  button becomes a ChartNetwork icon that opens Settings > Nodes (outline style,
  matching the node-update button) instead of the add-node modal.
- Blueprint deployments empty state: drive the serif headings from the theme
  heading-style token so Calm drops the italic.
- Snapshots: move the per-stack Restore onto the stack header row (right side),
  matching the ghost action style.

* feat: standardize the tab band on Security and add a tab hover state

- Apply the Fleet full-width tab band to the Security page (single band, the
  list's pill background flattened so the tabs sit directly in it).
- Add a hover highlight to tabs so the band reads as interactive, not flat;
  the active tab is unaffected.

* fix: drive reduced-motion transitions from the app setting, not the OS query

useReducedTransition called framer-motion's useReducedMotion(), which only
reflects the OS prefers-reduced-motion media query and ignores our MotionConfig
/ appearance toggle, so dialogs kept animating with the setting on. Read the
app's useReducedMotion selector instead. Verified: with the setting on, the
dialog opacity snaps 0->1 in one frame; with it off, it ramps over the spring.

* feat: standardize stack-detail body text to text-xs and add a log expand toggle

- Bump the anatomy panel body text (rows, field values, warnings) and the
  structured log lines from 10/11/12px to text-xs (12px), leaving the uppercase
  kicker labels and the log level/source badges as-is.
- Add an expand control next to the log download button that collapses the
  Command Center so the logs pane fills the left column; toggles back to restore.
This commit is contained in:
Anso
2026-06-28 08:17:34 -04:00
committed by GitHub
parent 04e69021e0
commit d6ce60d280
17 changed files with 167 additions and 91 deletions
@@ -324,6 +324,15 @@ export function EditorView(props: EditorViewProps) {
if (!editingCompose || activeTab !== 'files') setFilesFullscreen(false);
}, [editingCompose, activeTab]);
// Expand the logs by collapsing the Command Center card so the logs pane
// fills the left column. Toggled from the structured log viewer header.
const [logsExpanded, setLogsExpanded] = useState(false);
// The expand control lives only in the structured viewer; reset when the
// raw terminal is selected so the Command Center can't be stranded hidden.
useEffect(() => {
if (logsMode === 'raw') setLogsExpanded(false);
}, [logsMode]);
// Below md, render the segmented full-screen mobile detail instead of the
// desktop two-pane grid. All hooks above run unconditionally before this
// branch so hook order stays stable across breakpoints.
@@ -339,7 +348,9 @@ export function EditorView(props: EditorViewProps) {
files fullscreen so the editor card fills the width. */}
{!filesFullscreen && (
<div className="flex flex-col gap-6 min-h-0">
{/* Command Center Card (identity + health strip) */}
{/* Command Center Card (identity + health strip). Hidden when
the logs are expanded so the logs pane fills the column. */}
{!logsExpanded && (
<Card className="rounded-xl border-muted bg-card shrink-0">
<CardHeader className="p-4 pb-2">
<div className="flex items-start justify-between gap-3">
@@ -404,9 +415,16 @@ export function EditorView(props: EditorViewProps) {
/>
</CardContent>
</Card>
)}
{/* Logs Section (fills remaining left-column height) */}
<StackLogsSection stackName={stackName} logsMode={logsMode} setLogsMode={setLogsMode} />
<StackLogsSection
stackName={stackName}
logsMode={logsMode}
setLogsMode={setLogsMode}
logsExpanded={logsExpanded}
onToggleLogsExpand={() => setLogsExpanded((v) => !v)}
/>
</div>
)}
@@ -185,6 +185,7 @@ export function ViewRouter({
<LazyView>
<FleetView
onNavigateToNode={onFleetNavigateToNode}
onOpenSettingsSection={onOpenSettingsSection}
fleetUpdatesIntent={fleetUpdatesIntent}
onFleetUpdatesIntentConsumed={onFleetUpdatesIntentConsumed}
fleetTab={fleetTab}
@@ -555,10 +555,14 @@ export interface StackLogsSectionProps {
stackName: string;
logsMode: 'structured' | 'raw';
setLogsMode: (mode: 'structured' | 'raw') => void;
/** When set, the structured viewer shows an expand control that collapses
* the Command Center to give the logs more vertical room. */
logsExpanded?: boolean;
onToggleLogsExpand?: () => void;
}
// Logs pane: structured / raw-terminal toggle + the live viewer.
export function StackLogsSection({ stackName, logsMode, setLogsMode }: StackLogsSectionProps) {
export function StackLogsSection({ stackName, logsMode, setLogsMode, logsExpanded, onToggleLogsExpand }: StackLogsSectionProps) {
return (
<div className="flex-1 min-h-0 flex flex-col gap-2 overflow-hidden">
<div className="flex items-center justify-between">
@@ -568,7 +572,7 @@ export function StackLogsSection({ stackName, logsMode, setLogsMode }: StackLogs
type="button"
onClick={() => setLogsMode('structured')}
className={cn(
'rounded px-2 py-0.5 font-mono text-[10px] uppercase tracking-wide transition-colors',
'rounded px-2 py-0.5 font-mono text-xs uppercase tracking-wide transition-colors',
logsMode === 'structured' ? 'bg-brand/15 text-brand' : 'text-stat-subtitle hover:text-foreground',
)}
>
@@ -578,7 +582,7 @@ export function StackLogsSection({ stackName, logsMode, setLogsMode }: StackLogs
type="button"
onClick={() => setLogsMode('raw')}
className={cn(
'rounded px-2 py-0.5 font-mono text-[10px] uppercase tracking-wide transition-colors',
'rounded px-2 py-0.5 font-mono text-xs uppercase tracking-wide transition-colors',
logsMode === 'raw' ? 'bg-brand/15 text-brand' : 'text-stat-subtitle hover:text-foreground',
)}
>
@@ -588,7 +592,7 @@ export function StackLogsSection({ stackName, logsMode, setLogsMode }: StackLogs
</div>
{logsMode === 'structured' ? (
<ErrorBoundary>
<StructuredLogViewer stackName={stackName} />
<StructuredLogViewer stackName={stackName} expanded={logsExpanded} onToggleExpand={onToggleLogsExpand} />
</ErrorBoundary>
) : (
<div className="flex-1 rounded-xl overflow-hidden border border-muted bg-black p-3 shadow-[inset_0_2px_4px_0_oklch(0_0_0/0.4)]">