Square every corner, enlarge the main surfaces and add a to-do list

Rounded rectangles and round controls are now square across the app; only
status dots, glows, the sun, rings and the breathing circle stay round.
Cards, rows, thumbnails, featured cards, category tiles, the standing card
and the nav are larger. Home gets a quick To-do list kept on the device
(TodoItem in InternalMemory), seeded with sample items in mock mode.

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 14:50:31 +03:00
parent 36bc41509d
commit 9c858b8146
38 changed files with 478 additions and 186 deletions

View File

@@ -48,7 +48,7 @@ class TickBox extends StatelessWidget {
height: size,
decoration: BoxDecoration(
color: checked ? tone : Colors.transparent,
borderRadius: BorderRadius.circular(7),
borderRadius: BorderRadius.zero,
border: Border.all(
color: checked ? tone : colorGrey.withValues(alpha: 0.55),
width: 1.6,
@@ -202,7 +202,7 @@ Widget addTaskAffordance(
alignment: Alignment.center,
decoration: BoxDecoration(
color: tone.withValues(alpha: 0.12),
borderRadius: BorderRadius.circular(14),
borderRadius: BorderRadius.zero,
border: Border.all(color: tone.withValues(alpha: 0.25), width: 1),
),
child: Icon(Icons.add_rounded, size: 22, color: tone),

View File

@@ -32,7 +32,7 @@ Widget pill(
padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 5),
decoration: BoxDecoration(
color: background,
borderRadius: BorderRadius.circular(999),
borderRadius: BorderRadius.zero,
border: Border.all(color: foreground.withValues(alpha: 0.20), width: 1),
),
child: Row(
@@ -57,7 +57,7 @@ Widget pill(
/// The standard card surface.
Widget card({
required Widget child,
EdgeInsets padding = const EdgeInsets.all(16),
EdgeInsets padding = const EdgeInsets.all(20),
EdgeInsets margin = EdgeInsets.zero,
Color? background,
Color? borderColor,
@@ -70,7 +70,7 @@ Widget card({
margin: margin,
decoration: BoxDecoration(
color: background ?? colorCard,
borderRadius: BorderRadius.circular(radius),
borderRadius: BorderRadius.zero,
border: Border.all(color: borderColor ?? colorGlassBorder, width: 1),
boxShadow: const [
BoxShadow(
@@ -159,7 +159,6 @@ Widget emptyState(
height: 76,
decoration: BoxDecoration(
color: tone.withValues(alpha: 0.08),
shape: BoxShape.circle,
),
child: Icon(icon, size: 32, color: tone),
),
@@ -191,7 +190,7 @@ Widget meter(
: fraction;
return ClipRRect(
borderRadius: BorderRadius.circular(999),
borderRadius: BorderRadius.zero,
child: LinearProgressIndicator(
value: clamped,
minHeight: height,

View File

@@ -36,7 +36,7 @@ class FloatingNav extends StatelessWidget {
Expanded(
child: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(34),
borderRadius: BorderRadius.zero,
boxShadow: const [
BoxShadow(
color: Color(0x1A1A1F1C),
@@ -46,7 +46,7 @@ class FloatingNav extends StatelessWidget {
],
),
child: GlassSurface(
radius: BorderRadius.circular(34),
radius: BorderRadius.zero,
tint: colorGlassStrong,
padding: const EdgeInsets.all(6),
child: Row(
@@ -62,10 +62,9 @@ class FloatingNav extends StatelessWidget {
GestureDetector(
onTap: onAction,
child: Container(
width: 64,
height: 64,
width: 72,
height: 72,
decoration: BoxDecoration(
shape: BoxShape.circle,
gradient: const RadialGradient(
center: Alignment(-0.3, -0.4),
colors: <Color>[colorNightGlow, colorNight],
@@ -98,7 +97,7 @@ class FloatingNav extends StatelessWidget {
padding: const EdgeInsets.symmetric(vertical: 9),
decoration: BoxDecoration(
color: active ? colorWhite : colorWhite.withValues(alpha: 0.0),
borderRadius: BorderRadius.circular(28),
borderRadius: BorderRadius.zero,
boxShadow: active
? const [
BoxShadow(
@@ -113,7 +112,7 @@ class FloatingNav extends StatelessWidget {
mainAxisSize: MainAxisSize.min,
children: [
Icon(entry.icon,
size: 19, color: active ? colorInk : colorInkSoft),
size: 23, color: active ? colorInk : colorInkSoft),
const SizedBox(height: 4),
text(entry.label, 10, active ? TextType.Medium : TextType.Regular,
color: active ? colorInk : colorInkSoft, maxLines: 1),

View File

@@ -23,7 +23,7 @@ class GlassSurface extends StatelessWidget {
const GlassSurface({
super.key,
required this.child,
this.radius = const BorderRadius.all(Radius.circular(20)),
this.radius = const BorderRadius.all(Radius.zero),
this.padding = EdgeInsets.zero,
this.tint,
this.onDark = false,
@@ -60,7 +60,7 @@ class GlassSurface extends StatelessWidget {
Widget glassCircle(
IconData icon,
VoidCallback onTap, {
double size = 42,
double size = 50,
bool onDark = false,
bool dotted = false,
Color? dotColor,
@@ -73,7 +73,7 @@ Widget glassCircle(
children: [
GlassSurface(
onDark: onDark,
radius: BorderRadius.circular(size),
radius: BorderRadius.zero,
child: SizedBox(
width: size,
height: size,

View File

@@ -32,8 +32,8 @@ Future<Goal?> showGoalPicker(
decoration: const BoxDecoration(
color: colorSheetBackground,
borderRadius: BorderRadius.only(
topLeft: Radius.circular(28),
topRight: Radius.circular(28),
topLeft: Radius.zero,
topRight: Radius.zero,
),
),
child: ListView(
@@ -93,7 +93,7 @@ Widget _goalOption(
padding: const EdgeInsets.fromLTRB(14, 13, 14, 13),
decoration: BoxDecoration(
color: colorWhite,
borderRadius: BorderRadius.circular(14),
borderRadius: BorderRadius.zero,
border: Border.all(
color: selected ? accent.withValues(alpha: 0.5) : colorBorder,
width: selected ? 1.5 : 1,

View File

@@ -136,8 +136,8 @@ class Sheet extends StatelessWidget {
decoration: BoxDecoration(
color: light ? colorFrost : colorPrimaryLight,
borderRadius: const BorderRadius.only(
topLeft: Radius.circular(32),
topRight: Radius.circular(32),
topLeft: Radius.zero,
topRight: Radius.zero,
),
),
clipBehavior: Clip.antiAlias,

View File

@@ -27,7 +27,7 @@ Widget roundedCornerButton(
disabledBackgroundColor: colorGrey.withValues(alpha: 0.4),
padding: EdgeInsets.symmetric(vertical: verticalPadding),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(radius),
borderRadius: BorderRadius.zero,
),
),
child: Row(
@@ -65,7 +65,7 @@ Widget outlinedActionButton(
side: BorderSide(color: fg.withValues(alpha: 0.35), width: 1),
padding: const EdgeInsets.symmetric(vertical: 16),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(radius),
borderRadius: BorderRadius.zero,
),
),
child: Row(
@@ -112,7 +112,7 @@ Widget iconButton(
alignment: Alignment.center,
decoration: BoxDecoration(
color: background ?? Colors.transparent,
borderRadius: BorderRadius.circular(radius),
borderRadius: BorderRadius.zero,
border: bordered
? Border.all(color: borderColor ?? colorBorder, width: 1)
: null,
@@ -161,7 +161,7 @@ Widget segmentedSelector<T>({
padding: const EdgeInsets.symmetric(horizontal: 14, vertical: 10),
decoration: BoxDecoration(
color: isSelected ? active : colorWhite,
borderRadius: BorderRadius.circular(10),
borderRadius: BorderRadius.zero,
border: Border.all(
color: isSelected ? active : colorBorder,
width: 1,

View File

@@ -17,7 +17,7 @@ Widget countStepper(
padding: const EdgeInsets.fromLTRB(14, 10, 8, 10),
decoration: BoxDecoration(
color: colorWhite,
borderRadius: BorderRadius.circular(12),
borderRadius: BorderRadius.zero,
border: Border.all(color: colorBorder, width: 1),
),
child: Row(
@@ -54,7 +54,7 @@ Widget _stepButton(IconData icon, VoidCallback? onTap) {
alignment: Alignment.center,
decoration: BoxDecoration(
color: enabled ? colorSecondary : colorInset,
borderRadius: BorderRadius.circular(10),
borderRadius: BorderRadius.zero,
),
child: Icon(icon,
size: 14, color: enabled ? colorPrimaryDark : colorGrey),

View File

@@ -54,19 +54,19 @@ Widget inputField(
contentPadding:
const EdgeInsets.symmetric(horizontal: 14, vertical: 14),
enabledBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(12),
borderRadius: BorderRadius.zero,
borderSide: BorderSide(color: colorBorder, width: 1),
),
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(12),
borderRadius: BorderRadius.zero,
borderSide: BorderSide(color: colorPrimaryDark, width: 1.4),
),
errorBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(12),
borderRadius: BorderRadius.zero,
borderSide: BorderSide(color: colorNegative, width: 1),
),
focusedErrorBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(12),
borderRadius: BorderRadius.zero,
borderSide: BorderSide(color: colorNegative, width: 1.4),
),
errorStyle: TextStyle(
@@ -80,6 +80,36 @@ Widget inputField(
);
}
/// The bare add-a-line field used inside a card: no label, no box of its
/// own; return or the trailing button submits.
Widget quickAddField(
TextEditingController controller,
String hint,
ValueChanged<String> onSubmitted,
) {
return TextField(
controller: controller,
onSubmitted: onSubmitted,
textInputAction: TextInputAction.done,
style: TextStyle(
fontFamily: getTextType(TextType.Regular),
fontSize: 16,
color: colorInk,
),
decoration: InputDecoration(
hintText: hint,
hintStyle: TextStyle(
fontFamily: getTextType(TextType.Regular),
fontSize: 16,
color: colorInkSoft,
),
isDense: true,
border: InputBorder.none,
contentPadding: const EdgeInsets.symmetric(vertical: 14),
),
);
}
/// The excuse field. Deliberately unadorned — no templates, no quick-picks, a
/// live character count that shows the minimum, because the friction is the
/// feature rather than an obstacle to route around.
@@ -131,19 +161,19 @@ Widget excuseField(
fillColor: colorWhite,
contentPadding: const EdgeInsets.all(14),
enabledBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(12),
borderRadius: BorderRadius.zero,
borderSide: BorderSide(color: colorBorder, width: 1),
),
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(12),
borderRadius: BorderRadius.zero,
borderSide: BorderSide(color: colorPrimaryDark, width: 1.4),
),
errorBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(12),
borderRadius: BorderRadius.zero,
borderSide: BorderSide(color: colorNegative, width: 1),
),
focusedErrorBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(12),
borderRadius: BorderRadius.zero,
borderSide: BorderSide(color: colorNegative, width: 1.4),
),
errorStyle: TextStyle(
@@ -180,7 +210,7 @@ Widget selectField(
padding: const EdgeInsets.symmetric(horizontal: 14, vertical: 16),
decoration: BoxDecoration(
color: colorWhite,
borderRadius: BorderRadius.circular(12),
borderRadius: BorderRadius.zero,
border: Border.all(color: colorBorder, width: 1),
),
child: Row(