Use when writing acceptance criteria for a task - express each as an observable Given/When/Then that QA can execute, including negative cases
The English summary is being prepared. Showing the original description.
Use when designing or building any mobile screen or component a user sees (Flutter, SwiftUI or Compose) - platform conventions, hierarchy, type that scales, colour roles and dark mode, safe areas and insets, forms and keyboard, states, feedback, and the generic-mobile anti-patterns.
The English summary is being prepared. Showing the original description.
See how to installReview the instructions the agent will receive before you install.
A screen that compiles and passes its widget test has not been designed. The two most common mobile failures are a web-style layout wearing a mobile skin (centred everything, modal-on-modal, a custom tab bar that doesn't match the platform) and a happy-path-only build with no loading/empty/error state.
Core principle: follow the platform's own conventions first, build from theme tokens and the atomic component library, and design every state — not just the one the task's screenshot shows.
| Concern | iOS | Android |
|---|---|---|
| Touch target | 44×44pt | 48×48dp |
| Top-level navigation | tab bar, 3–5 items | nav bar, 3–5 items → nav rail ≥600dp |
| Back | edge swipe, never overridden | system/predictive back; BackHandler/PopScope, never onBackPressed |
| Text | Dynamic Type text styles | Material type roles, in sp |
| Alerts | critical only | critical only |
| Non-critical feedback | — | snackbar |
Destructive actions carry a destructive role plus a confirmation or an undo window — never a silent delete either platform.
xs 4, sm 8, md 16, lg 24, xl 32 or the repo's own theme extension) — never a magic numeric literal in a widget/view.Theme.textTheme, Material type roles, Font semantic styles) — never a fixed/hardcoded size.ColorScheme/Theme.of(context).colorScheme, Material colour roles, asset-catalog semantic colours — never Color(0x…)/Colors.* outside the theme files.SafeArea, MediaQuery.viewPaddingOf(context).Scaffold's innerPadding + consumeWindowInsets — don't double-apply padding on top of it..ignoresSafeArea() only on a background layer, never on interactive content.NavigationSuiteScaffold/custom bottom bar doesn't automatically propagate inset padding to its content — verify by looking, don't assume.TextInputType.emailAddress, .keyboardType(.emailAddress), KeyboardOptions(keyboardType = ...)) and autofill hints.next moves to the following field, the last field is done/submits.mobile-accessibility); prefer no animation over a gratuitous one.app-locale-ui-copy); no leftover placeholder text.// ❌ fixed Row, hardcoded style, no layout adaptation —
// passes at text scale 1.0, overflows 82px on the right at 360 wide / text scale 2.0
Row(
children: [
Expanded(child: Text(task.title, style: const TextStyle(fontSize: 16))),
Text(task.price),
IconButton(icon: const Icon(Icons.add), onPressed: onAdd),
],
)
// ✅ decides by available width and text scale, themed, labeled
LayoutBuilder(
builder: (context, constraints) {
final narrow = constraints.maxWidth < 280 * MediaQuery.textScalerOf(context).scale(1);
final price = Text(task.price, style: context.textTheme.bodyMedium);
final addButton = IconButton(
icon: const Icon(Icons.add),
tooltip: 'Add to cart',
onPressed: onAdd,
);
final title = Text(task.title, style: context.textTheme.titleMedium);
return narrow
? Column(crossAxisAlignment: CrossAxisAlignment.start, children: [
title,
Row(children: [Expanded(child: price), addButton]),
])
: Row(children: [Expanded(child: title), price, addButton]);
},
)
The rewrite decides layout from the available width instead of assuming it, uses theme text styles so it scales with the system font size, and labels the icon-only button. See mobile-visual-self-review for the verified matrix test that caught the overflow.
Color(0x…)/Colors.*/hardcoded fontSize/magic EdgeInsets instead of theme tokens.Text/label.No reviews yet. Tell others what you thought.
No login needed. Share how it worked for you, ask a question, or note where it did not run.
No comments yet. Be the first to write one.
Use when writing acceptance criteria for a task - express each as an observable Given/When/Then that QA can execute, including negative cases
The English summary is being prepared. Showing the original description.
Use when the diff adds or changes an endpoint, resolver, RPC, job or query that takes an object id, a role check, a request binding or a tenant filter - BOLA/IDOR, function-level authorization, mass assignment and tenant scoping
The English summary is being prepared. Showing the original description.
Use on every UI change - semantic HTML, labels for controls, keyboard-navigable dialogs/menus, visible focus, and never color as the only signal
The English summary is being prepared. Showing the original description.
Use when a task changes any screen, form, dialog, menu or control - Lighthouse/axe scan of the changed screens, a keyboard walk, and the thresholds that fail a task
The English summary is being prepared. Showing the original description.
How to work a task returned with review, QA or UAT findings. Use when a task is in need_revision or PR review comments are in your context.
The English summary is being prepared. Showing the original description.
Use when the repository keeps its alerting in code, or a person asks for alerts outside TaskTrooper - PrometheusRule YAML, a Cloud Monitoring alert policy in Terraform, a Datadog monitor, each routed to TaskTrooper's alert ingest URL so it opens an incident here
The English summary is being prepared. Showing the original description.