[eric] ui: shrinking state is just a pulsing dot + one word, docs say minimalism beats carousels

This commit is contained in:
eric
2026-05-31 18:53:09 -07:00
parent 11b7d9b7a4
commit a6dd596405
2 changed files with 9 additions and 21 deletions
+2
View File
@@ -48,6 +48,8 @@ This app ships to non-developers. Anything a user sees has to read like a person
- **Match the app's design tokens.** Use `c.bg.surface`, `c.border.medium`, `c.accent.primary` from `claudeTokens`. Avoid raw MUI `Alert variant="filled"` blocks of saturated yellow/red — they read as dev-mode warnings, not user dialogs.
- **No alarming colors for normal flow.** "This file is too big" is a routine choice, not a warning. Warning/error coloring is reserved for actual failures the user can't recover from.
- **Friendly without being cute.** Conversational, not chirpy. "Want me to shrink it down to a summary?" not "Whoops! That file is huge!".
- **Minimalist by default. Less is more.** One short message, one subtle animation, one verb. Do NOT add rotating progress messages, multi-line status text, percentage counters, or step-by-step explainers unless the user explicitly needs them. A pulsing dot + "Shrinking" beats a 4-message carousel + spinner + progress bar every time. The user knows what they clicked; we just need to confirm we're alive.
- **Animations are subtle.** Pulse, fade, soft scale (≤1.0× to 0.6×). No bounce, no flashing, no harsh blinking, no rotating spinners with multiple emoji. Easing: `ease-in-out`. Duration: 1-1.5s for ambient states (loading), 150-250ms for state changes (hover, mode flip).
## Pitfalls
@@ -1,4 +1,4 @@
import React, { useEffect, useState } from 'react';
import React from 'react';
import Box from '@mui/material/Box';
import IconButton from '@mui/material/IconButton';
import Modal from '@mui/material/Modal';
@@ -6,33 +6,19 @@ import Snackbar from '@mui/material/Snackbar';
import CloseIcon from '@mui/icons-material/Close';
import { ClaudeTokens } from '@/shared/styles/claudeTokens';
const SHRINK_PROGRESS_MESSAGES = [
'Reading the file',
'Pulling out the key bits',
'Compressing',
'Almost done',
];
function ShrinkingLabel() {
const [idx, setIdx] = useState(0);
useEffect(() => {
const t = setInterval(() => setIdx((i) => (i + 1) % SHRINK_PROGRESS_MESSAGES.length), 4000);
return () => clearInterval(t);
}, []);
return (
<Box component="span" sx={{ display: 'inline-flex', alignItems: 'center', gap: 0.5 }}>
<Box component="span" sx={{ display: 'inline-flex', alignItems: 'center', gap: 0.6 }}>
<Box component="span" sx={{
display: 'inline-block', width: 8, height: 8, borderRadius: '50%',
bgcolor: 'currentColor', opacity: 0.85,
display: 'inline-block', width: 6, height: 6, borderRadius: '50%',
bgcolor: 'currentColor',
animation: 'osw-pulse 1.2s ease-in-out infinite',
'@keyframes osw-pulse': {
'0%, 100%': { transform: 'scale(0.6)', opacity: 0.45 },
'50%': { transform: 'scale(1)', opacity: 0.95 },
'0%, 100%': { opacity: 0.4 },
'50%': { opacity: 1 },
},
}} />
<Box component="span" sx={{ minWidth: 130, textAlign: 'left' }}>
{SHRINK_PROGRESS_MESSAGES[idx]}
</Box>
Shrinking
</Box>
);
}