Palette: seven roles (accent, good, caution added; highlight renamed alarm); no hard-coded colours left
/ crosscheck (push) Successful in 0s
CI / Analyze & Test (push) Successful in 13s
CI / Debug APK (push) Successful in 22s

background, foreground, subdued, accent (emphasis without danger), and the state
gradient good → caution → alarm; surface and onFill derived. smart-serow's
four-key themes still load (highlight = alarm; the new roles fall back).
Material's scheme follows: buttons in accent instead of the alarm colour.
Link state, mock banner, signal tiles, raw log, checklist button and marks,
camera page all take palette roles.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DDwfd6Ki8UfG4hK6W5YpJz
This commit is contained in:
2026-10-14 13:55:52 +09:00
parent 54ea278ca2
commit 3aeb09d61f
11 changed files with 165 additions and 72 deletions
+12 -8
View File
@@ -18,6 +18,7 @@ import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'boundary.dart';
import 'theme/palette.dart';
const checklistAssets = 'assets/contracts/checklists/';
@@ -309,14 +310,17 @@ class _ChecklistPageState extends State<ChecklistPage> {
Widget _panel(BuildContext context) {
final s = run.current;
final theme = Theme.of(context);
final p = AppTheme.of(context);
final a = run.currentAction;
// The big button by what pressing it does: start (good), stop a running span
// (caution: something is in progress), a point mark (accent), skip on (subdued).
final (Color color, IconData icon) = run.stepDone
? (Colors.blueGrey, Icons.skip_next)
? (p.subdued, Icons.skip_next)
: a!.point
? (Colors.blue, Icons.flag)
? (p.accent, Icons.flag)
: run.inSpan
? (Colors.red.shade700, Icons.stop)
: (Colors.green.shade700, Icons.play_arrow);
? (p.caution, Icons.stop)
: (p.good, Icons.play_arrow);
return Padding(
padding: const EdgeInsets.all(16),
child: Column(
@@ -339,7 +343,7 @@ class _ChecklistPageState extends State<ChecklistPage> {
child: FilledButton(
style: FilledButton.styleFrom(
backgroundColor: color,
foregroundColor: Colors.white,
foregroundColor: p.onFill(color),
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(24)),
),
onPressed: run.finished ? null : () => _send(run.press()),
@@ -394,7 +398,7 @@ class _ChecklistPageState extends State<ChecklistPage> {
style: TextStyle(
fontSize: 32,
fontFeatures: const [FontFeature.tabularFigures()],
color: reached ? Colors.lightGreenAccent : Colors.white,
color: reached ? AppTheme.of(context).good : AppTheme.of(context).foreground,
),
);
}
@@ -409,9 +413,9 @@ class _ChecklistPageState extends State<ChecklistPage> {
final pending = b.pending.length;
final ack = b.acks.where((x) => x.id == last.id).firstOrNull;
final (String status, Color? color) = ack != null
? (ack.ok ? ('✓', null) : ('✗ ${ack.detail}', Colors.redAccent))
? (ack.ok ? ('✓', AppTheme.of(context).good) : ('✗ ${ack.detail}', AppTheme.of(context).alarm))
: b.pending.any((p) => p.id == last.id)
? ('… unacked', Colors.orange)
? ('… unacked', AppTheme.of(context).caution)
: ('?', null);
return Text(
'"${last.text}" $status${pending > 1 ? ' · $pending waiting' : ''}',