Groups let people keep each other honest: create one or join with a six-letter invite code. Each group has shared goals split into measurable objectives (km, sessions, words) that every member logs toward, a leaderboard of kept rate and streak with nudges, and a group chat where check-ins and nudges appear as cards beside the talk. The open chat polls for new messages. Reached from a new Groups tab (Training moves into the day rail), a Home "Your groups" rail that opens the chat, and a Group tile in the add sheet. Mock mode seeds two groups, a joinable one and members who reply. The water tracker is removed; it did not fit the app. Bottom sheets are now square app-wide via the theme. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01KhQh614DMeYoQEH9SoMRUw
5.4 KiB
Grounded — Design Language
Reference: an airy fitness-app look. Sage mist drifting into cream behind
everything (AmbientBackground), frosted glass for controls and floating
chrome (GlassSurface, glassCircle), ink type with a soft grey second
tone, painted landscapes instead of photography (SceneArt), a floating
glass tab bar with a dark square action button (FloatingNav), and one lime
spark on night-green for the primary control.
Building blocks (designs/)
| Piece | Use |
|---|---|
AmbientBackground |
The backdrop for every light screen. |
GlassSurface / glassCircle |
Frosted panels and square controls; onDark over a scene or tinted stage. |
SceneArt |
Painted sky, sun and ridges with an optional figure glyph. Palettes come from scenePalette(kind), goalScene(accent), classScene(class); seed with sceneSeed(title) so an item always wears the same picture. |
DotDigits |
The dotted clock in the routine player. |
FloatingNav |
Home's tab bar; the selected tab is a filled night block. The side action button is optional. |
GroundedMark |
The logo, drawn — a lime sun on a ground line under two arcs. The launcher PNGs in assets/icons/ were rendered from the same geometry. |
Cards are image-led where an item has a kind (routines, goals, tasks): scene on
top or as a thumbnail, white type over the shaded lower half, three light
numbers along the bottom. Greetings are two-tone: Medium ink, then Regular
colorInkSoft. Primary buttons are square night bars with a lime icon.
Sheet is light (ambient) by default; passing chrome, banner or
scene gives a tinted stage with white type. Home, Routines and the player
build their own layouts from the same pieces.
The sections below describe the original record-style type scale, which still applies to labels and metrics.
Type — General Sans
| Role | Family | Size | Use |
|---|---|---|---|
| Display | TextType.Light |
30–44 | Screen titles. Always light, never bold. |
| Title | TextType.Bold |
17–20 | Card and section titles. |
| Body | TextType.Regular |
13–14, height: 1.5 |
Descriptions, copy. |
| Label | TextType.Bold |
10–11, letterSpacing: 0.8–1.2, uppercase, colorGrey2 |
Metadata above a value. |
| Metric | TextType.Bold |
24–34 | Debt score, counts. |
The label/value pair is the core unit: a tiny grey all-caps label sitting directly above a large dark value. Used everywhere numbers appear.
Geometry
- No rounded corners anywhere: sheets, cards, chips, buttons, fields, tiles and portraits are all square (
BorderRadius.zero). Only small status dots, glows, the sun, progress rings and the breathing circle stay round. - Screen padding
20horizontal. Card padding16. Section gap28. - Hairlines at
colorDivider(black 7%), borders atcolorBorder(black 8%). - One soft shadow only:
0 4 18 rgba(0,0,0,0.03). No coloured glows.
Colour
Near-black ink (colorPrimaryDark #141414) on warm off-white
(colorPrimaryLight #EDEEEA), with a single green accent (colorPrimary #2F6F4E). Enforcement tiers own the rest of the palette:
| Standing | Colour |
|---|---|
| Good | green #2F6F4E |
| Warned | amber #C98A04 |
| Grounded | rust #B5442F |
| Lockdown | oxblood #7A1F14 |
The tier colour is used consistently — header, chip, meter, queue accent — so the standing is legible without reading the word.
Structure
Every screen is: black headerBar (back, title, action) → white sheet with a
square top edge → sectionHeader (label + light display title) → content.
Rules
- Display titles are Light. Bold is for labels and metrics only.
- Numbers get a label above them, never beside them.
- Chips carry state, never actions.
- One primary button per screen; everything else is outlined or text.
- Empty states are plain. An empty overdue queue is good news, not a party.
Home
Home opens on a deep forest header block (colorHeaderTop → colorHeaderBottom):
greeting and avatar, a Today / Weekly toggle, a seven-day streak panel ending
today (a leaf on every kept day, kept = 80%+), then the numbers. Today shows
minutes held against planned, a ring with + that opens the "Add to today"
sheet, the plan as thumbnails, the report-card letter as the Score, and one
bar per commitment class. Weekly swaps in the week's average, a bar per day
and the class completion rates. Below the block, on the light ambient
surface: the rest of the day. Bars on the dark block use the colorBar* tokens.
Groups
see/group/: people keeping each other honest. A group has members, shared
goals and a chat.
- Shared goals are split into objectives with a number and a unit (200 km, 40 runs, 30,000 words). Every member logs toward them; the card shows the group total, your share and a night Log button. Like personal goals, they carry no debt.
- Leaderboard ranks members by kept rate over the last 7 days, with streak, last check-in (red "quiet" after 24h) and a nudge button.
- Chat keeps the work and the talk together: plain messages are square bubbles (yours in night, others white with the author's colour), while check-ins (green bar) and nudges (amber bar) are cards in the thread. The open chat polls every 4 seconds.
- Members are drawn by
memberAvatar/avatarStack(designs/MemberAvatar.dart): square painted portraits with the initial. - Groups are reached from the nav (Groups tab), the Home "Your groups" rail (tap opens the chat) and the add sheet.