Redesign the UI after the fitness reference and replace the logo

Light sage-to-cream ambient backdrop, frosted glass controls and painted
SceneArt landscapes in place of photography. Home becomes a dashboard with a
two-tone greeting, a frosted summary ring, category portraits, an up-next rail
of image-led cards and a floating glass tab bar. The routine library gets an
image header and painted cards; the player gets a scene stage, steps on an
arc, a dotted clock and a night pill with a lime spark. Goals become painted
cards in their own colour.

New logo: a lime sun resting on a ground line under two arcs. The splash
raises the sun and lights the arcs; launcher icons and native splash are
regenerated to match.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KhQh614DMeYoQEH9SoMRUw
This commit is contained in:
alvocool
2026-11-02 12:33:13 +03:00
parent b31bc47cc0
commit fe268cb8aa
100 changed files with 3394 additions and 1387 deletions

View File

@@ -102,6 +102,47 @@ const List<Color> goalAccents = <Color>[
Color(0xFF3F6E73),
];
// ── Ambient ───────────────────────────────────────────────────────────────────
// The light, airy surface everything now sits on: sage mist drifting into
// cream, frosted glass for controls, ink for type and one lime spark for the
// primary transport control.
const Color colorAmbientTop = Color(0xFFD5E3DA);
const Color colorAmbientMid = Color(0xFFEAEFE6);
const Color colorAmbientBottom = Color(0xFFF5F1E6);
const Color colorAmbientGlowSage = Color(0xFFB9D6C4);
const Color colorAmbientGlowWarm = Color(0xFFF3DEC0);
const Color colorInk = Color(0xFF1A1F1C);
const Color colorInkSoft = Color(0xFF8E9690);
const Color colorGlass = Color(0x8CFFFFFF);
const Color colorGlassStrong = Color(0xD9FFFFFF);
const Color colorGlassBorder = Color(0xB3FFFFFF);
const Color colorLime = Color(0xFFB9F25B);
const Color colorNight = Color(0xFF18211C);
const Color colorFrost = Color(0xE6F6F7F2);
// Night lit from the top-left: the tile, the insight card, the action button.
const Color colorNightLift = Color(0xFF2B3A31);
const Color colorNightGlow = Color(0xFF3A4A40);
// The overdue callout: a warm blush rather than an alarm panel.
const Color colorOverdueWarm = Color(0xFFF9E1D8);
const Color colorOverdueWarmEnd = Color(0xFFFFF6EF);
const Color colorOverdueGlow = Color(0xFFD7654B);
// ── Scene art ─────────────────────────────────────────────────────────────────
// The painted landscapes that stand in for photography on cards. Each kind has
// a sky (top → horizon), a sun, three ridges (far → near) and an ember accent.
const List<Color> sceneWorkout = <Color>[
Color(0xFF9CCBB0), Color(0xFFEFF1DC), Color(0xFFFFD49A),
Color(0xFF86B79B), Color(0xFF4E8C6F), Color(0xFF24563F), Color(0xFFE5793D),
];
const List<Color> sceneMeditation = <Color>[
Color(0xFFAEB8E6), Color(0xFFF6E3E2), Color(0xFFFFE6C6),
Color(0xFFA2A9D6), Color(0xFF7480B8), Color(0xFF3F4A7A), Color(0xFFF2A6A0),
];
const List<Color> sceneMustDo = <Color>[
Color(0xFFEBCFA3), Color(0xFFF8F0E0), Color(0xFFFFB46B),
Color(0xFFD9B37F), Color(0xFFB0834A), Color(0xFF6B4C26), Color(0xFF2F6F4E),
];
// ── Debt / charting ───────────────────────────────────────────────────────────
const Color colorDebtLine = Color(0xFFB5442F);
const Color colorDebtFill = Color(0x1AB5442F);

View File

@@ -352,3 +352,55 @@ String targetLabel(DateTime? target) {
}
return "$days day${days == 1 ? "" : "s"} left";
}
/// The painted landscape a routine kind wears on its cards.
List<Color> scenePalette(RoutineKind value) {
switch (value) {
case RoutineKind.Workout:
return sceneWorkout;
case RoutineKind.Meditation:
return sceneMeditation;
case RoutineKind.MustDo:
return sceneMustDo;
}
}
/// A landscape tinted from a goal's accent, so a goal's cards read as its own.
List<Color> goalScene(Color accent) {
final HSLColor base = HSLColor.fromColor(accent);
Color shade(double lightness, double saturation) => base
.withLightness(lightness)
.withSaturation((base.saturation * saturation).clamp(0.0, 1.0))
.toColor();
return <Color>[
shade(0.80, 0.55),
const Color(0xFFF6EFE2),
const Color(0xFFFFD9A0),
shade(0.66, 0.6),
shade(0.48, 0.8),
shade(0.30, 0.9),
const Color(0xFFE5793D),
];
}
/// The landscape for a task row, chosen by how much the task weighs.
List<Color> classScene(CommitmentClass value) {
switch (value) {
case CommitmentClass.NonNegotiable:
return sceneMustDo;
case CommitmentClass.Standard:
return sceneMeditation;
case CommitmentClass.Elective:
return sceneWorkout;
}
}
/// A stable seed from any string, so the same item always gets the same scene.
int sceneSeed(String key) {
int hash = 7;
for (int unit in key.codeUnits) {
hash = (hash * 31 + unit) & 0x7fffffff;
}
return hash;
}

View File

@@ -2,8 +2,8 @@ const String imagePath = "assets/images";
const String iconPath = "assets/icons";
/// The anchor mark, matching the native splash so the handover is invisible.
const String splashMark = "$iconPath/splash.png";
/// The mark on a night disc, as the native splash shows it.
const String splashMark = "$iconPath/splash_orb.png";
const String logoMark = "$iconPath/icon.png";