Stage 3: Plan editor with Steps, Supersets and reordering

- Plan model with immutable edits: add with Mode defaults, move, remove,
  Superset with next, take a member out, ungroup; Stretching length
  estimate from holds, sides, rounds and Transitions
- drift database (plans table, items as JSON, ADR 0005) and
  PlanRepository; Plans list per Mode with rename/duplicate/delete
- Editor: drag handles, step editor sheet (sets, reps or time, optional
  kg; hold, both sides, rounds; Superset sets and rest between),
  pause between holds for Stretching Plans
- Exercise picker reusing the Library browser; Add to plan from the
  Exercise detail page
- Theme: Mode-styled snackbar, FAB, menus, segmented buttons, switches

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
CedricandClaude Opus 5.5 committed 2026-10-28 23:48:07 +01:00
1 parent 786dd52e30
commit bbdca95541
28 files changed
+3654 -11

No files matched your search

+10 -2
View File
@@ -4,11 +4,14 @@ import 'zen_style.dart';
/// A tab's big title and an optional line under it.
class PageHeader extends StatelessWidget {
const PageHeader({super.key, required this.title, this.subtitle});
const PageHeader({super.key, required this.title, this.subtitle, this.action});
final String title;
final String? subtitle;
/// A button beside the title, such as "New plan".
final Widget? action;
@override
Widget build(BuildContext context) {
final s = ZenStyle.of(context);
@@ -18,7 +21,12 @@ class PageHeader extends StatelessWidget {
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(title, style: text.headlineLarge),
Row(
children: [
Expanded(child: Text(title, style: text.headlineLarge)),
if (action != null) ...[const SizedBox(width: 12), action!],
],
),
if (subtitle != null) ...[
const SizedBox(height: 6),
Text(subtitle!, style: text.bodyLarge?.copyWith(color: s.inkMuted)),