A phone without a camera whose authenticator doesn't open otpauth: had no
way but typing the key. It is copied again, the key alone (ADR 0017
amended, the developer's decision of 3 Nov 2026): on Android through each
app's SensitiveClipboard.kt, marked EXTRA_IS_SENSITIVE, so Gboard and the
system show no preview and keep it out of their histories; elsewhere through
Flutter's clipboard. Emptied 60 seconds later if the clipboard still holds
it. The recovery phrase and codes stay never copied.
The code's field counted "/7", taking an optional space for a seventh
character: it now takes six digits alone, a pasted space dropped, and counts
nothing.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
The developer's request of 3 Nov 2026: a dream journal, sealed and
synced as the sittings, with Today's morning card and its switch in
Settings. What an entry holds beyond the request, its own `dream`
table, the fourth tab between Explore and Profile and why, the
Journal's list, search and filters, the editor and Profile's two
figures are the agent's recommendations, to be confirmed. The `dreams`
migration's SQL is explained under Migrations; it is step 5, the
release moving to step 6.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
Proposed by the agent on 3 Nov 2026, the developer having asked to go on
without their interjection: three tabs (Today, Explore, Profile) on
Todo's and Train's frame, fern washes, Halkyon's own practices as text
cues with a silent timer, bells synthesised for the app, a sitting over
the tabs, sealed and synced settings and sittings, the figures worked
out on the device, development ports of its own. Every decision is the
agent's recommendation, to be confirmed.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
planReminders plans each reminder at a time of its own of an open task,
whatever its date, under an ID of its own; the notification says
"Reminder" for a task without a time. The task's sheet always has its
reminders' row: those before its time where it has one, those at a time
of their own each with its remove button and "Remind at a time" (a day,
then a time), the permission asked as a first one is chosen. The date
sheet sets a duration once there is a time (none, 15 minutes to 4
hours, as Todoist's), a time cleared taking it with it. Recorded as
ADR 0033, D18 (the developer's, 3 Nov 2026).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
Built as Todo's in a clone of its own, from apps/train/snap/, for train.halkyon.eu; its
listing says the desktop shows, plans and keeps the statistics, and records nothing.
The snap tests now hold every snap built in a clone of its own.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
Each icon now ends in the colour its app's screens wash down from: Learn cobalt into
purple, Todo through violet into strawberry (Learn's former gradient), Train unchanged
into carrot, Meditate's to come through pacific into fern (Todo's former). Train's glyph
is Lucide's dumbbell, Meditate's will be the sprout.
Learn shows its graduation cap atop the rail, on the launch screen and on halkyon_app's
screens, as Todo and Train show theirs; the kingfisher leaves the app and stays the
F-Droid repository's icon.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
The certificate of the key Todo's releases are signed with (alias
halkyon-todo), made in memory and kept in Proton Pass alone; the release
tool releases no APK signed otherwise.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
deploy/compose.todo.yaml adds Todo's server at todo.halkyon.eu, a member
of Learn's register, its database halkyon_todo in the instance's
PostgreSQL, its image built as Train's. redeploy.sh and backup.sh go over
every app server .env switches on (train, todo). Each compose file names
its server to the register in a variable of its own
(INSTANCE_MEMBER_TRAIN, INSTANCE_MEMBER_TODO), which halkyon_base adds to
INSTANCE_MEMBERS, each address once, as a second compose file's default
would have replaced Train's.
apps/todo/release.dart configures the release tool for Todo's APK and
snap: a key of its own (pinned once made; until then nothing is
released), the F-Droid listing (Time, NonFreeNet), and the snap from
apps/todo/snap/, which the tool builds in a clone of the repository at the
tag with that folder in place of snap/, as snapcraft builds one recipe a
folder and the root's is Learn's. What's new for 0.1.0 in English and
German, now shown. Android's backup and transfer are off, as Train's
(D53): the reminders scheduled keep their tasks' titles unsealed.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
Settings' Moving more, on Android: a reminder to get up after an idle
time, and a suggested walk or run, each off until turned on (then every
30 minutes, weekdays 9:00 to 18:00, not 12:00 to 13:00, each value the
person's), turning on asking for the activity and notification
permissions.
A WorkManager job every 15 minutes reads the phone's step counter and
keeps two hours of readings. It reminds where fewer than 50 steps came
over the idle time, all of it within the hours and outside the break,
on the person's days, never while Train records or the phone is in a
car (Android's car mode, or a car's Bluetooth audio or hands-free). It
suggests a walk or a run where the last span averaged a walking or
running cadence, once an hour; tapped, the Record sheet for it opens.
The decisions are pure Kotlin (Movement.kt), tested on the JVM; the
notifications' words are the app's, written into the job's
configuration as the person's app opens.
Polar's SDK sets neither the band's inactivity alert nor tells of one
without an all-day connection, hence the phone's steps (ADR 0037).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
A workout with a track gets the weather over it as its page opens, once
while it has none: the hours from the one it started in to the one it
ended in, kept in its sealed payload (temperature, feels-like, humidity,
precipitation, the WMO code, the wind, its gusts and direction) and shown
under its totals with the link to Open-Meteo its licence asks for.
Train's server asks Open-Meteo in the person's place (the `weather`
endpoint), so Open-Meteo never sees their address: the place rounded to
two decimals (also on the phone), a span of at most 48 hours, the
forecast API for recent spans and the archive for older ones, for people
signed in, at most 30 requests a person a minute, nothing kept or
logged. On by default; `WEATHER=off` switches it off, and
`OPEN_METEO_API_KEY` moves it to the paid hosts for an instance used
commercially.
Health Connect's fingerprint leaves the weather out, so keeping it
writes nothing again. No table and no migration.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
Strength plans of exercises from a catalogue or the person's own, in
blocks of one exercise or several done in turn (supersets, circuits),
each with its sets, reps or seconds, weights and rests; each a sealed
`strength_plan` row. Plans are marked with what the place chosen lacks,
and a session offers swaps moving the same way that the place allows.
A session runs on every device, set by set with the rest counted down,
each weight made up from the place's plates, bars and fixed weights with
the plate changes between sets, kept in strength_session.json after each
change so one cut off is carried on, and saved as a workout of the new
activity Strength with its sets, listed on its page; strength training
in Health Connect and FIT, no GPX.
Migration 20261102113104496-strength-plans is purely additive: it
creates the table strength_plan (id uuid v7, spaceId, keyId, the sealed
payload and its nonce), its index on spaceId, and a foreign key to
offline_sync_spaces with ON DELETE CASCADE, so deleting a person's sync
spaces deletes their plans; then the modules' version rows. The
gen_random_uuid_v7 function is created or replaced as in every
migration.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
The places a person trains at (home, a gym), each a sealed, synced
`training_place` row with its equipment: bars and handles with their own
weight, plates by weight and count, dumbbells and kettlebells, the rest
by count, the person's own by name. A new place starts from what a home
or a gym usually has. The place last chosen is remembered on the device,
never its location.
The plate calculator loads each weight both sides alike, the heaviest
load not above it with the fewest plates, heavier inside, and over a
series of sets picks the loads making the fewest plate moves, listing
what comes off and goes on. Equipment is in Settings; strength plans
are to build on it.
The migration only creates the table, its space index and its cascade
to the sync engine's spaces.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
The public profile was already one per person for every service of an
instance (the register, ADR 0016); its app side was Learn's alone. It
moves into halkyon_app: the model, the repository on the module's
endpoints, the form, the avatar drawn on the device and the sheet with
someone's profile. They take the Public prefix (PublicProfileRepository,
BasePublicProfileGateway), as Train's own ProfileRepository holds the
body's figures. AppDependencies gains profiles and files, the picker the
avatar is chosen with, which moves out of Learn too.
HalkyonProfile is every app's Profile screen: the person's own tab first,
the same in every app (the account and the ways they sign in, the app's
own cards, then the public profile), then the app's own tabs, folding into
the title. Learn adds its inbox and Statistics. Train adds Progress, Days
and, where nothing records, Plans, and so opens on the person's tab, no
longer on Progress. Todo, which has no Profile tab, opens it from a row at
the top of Browse, where Todoist keeps the account.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
The question's text stands above its buttons: + attaching files, who
answers as a chip (Effort now a submenu of it), the conversations kept,
and the microphone while nothing is written, which gives way to the
button sending. What goes along is one row above the text, opening a
sheet with how far the assistant looks and the parts to send. A
conversation's follow-up has the same + and microphone.
Files are read on the device: an image goes as itself to an assistant
that reads images, a PDF as its pages' text, a text file as its text,
each cut at 20,000 characters and labelled by its name after the
question.
Voice is the device's own speech recognition (speech_to_text: Android,
Apple, Windows; none on Linux), in the app's language, the microphone
asked for once tapped. The privacy page says that Android's recogniser
may send the sound to Google or the phone's maker.
The field's Check goes, with its LanguageTool sheet (amending ADR 0024);
the editors' underlining and Why? stay.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
- Explore filters by what a studyset's licence lets a learner do: adapt
it (no NoDerivatives) and use it commercially (no NonCommercial),
which the instance reads from the release's licence
(ExploreQuery.adaptable, commercial) and the app the same way
(LicenseUse). An instance from before ignores both.
- While the studysets are read, the Library shows shimmering skeletons
of their cards rather than a spinner: halkyon_ui's new Shimmer and
SkeletonBox, still where the system asks for no animations.
- The scope's "Include private studysets" is offered only while the
person has a private studyset.
- An agreement to what goes where is per provider (protocol and host):
agreeing to one assistant agrees to every assistant of that provider,
those granted later too, and the agreement sheet says so. No
migration: it is written on every grant of the provider, so taking
one back keeps it for the others, and read per provider from any of
them.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
- Home's assistant starts folded into its button at the lower left, as
in the Library, where a field stood at its foot.
- The button has Material 3's floating action button shape (a rounded
square) rather than a circle, its gradient ring kept.
- On a studyset below expanded windows it stands in one row with Add
material and Study rather than above them.
- While studying, the ratings below the card make way while its field
is open rather than standing under it.
- The conversation opens at the window's full height, its header above
the list, so a drag on the header moves the sheet and a drag on the
list scrolls it. Close ends the conversation; any other way out folds
it into the button (ConversationDockCubit, above the router), its
answer still coming, until any button opens it again or another
conversation starts.
- An answer's Copy icon lines up with the answer's text.
- A sense's grammar notes run on after its glosses as one flowing text,
so a short note such as "n" no longer takes a line of its own.
- A card's hints show their count in a grey badge beside the title, so
it no longer reads as the hint's number.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
An indoor row started showed its notification but not its screen: the
Record tab's card pushed the screen only after the service had started,
and gave up silently where the card was gone by then. Train's frame now
opens it as the recording's phase turns to recording; one found running
as the app opens leaves the tabs as they were. The notification tapped
opens the recording's screen, not merely the app (RecordingOpenings.kt).
A workout's page kept a SafeArea at its foot, whose inset under the
floating bar is the bar itself: its content stopped at the bar's top, a
plain band behind it. It runs on beneath the bar as the tabs do, and the
tabs' lists and a day's page end with the body's bottom padding rather
than a fixed 88 px, which left their last item under the bar.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
Apple's systems take actions from categories registered at start: one
for each length a snooze can be, its action in the language the app
starts in, not to the foreground, so that iOS snoozes in the plugin's
isolate with the app closed (AppDelegate registers the plugins for it).
Windows hands back only the button's arguments, which carry the
notification's ID and payload. macOS and Windows launch the app for an
action while it is closed, and the gateway snoozes what launched it as
it starts. Not yet tried on any of the three devices.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
From 720 pixels of the Calendar's own width on, a month grid in place
of the agenda: the month's weeks from the week's first day, the days
of the months beside it muted, each day with as many of its tasks as
fit and the rest counted, opening the day's tasks in a sheet; past
days with their overdue and done tasks. A task held and dropped on
another day moves there (moveTask), a day's free space tapped adds a
task on it, a line tapped opens its task.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
A block held and dragged moves its task to another of the three days
shown and another time, its top snapping to a quarter hour, the time it
would take shown under the pointer, its duration, recurrence and
reminders kept; dropped on a day's All day it loses its time and
duration. Either can be undone for a moment. A later time of a repeating
task doesn't move. DayDropArea's move is now moveTask, shared by both.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
Settings gains Todo's own groups, kept in the person's sealed settings
row on every device. Tasks: the weekday weeks start on (the language's
unless set), which the week strip, the date and repeat pickers and the
filters follow; and whether a recurring task done opens its sub-tasks
again (on at first). Reminders: an automatic reminder (none at first)
that TaskRepository writes into a task gaining a time without reminders
of its own, and how long a reminder is snoozed for (15 minutes at first).
Each reminder's notification has a Snooze action on Android and Linux:
the reminder comes back that much later under an ID of its own,
scheduled from what the notification carries, so on Android with the
app closed too (the plugin's ActionBroadcastReceiver declared); the plan
of the person's reminders leaves snoozed ones alone. iOS, macOS and
Windows get it later.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
A project's Display gains the Calendar layout: Upcoming's week strip
and agenda, now shared as DayAgenda, over the project's tasks it keeps,
with No date beside the month and Future occurrences, each repeating
task also on the days it will come back (calendarOf on Repeat.next),
muted, neither ticked off nor dragged.
Upcoming gets a Display of its own, the same sheet over another target
(DisplayTarget): Agenda or 3-day, done tasks, future occurrences,
sorting, the filters by deadline, priority and label, and in the grid
Colouring by priority, label or project. It is kept in the person's
settings, one sealed row under an ID keyed by the account in the new
synced table todo_settings (migration settings: the table, its index
on spaceId and its foreign key to the space, cascading on delete).
The 3-day grid shows today and the two days after, stepped or swiped
three at a time: tasks without a time all day, timed ones as blocks as
long as they last, overlapping ones side by side (layOutDay). A long
press on a half hour adds a task there for half an hour; Overdue opens
the overdue tasks with Reschedule.
The board's separator builder names its BuildContext, as the root's
analyzer plugin asks (never_discard_build_context).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
The Display's new Layout picks List or Board. The board has a column
for the tasks in no section, then one a section with its menu, each
task a card and each column ending with Add task, a last column adding
a section; grouped otherwise, a column a group. Narrower than a medium
width it pages one column at a time with dots below; from it on the
columns stand side by side. Cards drag within and between columns as
rows do (D16), every scrollable they are in scrolling at its edges.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
- A Display button beside a project's menu (the Inbox's too), a dot
on it while the project shows otherwise than at first, opens its
sheet: completed tasks, grouping (date, deadline, added date,
priority, label), sorting (name, date, deadline, added date,
priority), filters by date, deadline, priority and label, and
Reset all.
- The choices live in the project's sealed payload (ProjectView,
written only once set), so every device shows the project alike.
- Grouped, the groups stand in the sections' place under pinned
headings; rows are dragged only while sorted by hand by sections.
- Show done tasks moves from the menu into Display.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
- halkyon_ui's sheetShowsAsDialog says whether showAdaptiveSheet shows
a dialog here, for a sheet of its own that can't go through it.
- Learn's conversation, a half-height sheet dragged up, asks it: where
sheets are dialogs it is a dialog up to 720 wide and as tall as the
window, with no handle to drag.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
A row of Upcoming, overdue ones too, held and dropped on another day
moves there, its time, duration and recurrence kept; Moved to … offers
Undo. The tint over a day a drag hovers is laid beside the rows, not
around them, which paint on the Material beneath.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
Up to five projects or labels whose name, or a word of it, starts with
what follows the symbol show below the title; one tapped completes it.
None for a symbol inside a word (C#), nor once a name is typed whole.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
- A project's row, held, is dragged before or after another, or a
little to the right to become its sub-task, or onto a section's
heading; its sub-tasks go with it, and Order changed offers Undo
(TaskRepository.place). The list scrolls at its edges.
- The add button is dragged onto a project's list to add the task
between two rows, onto a day in Upcoming for that day, onto Today
for today; dropped back on its place, an ×, it gives up.
- Holding a row now drags it; a swipe to the right selects it.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
- A section's heading stays atop a project's list while its tasks
scroll beneath it (slivers, PinnedHeaderSliver).
- Upcoming's month unfolds in place beneath its strip, from its name
or its handle; a button beside the month goes back to today.
- Tasks are chosen together: a row swiped right or held, or Select
tasks in Today's, Upcoming's and a project's menu; a bar of date,
move, labels, priority and more (complete, duplicate, deadline,
delete) takes the navigation bar's place. A row swiped left asks
for its date.
- TaskRepository.move moves tasks with their sub-tasks.
- parseQuickAdd reads #project, @label (an unknown one made),
{deadline}, !!1 and p1 to p4, !30m, dates, times and recurrences
(tomorrow 9am, Mon 18:00, ev Tue 7pm, every 2 days, every weekday),
from a table of words per language: English, and German beside it.
- Each token is highlighted and shown on its chip; a tap keeps it as
text, and a chip picked takes it out of the title.
- Quick add shows its title alone at first, its chips once typing
starts, and the description and deadline behind its + (the
description also from the down arrow).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
- halkyon_ui: showAdaptiveSheet shows a dialog on Linux, macOS and Windows
at every width (bottom sheets stay on phones and tablets below expanded
windows), so Learn and Train follow; SheetScaffold takes a heading in
the title's place and may leave out its close button.
- Todo: the tabs are Inbox, Today, Upcoming, Browse, Today still opening;
`serverpod start` launches the app on Linux, as it has no web build.
- A task's sheet shows where the task is (its project, an icon once tasks
are above it, and the tasks above it, each opening what it names) and a
⋮ menu in place of its close button: when it was added (its UUID v7),
Duplicate with its sub-tasks, hiding its done sub-tasks (synced in its
payload), Close in the pane, Delete after asking. The description's icon
stays by its first line.
- A row names its project and section at the end of its date's line; every
menu entry has its icon.
- Learn: a studyset's path starts at the Library tab's icon, named by its
tooltip.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
A task with a time takes reminders, minutes before it, in its sealed
payload; each device plans the coming ones whenever the tasks change and
schedules them with the system through flutter_local_notifications
(Android, iOS, macOS, Windows; on Linux the running app shows them), at
the minute where Android allows exact alarms. Notifying is asked for
when a task first gets a reminder; signing out or switching person
cancels them. Upcoming gets its week strip: the month opening
Material's calendar, the weeks before and after, a dot under each day
with tasks; a day picked scrolls the agenda to it, and scrolling moves
the strip along. From expanded windows on, a task opens in a pane
beside the list rather than in a dialog. Search, from every tab's app
bar, finds projects by name and tasks by every word typed, in their
title, description or labels, whatever the case and accents, on the
device alone.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
A task's date may recur: every n days, weeks (on which weekdays),
months (on its day, or its nth or last weekday), years, from its date
or from when it is done, until a day or for n times. Done, it moves on
to the next day after both its date and today, its deadline as far, its
time kept, its done sub-tasks open again and when it was done kept in
its payload; undo writes all of it back. The date sheet offers the rules
that fit the task's day and a rule of the person's own; rows show a
recurring date with its own icon, the task sheet the rule in words.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
The tabs hold the person's tasks: Today what is overdue (Reschedule
moving it all to a day, times kept) and what is due today; Upcoming the
overdue ones and the next four weeks day by day; Inbox and each
project's screen from Browse the tasks above and in their sections, done
ones on asking; Browse the projects with their open counts and the
labels. A task's row shows its check in its priority's colour, its date
in the colour of how near it is, its deadline, its sub-tasks done and
its labels; quick add takes its title, date, priority, project, labels
and description and stays for the next; its sheet edits all of it, adds
sub-tasks and deletes it with them after asking. Colours are the
palette's, cerise for overdue and P1 against the strawberry wash.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
TodoPerson opens the person's own sync database in their folder,
halkyon_app's SyncService behind AppCompatibility, their key (TodoKeys,
Train's copied with Todo's own key IDs) and their projects, and closes
them in that order, the key last. A project is sealed for its row; a
readable, foreign or moved row shows locked, and a device without the
account's keys reads and writes nothing. The Inbox is the row under an
ID keyed by the account, so every device makes the same one and the
instance can't tell which it is; it can't be deleted. Settings shows
Sync's card first and the cog its dot while sync fails, as Learn's.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
halkyon_app's WhatsNew reads what each release changed from the app's
assets/whats_new/ (<version>.<language>.txt, English and German, a change
a line): after an update a sheet lists every release since the one the
device showed last, newest first, once; Settings shows the running
version's again, above About. Nothing on a fresh install.
tool/release.dart drafts the missing texts from the commits that count
after "Go on?" (German marked TRANSLATE:), opens them in the editor until
they fit (no mark left, F-Droid's 500 characters) and commits them with
the version. The English is the Forgejo notes' What's new, each language
F-Droid's changelog of the build, written at publishing and copied in by
tool/fdroid_repo.sh. Learn and Train bundle their texts, Learn's 0.22.0
and Train's 0.1.0 written to start.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
halkyon_ui's FoldingTabs: the tab row under the app bar's title at the
top, scrolling away with the content, the chosen tab's name then small
under the title, which, tapped, scrolls back up to the row, as Strava's.
Learn's Profile (Profile, Statistics) is built on it, and Train's
Profile in tabs: Progress (your body, the last 12 weeks, this year),
Days, and Plans where the device doesn't record.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
While the Loop gave figures for today, Home shows them above the week:
steps, active time, last night's sleep and Nightly Recharge, as Profile
lists a day, tapped opening the day's page. Shown above Home's message
too, before a first workout; the week waits for one.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
Above the days: a card with your body's weight and resting and maximal
heart rate, tapped opening Your body; the last 12 weeks' time trained as
bars, a week tapped showing its time, distance and workouts; and this
calendar year by activity. Home's week card reads its time as the days do.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
The Record tab shows a card per activity it records, the interval plans
below. A card's Start opens the Record sheet for that activity, which
keeps every other choice; the sheet no longer chooses the activity, and
so offers the plans and routes for it or for any. While a recording is
under way or waits to be saved, the cards wait, the bar leading back.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
A tunnel that fails to come up takes Jellyfin's internet with it, as
linuxserver/wireguard's client mode deletes the default route. Named by
learn.halkyon.eu, the endpoint needed DNS to come up, which the home end
starting or waking hasn't always got yet; by its address the tunnel comes
up whatever the network does. Closes ADR 0032's open point.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
linuxserver/wireguard's client mode deletes the default route when wg0.conf
fails to come up, so Jellyfin, in its namespace, loses TMDb and scans get
frames for posters. The README's step 4 says so and how to recover; ADR
0032 holds the ways out, open for the developer to decide.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
The instance's map with every route drawn, fitted to them all, a route
tapped opening its planner. On phones the map stands above the list;
from expanded windows on the two are panes side by side, as Material's
list-detail layout. Without a route to draw, the list alone.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
The week's time, distance and workouts above Home's list, and a strip of
its days, each as tall as the time trained on it, starting on the day the
person's language starts weeks on. Home's empty hint points to the Record
tab, where its button had gone.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
halkyon_ui's NavigationFrame takes a status, standing above the floating
bar below medium windows and at the foot of the screen's panel from there
on. Train's RecordingBar fills it while a recording runs or waits to be
saved: its activity, moving time and distance, paused or stopped, a tap
back to it. Saving now opens the workout's page in Home's tab.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
As Learn's: a cog atop Home and Profile, with the count of accounts
waiting for whoever operates the instance, opens Settings over the tabs,
where an account sheet had held the account and the training's screens.
Grouped in cards: the operator's card, the training (your body, Health
Connect, the Polar Loop, music, those the device has), the account near
the foot, About Halkyon Train last, and the version small at the very
bottom.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
Train's tabs are Strava's five where one screen with four tabs at its
top had held workouts, days, plans and routes: Home the workouts, Maps
the routes, Record recording and the interval plans, Groups a screen
saying they come later, Profile the days and the way to the account.
A device that doesn't record has no Record tab, its plans beside the
days in Profile.
The frame is halkyon_ui's NavigationFrame, driven by go_router as
Learn's: a workout's page opens in Home and a day's in Profile with the
tabs beside them; the route and plan editors and the recording cover
them, their content handed over as it is. Every tab washes down from the
top in carrot, the warm end of Train's icon, as Learn's in cobalt.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>