calm-layout-and-motion

Enforces Calm design system spacing, touch-target, and motion token rules in Flutter UI code.

Updated Sep 2, 2026
One-click install
npx skills add https://github.com/zakariaf/Odova --skill calm-layout-and-motion-zakariaf
Or copy as Structured Prompt for Agent
Please help me install this Agent Skill.
Skill: calm-layout-and-motion
Source: https://github.com/zakariaf/Odova/tree/main/.claude/skills/calm-layout-and-motion
Command: npx skills add https://github.com/zakariaf/Odova --skill calm-layout-and-motion-zakariaf

SYSTEM DOCUMENTATION & REQUIREMENTS

💡 This Skill includes scripts (resource) and references (resource) components.

What problem does it solve? Flutter screens drift out of visual consistency when developers hardcode spacing values, undersize tap targets, or invent ad-hoc animation durations and curves. This Skill enforces the Calm design system's spatial and motion discipline so every screen in the Odova app shares one rhythm, one hierarchy, and one motion vocabulary. ## Core Features & Use Cases - Spacing and layout enforcement: Applies the ten-step CalmSpace scale plus the 22pt screen gutter, the one-primary-element-per-screen rule, and the CalmScaffold screen skeleton. - Touch target validation: Ships scripts/check_touch_targets.sh, a CI gate that fails on control-sizing literals below 52px, MaterialTapTargetSize.shrinkWrap, raw Duration/Curves outside the theme directory, and pumpAndSettle in reduced-motion tests. - Motion token governance: Restricts animation to five durations and four cubic curves from CalmMotion, including the arrival-only easeSettle rule and reduced-motion collapsing to Duration.zero. - All-clear state design: Distinguishes the designed CalmAllClear good state from CalmEmptyState so the most common Home screen never renders as a failure. - Use Case: While building a new Odova screen, use this Skill to lay out the CalmScaffold with correct gutters, size every tap target to the 52px floor, animate the bottom sheet with the sheet duration, and run the gate script before opening a PR. ## Quick Start Ask the assistant to lay out a new Odova screen following the calm-layout-and-motion rules and then run the touch-target check script on the lib directory.

Frequently Asked Questions about calm-layout-and-motion

High-intent search queries and answers about installing and using this skill.

FAQPage Schema
How do I enforce a minimum touch target size in Flutter?

Wrap the gesture in an explicit SizedBox or ConstrainedBox set to the 52px floor with HitTestBehavior.opaque, since the visible ink may be shorter. The check_touch_targets.sh script fails any control-sizing literal below 52 and bans MaterialTapTargetSize.shrinkWrap.

How do I handle reduced motion in Flutter animations?

Route every duration through a resolveMotion helper that returns Duration.zero when MediaQuery.disableAnimationsOf is true, and set themeAnimationStyle to AnimationStyle.noAnimation on MaterialApp. Never branch to a shorter duration instead of zero.

Why does an overshoot curve crash Flutter opacity animations?

Opacity asserts that values stay between 0.0 and 1.0, so a curve like easeSettle whose control point overshoots past 1.0 triggers a debug-mode assertion crash. Reserve overshoot curves for scale, offset, and size entrances only.

Can I use pumpAndSettle in reduced-motion widget tests?

No. When animations collapse to zero duration there is nothing to settle, so pumpAndSettle asserts nothing and hides the frame under test. Use a single pump() instead; the gate script flags pumpAndSettle inside reduced-motion test cases.

What is the difference between an empty state and an all-clear state?

An empty state means a list the user has not filled yet and gets a neutral art disc with one primary action. An all-clear state means work is done and gets a sage-tinted card with a reassuring mark, the good news, the next item, and the last-confirmed date, with no primary CTA.

Why avoid left and right in Flutter EdgeInsets for RTL support?

Hardcoded left and right break mirrored layouts in RTL locales like Arabic, Persian, and Kurdish. Use EdgeInsetsDirectional, AlignmentDirectional, and PositionedDirectional with start and end so three of Odova's six locales render correctly.