Skip to main content

Canthus — Design System & Copy Reference

Version 2.4 | March 2026
North Star: Protect the user’s mental state first. Enable task completion second.
Every colour, typeface, spacing decision, animation, and word choice in this system must pass one question: does this make the person feel capable, or does it subtly imply failure? This is not a productivity app. It is a capacity tool for people whose capacity fluctuates unpredictably. Every design choice flows from this distinction.

Table of Contents

  1. Typography
  2. Colour System
  3. Spacing & Layout
  4. Elevation & Depth
  5. Iconography
  6. App Structure & Navigation
  7. Core Components
  8. Temporal Tasks & Appointments
  9. Add Task Flow
  10. Motion & Animation
  11. Copy System
  12. Accessibility
  13. Data & Privacy
  14. What This System Does Not Do

1. Typography

1.1 Font Pairing

Primary (body text): Atkinson Hyperlegible Developed by the Braille Institute specifically for low vision and reading difficulty. Used for all body text, labels, and captions. Chosen for its proven legibility during cognitive fatigue and its unique letterforms that prevent common misreadings (b/d, i/l, 0/O). Free on Google Fonts, available in Flutter via google_fonts. Display (headings): DM Sans A warm humanist sans-serif used in Bold and SemiBold weights for headings and the mana display number. Brings warmth and approachability to high-visibility elements without sacrificing readability. Also free on Google Fonts. Why this pairing: Atkinson Hyperlegible provides the strongest accessibility foundation where it matters most — body text the user reads repeatedly during cognitive fatigue. DM Sans display weights bring warmth and character to high-visibility elements.

1.2 Type Scale

TokenFontSizeWeightLine HeightLetter SpacingUse
displayDM Sans28sp7001.2-0.3pxMana number, screen hero text
heading-1DM Sans22sp6001.3-0.2pxScreen titles
heading-2DM Sans18sp6001.35-0.1pxSection headers, card titles
body-lgAtkinson16sp4001.650Primary task text
bodyAtkinson14sp4001.650Supporting content
labelAtkinson13sp7001.00.2pxButtons, nav labels, chips
captionAtkinson12sp4001.50.1pxTimestamps, hints

1.3 Hard Rules

  • Minimum readable size: 14sp. Nothing the user needs to read is smaller.
  • Body line height: never below 1.5. Non-negotiable for brain fog readability.
  • No italics for body text. Increases cognitive load for visual processing difficulties.
  • No label-as-placeholder pattern. Form fields always show a persistent visible label.

2. Colour System

Dark mode is the designed and primary experience. Light mode is deferred. All contrast ratios are validated against dark mode pairings.

2.1 Compliance

This system targets compliance with three standards, all of which converge on the same contrast requirements:
  • WCAG 2.1 AA — 4.5:1 normal text, 3:1 large text, 3:1 UI components
  • ADA (2024 DOJ rule) — requires WCAG 2.1 AA for digital services
  • European Accessibility Act 2025 — mandates EN 301 549 v3.2.1, which references WCAG 2.1 AA
Meeting WCAG 2.1 AA satisfies all three.

2.2 Dark Mode Foundation

TokenHexUse
bg-base#13141CApp background
surface-1#1C1D29Cards, elevated surfaces
surface-2#272839Input fields, secondary surfaces
surface-3#353647Tertiary surfaces, hover states
border#606388Dividers, card outlines
border-strong#7578A0Focused inputs, emphasis borders

2.3 Text Colours

All ratios measured against bg-base (#13141C).
TokenHexRatio vs bg-baseNotes
text-primary#F1F1FA16.2:1 ✅ AAAMain content text
text-secondary#A3A5C89.3:1 ✅ AAASupporting text
text-tertiary#8385A84.7:1 ✅ AAHints, timestamps
text-disabled#4849632.1:1 ❌ intentionalDisabled state — WCAG exempts disabled components
⚠️ Tertiary text constraint: text-tertiary only passes contrast on bg-base. It must not be used on card surfaces (surface-1 or surface-2). On cards, use text-secondary as the minimum for any readable text. This is a hard rule.
Disabled text: Always accompanied by a non-colour indicator (strikethrough or lock icon). The low contrast communicates non-interactivity.

2.4 Mana Accent

TokenHexRatio vs bg-baseUsage rules
mana-50#0E0F1ASubtle fill only, never for text
mana-100#161829Background chips
mana-200#252A4AMana cost icon washed state
mana-300#3A4280Hover/pressed states
mana-400#5560CC3.1:1UI components, borders, icons — not for body text
mana-500#6B73D84.4:1Large text (18sp+) or icons only
mana-600#8E96E66.2:1Primary interactive text, active labels
mana-700#B8BCF09.1:1High-emphasis mana text (mana number)
Key rule: Any mana-coloured text at body size must use mana-600 minimum. mana-400 is only for UI components (icons, borders), never body text.

2.5 Semantic Colours

TokenHexRatioUse
success#5DBF8A7.2:1Task completed
caution#D4A8436.8:1Gentle heads-up, deadline approaching
rest#9B8FD45.3:1Recovery day, rest state
critical#E070604.8:1Genuine errors only
Rule: Semantic colour is never the sole state indicator. Every coloured state has a companion shape, icon, or label. This satisfies WCAG 1.4.1 (Use of Colour).

2.6 Contrast Validation Summary

All text/background pairings used in the system have been validated. The key constraints to remember:
  • text-primary, text-secondary pass on all surfaces
  • text-tertiary passes on bg-base only
  • text-tertiary fails on surface-1 (3.7:1) and surface-2 (2.9:1) — never use it on cards
  • mana-600 passes on bg-base (6.2:1) and surface-1 (4.9:1)
  • ✅ All semantic colours pass on bg-base

3. Spacing & Layout

3.1 Grid

Base grid: 8pt. Micro-adjustments: 4pt.
TokenValueUse
space-14pxMicro — icon internal padding, tight badges
space-28pxXS — tight internal spacing
space-312pxSM — compact card padding
space-416pxMD — standard gap, content padding
space-520pxLG — section gaps
space-624pxXL — between cards
space-832px2XL — major section breaks
space-1248px3XL — hero areas

3.2 Screen Layout

  • Horizontal margins: 20px (wider than standard 16px — reduces density and overwhelm)
  • Safe areas: Always respected. Nothing behind notch, dynamic island, or home indicator.
  • Content never truncates at any system text scale setting.

3.3 Touch Targets

  • Minimum: 48×48dp for all interactive elements (WCAG 2.5.8 AA)
  • Primary actions: 56×56dp
  • Minimum gap between targets: 8dp
  • All swipe gestures have a tap alternative (WCAG 2.5.1)

3.4 Corner Radius

TokenValueUse
radius-sm8pxChips, tags, small badges
radius-md12pxCards, inputs, task cards
radius-lg16pxBottom sheets, large cards
radius-xl24pxModals, nav bar pill
radius-full9999pxButtons, completion circles, pills

4. Elevation & Depth

Hierarchy uses colour temperature shift, not drop shadows. Surfaces get progressively warmer as they elevate. This produces lower visual noise than shadows and works better in dark mode.
LevelSurface TokenAdditional TreatmentUse
0bg-baseNoneApp base
1surface-1NoneCards at rest
2surface-21px border top edge onlyFocused states, active cards
3surface-3Subtle mana-tinted glow rgba(85,96,204,0.06)Bottom sheets, floating nav
4surface-3Stronger mana glow rgba(85,96,204,0.12)Critical overlays
The mana-tinted glow at levels 3–4 is a barely-perceptible aura, not a hard shadow. It reinforces the mana metaphor at a subconscious level.

5. Iconography

5.1 Philosophy

Icons carry the mana/wizardry metaphor. They should feel like objects from an arcane world — not gamified (no cartoonish effects), not clinical (no medical crosses or charts), not corporate (no briefcases or bar graphs). The aesthetic is quiet enchantment — things that feel like they belong in an apothecary or a scholar’s study.

5.2 Style Specifications

  • Grid: 24×24dp base, 2dp padding (20dp content area)
  • Stroke weight: 1.5px at 24dp — slightly lighter than standard, more delicate and arcane
  • Corners: Fully rounded joins and terminals — no sharp points
  • Style: Outline at rest, filled/glowing for active states
  • Colour at rest: text-tertiary
  • Colour active: mana-600 fill with subtle mana-400 glow

5.3 Mana Cost Icons — Crystal Orbs

The mana cost metaphor uses crystal orbs — spherical gems that show fill level, connecting directly to the mana pool concept. Four tiers:
TierVisualCost Range
1Single small orb1–3 mana
2Single larger orb with inner glow4–8 mana
3Orb with orbiting spark9–15 mana
4Double orb cluster with radiant burst16+ mana
Each tier has a washed state (using mana-200 outlines) and a filled state (using mana-500 through mana-700). The number itself is shown in caption size beside the orb cluster.

5.4 Full Icon Set

IconMetaphorUse
Crystal orb (4 tiers × 2 states)Glowing sphereMana cost on tasks
Mana pool / cauldronBubbling vesselMana screen, pool display
Rune / sigilAbstract geometric markCheck-in state, loading
Wand / sparkThin wand with star tipAdd task, create action
ScrollRolled parchmentTask list item
Seedling / sproutSmall growing plantOrchard tab icon
Constellation3 connected starsInsights / pattern view
Moon phaseCrescentRest day, low mana state
Hourglass (arcane)Sand timer with rune markingsTemporal task indicator
ShieldSimple rounded shieldProtection mode, essential task flag
EyeArcane eyeTransparency panel
SpiralInward spiralLoading, calibrating
Flame (small)Gentle candle flame”Warmth” indicator (not a streak)
Body axisSimplified personCheck-in body axis
Brain / star burstAbstract neural burstCheck-in mind axis
HeartSoft heartCheck-in mood axis
Settings / compassArcane compass roseSettings

6. App Structure & Navigation

6.1 Three Tabs

TabPurposeWhat it contains
ManaWhere the user learns what they have todayCheck-in, pool display, upcoming appointments, patterns
TasksSurvival and maintenance tasksOnly tasks achievable within current pool, plus essential tasks always
OrchardLeisure, hobbies, passion projectsSame mana pool — creative nourishment is equal to chores
The Mana tab is the primary entry point. The full 3-axis check-in is the recommended daily path and produces the most accurate pool. However, the Tasks and Orchard tabs are never hard-locked. A tiered check-in system (§7.1) ensures users always have access to their task list, with data quality degrading gracefully when a full check-in isn’t possible. The system needs a state vector to compute the pool accurately — but on days when the user cannot provide one, the system estimates rather than blocks. Why the Orchard has equal status to Tasks: Purely restrictive pacing is no more effective than standard care. Enabling users to plan and protect mana for the things they love — not just survival tasks — is clinically supported and philosophically essential.

6.2 Navigation Bar

  • Floating pill shape, surface-3 background, level-3 mana glow, radius-xl
  • 16px above bottom safe area edge, width = screen width minus 32px
  • Active: mana-600 filled icon + label, mana-100 circle background behind icon
  • Inactive: text-tertiary outline icon, no label
  • Before check-in: All three tabs are navigable. Tasks and Orchard use estimated pools (see §7.1 tiers). A subtle text-secondary banner at the top of Tasks/Orchard reads: “Your mana is estimated today — check in when you’re ready for a better reading.” The banner is dismissable.
  • Touch targets: 56dp each

7. Core Components

7.1 Mana Screen

The first screen the user sees each day. Single scrollable column — all content in one continuous flow.

State A — Check-in required

The screen opens showing the full 3-axis check-in as the recommended path. Three rows, one per axis (Body, Mind, Mood). Each axis is a 1–5 scale implemented as five large tappable circles (56dp each). No sliders — sliders require fine motor precision that isn’t appropriate for this audience. Anchor labels for each axis:
AxisLow EndHigh End
Body”Moving gently""Feeling strong”
Mind”Foggy today""Sharp and clear”
Mood”A hard one""Really good”
No numbers on the circles. After all three are selected, a single primary button appears: “See my mana”. Below the primary button, two alternative paths are visible: Quick check-in (ghost button): Opens a single-question view — “How are you today?” with three large tappable options: “Rough day”, “Okay day”, “Good day”. These map to pre-defined state vectors derived from the user’s personal history (25th / 50th / 75th percentile of recorded states, or [2,2,2] / [3,3,3] / [4,4,4] for new users). Produces a valid state vector in one tap. The pool is computed. Tasks surface. Data is less precise but clinically defensible — it approximates the single-dimension energy rating used in Energy Envelope research. “Skip for now” (text link): If yesterday’s check-in exists, carries forward yesterday’s state vector with a conservative dampening factor (each axis × 0.9, floored at 1). If no yesterday exists, uses the user’s historical median with an 0.8 multiplier applied to the resulting pool. In both cases, the system marks this as an inferred check-in with reduced confidence weighting. The full check-in remains the visually prominent path. The alternatives are clearly available without being emphasised — easy to find, hard to abuse.

State B — Check-in complete

Shows the daily mana pool (see Pool Display below), then scrollable content: check-in summary pills, Upcoming section, Your Patterns section.

7.2 Pool Display

  • Large mana number in display style, mana-700, centred
  • Below: the word “mana” in body, mana-400
  • Below: crystal orb icons indicating pool tier (decorative)
  • Below: a single transparency sentence in body, text-secondary — explains why today’s pool is what it is
The pool display deliberately does not show a bar, a percentage, or a fraction. Just the number and its context sentence.

7.3 Task Card

The repeating unit for both Tasks and Orchard screens. Anatomy:
  • Container: surface-1, radius-md, 1px border stroke
  • Left accent bar: 3px wide, full card height, colour maps to mana tier
  • Completion target: 44dp circle, border stroke at rest
  • Task name: body-lg, text-primary
  • Subtitle: caption, text-secondary (not tertiary — must pass contrast on surface-1)
  • Mana cost: right-aligned orb cluster + number in caption, mana-600
Visibility rule: Tasks whose mana cost exceeds the remaining pool are not shown, with one exception: essential tasks (see §7.3.1). Non-essential over-budget tasks don’t appear greyed out, dimmed, or locked — they simply surface when conditions allow. Absence is less distressing than visible unavailability. The user is not confronted with things they cannot do. States: Default → Selected (multi-complete mode) → Completing (800ms hold) → Completed (slides out, moves to “Done today” section) Orchard variant: Identical structure with a seedling icon replacing the completion circle. Uses a “Tend” action rather than “Complete”.

7.3.1 Essential Tasks

A task can be flagged as essential by the user via a toggle at creation or edit time: “This is essential” (with a small shield icon). Essential tasks are things the user cannot safely skip — medication, feeding a dependent, critical medical appointments. The toggle is off by default. The app does not suggest which tasks should be essential — the user decides. Surfacing rules: Essential tasks are always visible on the Tasks screen, regardless of pool. Their display adapts based on whether they fit within the remaining pool:
  • Within pool: Standard task card. No special treatment. The essential flag is invisible in normal operation — it only activates below the pool threshold.
  • Over pool: The task card appears with a distinct treatment:
    • Card background shifts to surface-2 (slightly elevated — this card is different)
    • Mana cost orbs use caution amber instead of standard mana colour
    • A single line below the task name: “This will use more than you have today” in caption, text-tertiary
    • The completion circle remains active — completing an over-pool essential task pushes the user into overflow, which the existing system handles gracefully
  • On rest days (pool ≤ 5): Essential tasks appear in a dedicated “Essentials” section at the top of the Tasks screen, above any regular tasks. Section header: “What matters most today” in heading-2, text-primary. Below it: “These are your essentials. Everything else can wait.” in caption, text-secondary.
Essential flag limit: If a user marks more than 5 tasks as essential, a soft prompt: “You have quite a few essentials — on a tough day, fewer means easier. Would you like to review which ones are truly must-dos?” This is a suggestion, not a block. Appointments on their day are implicitly essential — the anchor card treatment (§8.4) already handles this. No additional essential flag needed.

7.4 Multi-Task Completion

Long press on any task card enters multi-complete mode. User taps additional cards to select, then taps “Complete all” — all selected cards animate simultaneously in a single 800ms hold. Completing 10 tasks takes: 1 long press + 9 taps + 1 confirm + 800ms (not 10 × 800ms = 8 seconds of forced waiting).

7.5 Stability Indicator

A small ambient constellation icon in the top-left corner of the Mana screen. Three dots connected by two thin lines forming a triangle. Only the colour changes across states. Availability: Not shown until 14 check-in days recorded.
StateColourMeaning
Stablemana-400Consistent rhythm for 14+ days
Transitionaltext-tertiaryPattern is settling or recovering
Unstabletext-secondaryRegime shift detected — app is adjusting
The icon is never absent once the threshold is reached — removing it during bad periods would itself be a worse signal. No animation, no pulsing. Long-press shows a one-sentence tooltip.

7.6 Your Patterns Section

Lives at the bottom of the Mana screen scroll. Three tabbed panels: Rhythm (available from 5 check-in days) — 14-day bar chart showing daily mana spend (what was done, not what was available). Y-axis uses named bands (Rest / Gentle / Moderate / Full) relative to personal baseline. No numerical axis by default. Long-press any bar for a percentage tooltip. Days (available from 21 check-in days) — Weekly pattern view showing average spend per day of the week over 28 days. Purely a cross-day comparison — cannot show a directional trend. Balance (available from 7 check-in days) — Proportion bar showing physical vs cognitive mana split over 14 days. Descriptive context sentence below (e.g. “A fairly even mix lately”). Purely descriptive, never implies the balance should change. Missing days are filled with greyed estimated bars (using day-of-week average or personal baseline), with honest tooltips explaining the estimation. PEM recovery banner: Shown above active panel content when the system is in post-PEM recovery. Text: “Your pattern is in recovery — this data reflects a difficult stretch. It will settle as you feel better.” Below the banner text, a quiet text link: “Do you know what triggered this?” — tapping opens a bottom sheet listing completed tasks from the past 7 days. The user can select tasks they believe triggered the crash, or tap “Not sure” to dismiss. This is never prompted via notification or modal — it appears only within Patterns, only when scrolled to, only during recovery.

7.7 Buttons

VariantBackgroundTextHeight
Primarymana-400bg-base52dp
SecondaryTransparentmana-600 (1.5px mana-400 border)52dp
Destructivecritical @ 20%critical (1px critical border)52dp
GhostTransparentmana-60044dp
All buttons: label type, radius-full, 48dp minimum touch target. Destructive actions always require two confirmations.

7.8 Bottom Sheets

  • Background: surface-3, radius-lg top corners, flat bottom
  • Drag handle: 36×4px, border-strong, centred, 12px below top edge
  • Overlay: rgba(20,18,16,0.72) — warm-tinted dark scrim
  • Always dismissible by drag or overlay tap
  • Max height: 85% screen height with internal scroll

8. Temporal Tasks & Appointments

8.1 Philosophy

Temporal tasks are treated as a capacity problem, not a time problem. The design never says “you are running out of time.” It says “here is what this needs, and here is what you have.” This is grounded in stress appraisal theory: the same deadline can be appraised as a threat (“I might fail”) or a challenge (“here is what I need to solve this”). The system systematically produces challenge appraisal. PEM risk from emotional distress is equivalent to physical exertion — a poorly designed urgency signal is a medical risk.

8.2 Two Task Types

Deadline tasks — Can be completed on any day within a window. “Pay electricity bill by Thursday.” Governed by the horizon system. Appointment tasks — Fixed to a specific day and time. A GP visit, a hospital scan. Cannot be completed early or deferred without real-world consequence.

8.3 Deadline Tasks — Horizon System

WindowBehaviour
> 7 days outInvisible — not in any list
3–7 days outSurfaces in task list with hourglass icon and calm date label
< 3 days outHourglass becomes filled, caution amber pill label added
Day ofAmber pill reads “Today” — single word, no countdown
The horizon window (default 7 days) is per-task configurable at creation. A “Show upcoming” toggle is available for users who prefer full visibility. No red states at any point — caution amber is the maximum urgency signal. Date labels use day names only — “Thursday”, not “3 days” or “Due Thu 14 Mar”. Day names are calendar-natural. Countdowns are pressure.

8.4 Appointment Tasks

Created via a “This happens on a specific day” toggle. Fields: name, date, optional time, mana estimate (1–5 scale), optional recurrence, optional notes. Mana reservation: On creation, users can set aside mana for the appointment day. On the day, the pool reflects the reservation and task surfacing uses the reduced available mana. Day-of Anchor card: Appears at the top of the Tasks screen, surface-2 background, caution amber accent bar, filled hourglass icon. Cannot be swiped away — can only be marked as attended. Needs Updating flow: If an appointment passes without being marked attended, it moves to a “Needs updating” section (never “Missed” or “Failed”). The correction window is 3 check-in days (not calendar days) — a user in a flare who hasn’t opened the app is not locked out.

8.5 Day-Before Notification

Sent at 11am (configurable 8am–6pm). Suppressed if the user has already viewed the Upcoming section that day. Appointment name is never included in the notification body — lock screen privacy. Single appointment: “You have something tomorrow that will take some energy.” Multiple: “You have a couple of things tomorrow that will take some energy.”

9. Add Task Flow

9.1 Philosophy

Task creation must never cost more energy than the task itself. Two principles: fast capture first, detail optional second, and the task exists the moment the user names it.

9.2 Two-Step Flow

Step 1 — Quick Capture (half-height bottom sheet):
  • Text input for task name (keyboard raised immediately)
  • Duration field (natural language: “20 minutes”, “half an hour”)
  • Destination chips: Task · Orchard · Appointment
  • Essential toggle (shield icon, off by default) — only shown for Task destination
  • Two buttons: Done (creates immediately) and More (expands to detail)
Step 2 — Detail Layer (full-height sheet, all fields optional):
  • Name (pre-filled)
  • Duration (chip selector: Quick 5min / Short 15min / Medium 30min / Long 60min / Custom)
  • Difficulty rating 1–5 (“How much energy does this usually take you?”) — shown with the same “big circles” UI pattern as the check-in, positioned as the first detail field after name and duration to emphasise its importance
  • Physical or Mental? (Physical / Mix / Mental)
  • Essential toggle (if not already set in Step 1)
  • Live mana preview
  • Notes, Repeat options

9.3 Cost Estimation Pipeline

Runs automatically as the user types. Five steps in priority order:
  1. Personal library lookup — Matches against tasks the user has previously created/completed. Token-level Levenshtein distance matching with recency weighting. After 10 completions of a personal library task, template-derived costs are permanently overridden by the user’s actual patterns.
  2. System template lookup — Matches against bundled task templates. Same Levenshtein matching.
  3. Semantic embedding match — On-device MiniLM-L6-v2 model (~22MB) computes cosine similarity against pre-encoded template embeddings.
  4. LLM estimation (opt-in) — On-device model preferred, cloud fallback sends task name only.
  5. Difficulty rating fallback — User rates 1–5 manually.
Medium-confidence matches show a confirmation chip: “Looks similar to [Template Name] — right?” with Yes/No options.

9.4 Mana Cost Display States

StateTriggerAppearance
KnownHigh-confidence match or all fields user-confirmedNormal colour, full opacity
UncertainAny field defaulted50% opacity, text-tertiary colour
RangeFuture-day task with calculable rangeShows ~X or X–Y
UnknownNo match, no user inputShows ?
Tapping the mana cost area in any non-Known state opens the task detail for editing.

10. Motion & Animation

10.1 Principles

No spring physics. No bounce. No overshoot. No parallax. No looping animations except the mana calibration loading state (slow spiral rotation, stops when complete). Vestibular disorders are common in ME/CFS, fibromyalgia, and POTS. Any motion suggesting rotation, oscillation, or rapid movement can trigger symptoms. Transitions should feel like the UI is already in the right state before you noticed it moved.

10.2 Duration & Easing

TokenDurationCurveUse
motion-instant0msReduce Motion mode only
motion-fast120msease-standardToggle states, icon changes
motion-med220msease-enterCard selections, panel opens
motion-slow380msease-enterScreen transitions, bottom sheet entry
motion-complete800msease-standardTask completion hold
CurveValue
ease-standardcubic-bezier(0.4, 0.0, 0.2, 1.0)
ease-entercubic-bezier(0.0, 0.0, 0.2, 1.0)
ease-exitcubic-bezier(0.4, 0.0, 1.0, 1.0)

10.3 Reduce Motion

Detected via MediaQuery.of(context).disableAnimations in Flutter. When enabled:
  • All transitions become instant opacity fades at motion-fast (120ms, opacity only)
  • Task completion hold retained at 400ms with opacity fade only (success feedback preserved, motion removed)
  • No exceptions. Every animation has a declared Reduce Motion variant.

11. Copy System

11.1 Voice

The app speaks as a calm, knowledgeable friend who happens to understand energy management. Not a medical professional (clinical distance), not a productivity coach (pressure), not a cheerleader (false positivity). Warm, matter-of-fact, never surprised by difficulty. Copy principles:
  • Honest. The system does not hide bad states. Users with chronic illness know when they’re in a bad period.
  • Non-patronising. Never tell the user how to feel or what they should do.
  • Non-prescriptive. Avoid “you should”, “you need to”, “make sure to”.
  • No urgency manufacture. The user already has enough. Do not add to it.
  • No false positivity. Don’t celebrate low activity or frame hard days as opportunities.

11.2 Banned Phrases

❌ BannedWhy✅ Replacement
”You only completed…”Frames completion as a scoreDon’t surface completion counts this way
”Don’t forget…”Creates urgencyRemove or rephrase as neutral info
”You’re falling behind”Implies failureNever use
”Great job!” / “You did it!”Patronising for adults managing illnessRemove or use neutral acknowledgement
”Push yourself” / “Keep going!”Encourages overexertionNever use
”No tasks completed today”Frames rest as failure”Nothing tracked today” or nothing at all
”Streak”Implies continuity is a goalNever use
”Overdue”Guilt-inducing”Carried over”, or remove
”You missed…”BlameNever use
Any red urgency indicator on tasksVisual guiltDo not implement
”Low energy”Clinical framing”Gentle day"
"Depleted”Deficit language”Resting"
"Task too expensive”Transactional”Save this for a stronger day"
"Failed to complete”Failure language”Carried forward"
"Insufficient mana”System language”Not quite yet"
"Try harder”Never, under any circumstances
”Welcome back”Implies leaving was notableDon’t comment on absence
”We missed you”Implies obligation to use the appDon’t comment on absence

11.3 Copy by Context

Low capacity day: Show the shorter task list without comment. If a label is needed: “Today’s list” or nothing. Never say “You don’t have much energy today. Take it easy!” Rest day with essentials (pool ≤ 5): The Essentials section header reads “What matters most today”. Below it: “These are your essentials. Everything else can wait.” No commentary on the low pool. Skipped or deferred tasks: “Carried over” or move silently. No badge, no indicator. If the user asks: “Carried from [day].” Empty states:
ContextCopy
Tasks — all done”You’ve done enough for today.”
Tasks — no tasks yet”Nothing here yet. Add something small if you’d like.”
Orchard — empty”Your orchard is waiting. Add something you love.”
Mana pool at minimum”Today is a rest day. That is enough.”
No check-in data”Let’s see how you’re feeling before we figure out your day.”
Errors: Calm, one clear next step, no urgency. Never exclamation marks, never “Warning:”, never blame framing. Insights and patterns: Describe patterns factually without framing them as problems. “Thursday check-ins are often lower than the rest of the week.” Let the user interpret. Never frame observations as warnings. PEM / low state: No special message. Show the smaller list. Do not comment on check-in scores. Do not say “You’re having a rough day.” Do not say “Rest up.” Onboarding: Factual instructions. “Choose the tasks you did yesterday.” “Rate how hard each felt.” No hype. Never “Let’s get you set up!” or “You’re going to love this!“

11.4 Transparency Sentences

The sentences that explain the mana pool. Translate system state into accessible language:
  • Low confidence (< 0.3): “We’re still learning your patterns. Today’s mana is set carefully — it’s designed to feel comfortable, not like a stretch.”
  • Medium confidence (0.3–0.7): “On days you’ve felt like this recently, you’ve usually managed around [X] mana. Today is set a little below that to give you room.”
  • High confidence (> 0.7): “Based on your history, [X] mana is a good fit for how you’re feeling today.”
  • Post-PEM: “You had a tough stretch recently. Your mana is lower while you recover — it’ll grow back as you feel better.”
  • Post-overflow: “You’ve been doing more than your pool lately — we’ve nudged it up a bit.”
  • Returning after absence (7+ days, first 3 check-in days): “It’s been a little while — today’s mana is set gently while the app catches up.”
  • Quick check-in or skip used: “Your mana is estimated today — check in when you’re ready for a better reading.”
No percentages, no confidence scores, no coefficient values. The user sees the mana number and a human sentence.

11.5 Copy Review Checklist

Before shipping any new UI copy, check:
  • No banned phrases or variants
  • No urgency or alarm
  • No implied failure state for rest or low activity
  • No patronising affirmations
  • No commentary on absence or return
  • One clear next step if action is needed, or no action implied if none is needed
  • Consistent with the product contract anti-goals

12. Accessibility

12.1 Standards

  • WCAG 2.1 AA (all success criteria)
  • WCAG 2.2 AA (adds 2.5.8 Target Size minimum)
  • ADA 2024 (DOJ rule requires WCAG 2.1 AA)
  • European Accessibility Act 2025 / EN 301 549 v3.2.1

12.2 Key Requirements

Colour & Contrast: All pairings validated (see §2.6). text-tertiary on bg-base only. mana-400 and below for UI components only, never body text. mana-600 minimum for interactive text. Semantic colours always paired with a non-colour indicator. Motor & Touch: 48dp minimum touch targets throughout. 8dp minimum gap between adjacent targets. All gestures have tap alternatives. No time-limited interactions. No precision gestures (discrete taps replace sliders in check-in). Cognitive: No content auto-dismisses. All form fields have persistent visible labels. Error states explain the corrective action. Single action per screen where possible. The check-in is always bypassable — the tiered system (§7.1) ensures the user is never hard-locked from their task list. Screen Readers (Flutter Semantics): All interactive widgets wrapped in Semantics with meaningful labels. Mana orb clusters labelled (e.g. “3 mana cost”). Completion circles labelled (e.g. “Complete [task name]”). Live regions on mana number update and task completion. Bottom sheets announce heading on open. Multi-select announces count. Essential task flag announced: “Essential task: [task name]”. Text Scaling: All layouts tested at 200% text scale. No fixed-height containers that clip. Task cards expand vertically — names never truncate. Icon+label pairs in nav bar reflow to stacked if needed.

12.3 Acceptance Criteria for New Screens

Before a new screen ships:
  • Renders correctly at maximum system text size (no clipping, no overflow)
  • All interactive elements have semantic labels
  • Focus order is logical under screen reader navigation
  • State changes are announced
  • Reduced motion preference disables or replaces all animations
  • All text and UI elements meet WCAG AA contrast
  • All touch targets are ≥ 48×48dp

13. Data & Privacy

13.1 Architecture

The app uses four layers: UI (widgets, screens, navigation), Domain (mana logic, services), Data (local SQLite via Drift), and Platform (notifications). Domain has no outward dependencies — it defines interfaces that other layers implement. Local-first: The app is fully functional with no internet connection. SQLite (Drift) is the source of truth. Every feature works against the local store alone. No cross-device sync — user data stays on their device.

13.2 Storage

StoreContentsEncryptedWiped on Reset
SQLite (Drift)Tasks, check-ins, events, mana stateYes (SQLCipher)Yes
shared_preferencesSettings, feature flagsNoNo
Settings intentionally survive a data reset — notification preferences and accessibility settings are not health data.

13.3 Encryption

All SQLite data is encrypted at rest using SQLCipher. A 256-bit key is generated on first launch and stored in the platform keystore (iOS Keychain / Android Keystore). The key is never written to iCloud, Google Drive, or any cloud backup.

13.4 Delete All Data

Accessible from Settings. Wipes the SQLite database and encryption key atomically. Settings and feature flags survive. Calm, factual confirmation copy: “This will permanently delete all your data on this device. Your app settings will be kept. This cannot be undone.” Button: “Delete everything” — no exclamation marks, no “Are you sure?”, no blame framing.

14. What This System Does Not Do

  • No streaks. No consecutive day tracking of any kind.
  • No leaderboards or comparison. This is a private capacity tool.
  • No red mana states. Low mana = rest purple. Red = system errors only.
  • No task counts in headers. The list shows what is achievable, not the full backlog count.
  • No animations celebrating high-capacity days. High days are not achievements. They are just high days.
  • No internal numbers shown. Coefficient, confidence score, EWMA values, pool percentage — none of these are ever visible. The user sees the mana number and a human sentence.
  • No automatic recalibration prompts. The system adapts silently. Recalibration is a user-initiated option, never suggested.
  • No “you exceeded your pool” warning framing. Overflow is noted warmly, once per day, never as an alarm.
  • No “you should” language. Ever.
  • No hard lock-out. The user always has access to their task list, regardless of check-in status.
  • No absence penalty. Time away from the app does not decay the user’s data, patterns, or system trust. The app waits.
  • No commentary on absence. No “welcome back,” no “we missed you.” The app picks up where the user is.

Changelog — v2.3 → v2.4

Issue 1 — Tiered check-in (no hard lock): §6.1 rewritten from “gated entry point” to “primary entry point.” §6.2 navigation bar updated to remove locked state. §7.1 Mana screen now documents three alternative check-in paths (quick, momentum carry-forward, skip). §12 cognitive accessibility updated. Issue 2 — Absence handling: §11.2 added “Welcome back” and “We missed you” to banned phrases. §11.4 added returning-after-absence transparency sentence and quick-check-in/skip sentence. §14 added no absence penalty and no commentary on absence. Issue 3 — Terminology: All references to netMET and impliedNetMET throughout this document have been replaced with relativeCost and impliedRelativeCost. These values represent relative effort for this specific person, not absolute metabolic equivalents. The mana formula, pipeline, and personal library logic are unchanged — only the naming. §9.3 strengthened personal library override: after 10 completions, user patterns permanently override template-derived costs. §9.2 elevated difficulty rating to first detail field after name and duration. Issue 4 — PEM attribution: §7.6 PEM recovery banner now includes optional “Do you know what triggered this?” link for user-reported crash attribution. Issue 5 — Essential tasks: New §7.3.1 specifying the essential task flag, surfacing rules, over-pool display treatment, rest-day Essentials section, and essential count limit prompt. §7.3 visibility rule updated with the essential exception. §9.2 Quick Capture gains essential toggle. §11.3 added rest-day-with-essentials copy. §5.4 shield icon usage updated.
This document is the single design and copy source of truth for Canthus. When a new design or copy decision arises, return to the North Star and work forward.