From UI Motion & States
Generates a sidebar panel with sliders, toggles, color pickers, and selects for live prototype tweaking (CSS variables). Useful when users request interactive controls instead of static variants.
How this skill is triggered — by the user, by Claude, or both
Slash command
/ui-motion:tweaks-panelWhen to use
Юзер хочет «дай переключатели для вариантов», «можно покрутить размер шрифта», «слайдер для цвета», «крутилки». Лучше чем плодить N статичных вариантов.
The summary Claude sees in its skill listing — used to decide when to auto-load this skill
Боковая панель с контролами, привязанными к CSS variables через `document.documentElement.style.setProperty()`.
Боковая панель с контролами, привязанными к CSS variables через document.documentElement.style.setProperty().
function TweaksPanel({ tweaks, onChange }) {
const [open, setOpen] = useState(true);
return (
<aside style={{
position: 'fixed', top: 0, right: open ? 0 : -300, width: 300, height: '100vh',
background: '#fff', borderLeft: '1px solid #e5e7eb', padding: 24,
overflowY: 'auto', transition: 'right .25s', zIndex: 100,
boxShadow: '-8px 0 24px rgba(0,0,0,0.06)',
fontFamily: '-apple-system, system-ui, sans-serif',
}}>
<button onClick={() => setOpen(!open)} style={{
position: 'absolute', left: -32, top: 16, width: 32, height: 32,
background: '#fff', border: '1px solid #e5e7eb', borderRight: 'none',
borderRadius: '8px 0 0 8px', cursor: 'pointer',
}}>{open ? '→' : '←'}</button>
<h3 style={{ margin: '0 0 16px', fontSize: 14, textTransform: 'uppercase', letterSpacing: '0.05em' }}>Tweaks</h3>
{tweaks.map(t => (
<div key={t.key} style={{ marginBottom: 20 }}>
<label style={{ display: 'block', fontSize: 12, color: '#6b7280', marginBottom: 6 }}>{t.label}</label>
{t.type === 'range' && (
<>
<input type="range" min={t.min} max={t.max} step={t.step || 1}
value={t.value} onChange={e => onChange(t.key, +e.target.value)}
style={{ width: '100%' }} />
<div style={{ fontSize: 11, color: '#9ca3af', marginTop: 4 }}>{t.value}{t.unit || ''}</div>
</>
)}
{t.type === 'color' && (
<input type="color" value={t.value} onChange={e => onChange(t.key, e.target.value)}
style={{ width: '100%', height: 32, cursor: 'pointer' }} />
)}
{t.type === 'toggle' && (
<button onClick={() => onChange(t.key, !t.value)} style={{
width: 48, height: 26, borderRadius: 13, border: 'none',
background: t.value ? '#YOUR_BRAND_COLOR' : '#d1d5db', position: 'relative', cursor: 'pointer',
}}>
<div style={{
position: 'absolute', top: 2, left: t.value ? 24 : 2,
width: 22, height: 22, borderRadius: '50%', background: '#fff',
transition: 'left .2s',
}}/>
</button>
)}
{t.type === 'select' && (
<select value={t.value} onChange={e => onChange(t.key, e.target.value)}
style={{ width: '100%', padding: 6, border: '1px solid #e5e7eb', borderRadius: 6 }}>
{t.options.map(o => <option key={o} value={o}>{o}</option>)}
</select>
)}
</div>
))}
</aside>
);
}
window.TweaksPanel = TweaksPanel;
function App() {
const [tw, setTw] = useState({
primary: '#YOUR_PRIMARY',
fontScale: 100,
radius: 12,
darkMode: false,
density: 'cozy',
});
// Применяем tweaks к CSS variables
useEffect(() => {
const r = document.documentElement;
r.style.setProperty('--h-primary', tw.primary);
r.style.setProperty('--h-font-scale', tw.fontScale + '%');
r.style.setProperty('--h-r-md', tw.radius + 'px');
r.style.setProperty('color-scheme', tw.darkMode ? 'dark' : 'light');
}, [tw]);
const tweaks = [
{ key: 'primary', label: 'Primary color', type: 'color', value: tw.primary },
{ key: 'fontScale', label: 'Font scale', type: 'range', min: 80, max: 120, step: 5, value: tw.fontScale, unit: '%' },
{ key: 'radius', label: 'Border radius', type: 'range', min: 0, max: 24, value: tw.radius, unit: 'px' },
{ key: 'darkMode', label: 'Dark mode', type: 'toggle', value: tw.darkMode },
{ key: 'density', label: 'Density', type: 'select', value: tw.density, options: ['compact','cozy','spacious'] },
];
return (
<>
<Prototype />
<TweaksPanel tweaks={tweaks} onChange={(k, v) => setTw(p => ({...p, [k]: v }))} />
</>
);
}
| Тёрл | Variable | Когда нужен |
|---|---|---|
| Primary color | --primary | смена бренда / эксперимент |
| Font family | --font-body | сравнение шрифтов |
| Font scale (80-120%) | --font-scale | a11y тест на крупный шрифт |
| Border radius | --r-md | brutalism (0) vs friendly (16) |
| Density | --space-base | compact / cozy / spacious |
| Dark mode | color-scheme | a/b dark и light |
| Reduced motion | --motion | a11y тест |
| Sidebar collapsed | UI state | desktop vs tablet pattern |
3-7 тёрлов — sweet spot. 10+ → юзер запутается.
Скилл tweaks-persist сохраняет состояние тёрл в localStorage и восстанавливает при перезагрузке. По умолчанию tweaks-panel этого не делает — каждое открытие = свежий старт.
label-letter-spacing, box-shadow-y-offset) → не дают ощутимую разницуnpx claudepluginhub jhamidun/claude-code-config-pack --plugin ui-motionProvides behavioral guidelines to reduce common LLM coding mistakes, focusing on simplicity, surgical changes, assumption surfacing, and verifiable success criteria.
Searches, retrieves, and installs Agent Skills from prompts.chat registry using MCP tools like search_skills and get_skill. Activates for finding skills, browsing catalogs, or extending Claude.
Creates, edits, and optimizes skills for Claude Code, including drafting, evaluating with test prompts, iterating on performance, and improving skill descriptions for better triggering accuracy.