The developer decided on 8 Nov 2026, after trying the variants on the
phone: the wave in the colour of the screen in view, without Material's
ripple, the indicator kept and there at once, a 1.2 s wave, top corners
of 20 dp, the bar's own neutral surface. Learn's bar stays cobalt, the
colour its tabs wash in, rather than its icon's purple.
So the bar has one look: FlushNavigationBar.waveDuration and
cornerRadius are constants, and the debug section goes from the four
Settings screens with what it switched (NavigationBarDebugSection,
debugNavigationBarStyle, effectiveNavigationBarStyle, the style record
and the variants A, C and F, the speeds, the corners and the tinted
surface). Their tests go too; those stating the look kept stay. Learn's
sign-out helper no longer has to scroll past the section.
ADR 0030's amendment of D60, the halkyon_ui README and Learn's
AGENTS.md record the decision and the alternatives set aside.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
The developer's review of 8 Nov 2026: the bar follows the screen in view
rather than one colour per app, so a Todo project of its own colour gives
the bar that colour while it shows. The wave, the chosen destination's
icon and label and its indicator take ScreenTint.color, the colour the
screen in view claims through its TopGradient; the frame's accent, the
app's colour, stays only for the moment before any screen claims one,
since ScreenTint itself starts at cobalt, which would be wrong for Todo,
Train and Meditate. Learn's tabs claim cobalt, their wash, so its bar is
cobalt there now, not purple.
A colour changing on the same tab (a project opening) passes into the
next over 300 ms, at once with animations off. A wave paints in that
colour as it goes: it starts in the colour of the screen being left, as
the arriving one claims its own only once it shows, a frame later, and
passes into it with the rest of the bar.
A person's colours may be light, so the chosen destination's colour is
made legible (readableTone, halkyon_ui): a palette colour starts from its
own text tone as Todo's dates take it (its outline in light mode, its
fill in dark), any other colour from itself, then darkens towards black
in light mode and lightens towards white in dark, only until it reads at
4.5:1 on the bar and on its indicator. Every palette colour is tested in
both themes, on the neutral and the tinted surface. This also lifts
Learn's label, which read at about 3:1.
The debug section gains Bar surface, neutral or tinted: tinted mixes 6 %
of the screen's colour into the bar's own surface in light mode and 8 %
in dark, changing with it. Neutral by default, and in the shipping style.
Whats-New: The navigation bar takes the colour of the screen you're on, such as a project's own.
Whats-New-De: Die Navigationsleiste nimmt die Farbe des Bildschirms an, auf dem du bist, etwa die eines Projekts.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
Every account signs in with SimpleLogin or a password now, so GitHub
goes from the module, the shared app package, Learn and Todo, ahead of
ADR 0017's GITHUB_SIGN_IN_ENDS.
- halkyon_base: no `gitHubSignIn` endpoint, GitHub identity provider or
GitHub refusals; no `githubClientId`/`githubClientSecret`, no
`GITHUB_SIGN_IN_ENDS` and no `forgetGitHubAccounts`; the register
loses `account-with-github`. `SignInWays.gitHub`, the basics'
`gitHubClientId` and `gitHubSignInEnds`, and `PasswordRefusal`'s
`signInAgain` and `noAddress` go. A first password takes a code
mailed to the person's own address; an account without one sets none
(`wrongCredentials`).
- Learn's server: `instance.info()` without `gitHubClientId`, the
pruning without GitHub, and `minimumAppBuild` 24, as builds up to 23
(v0.20.0) require `SignInWays.gitHub`: the server deploys with the
release of build 24.
- halkyon_app: no GitHub button or problems on the start screen, no
password offered after a GitHub sign-in, and `ServerpodAuthGateway`
without the browser half only GitHub used (`(client, base:)`). The
account section offers a first password only to an account with an
address. `LoopbackWebAuth` and the apps' schemes stay, SimpleLogin's
ways back.
- Learn's Profile lists no GitHub; the texts go (English, German).
- Serverpod's `serverpod_auth_idp_github_account` stays, as its
migrations make it; a row goes with its account, and ADR 0020's D36
gives operators the SQL to delete those left.
- deploy/: compose.yaml and .env.example without GitHub. The READMEs,
AGENTS.md files and ADR 0017 amended.
BREAKING CHANGE: builds up to 23 can't read the instance's answers
about an account's ways in; minimumAppBuild is 24.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
Every new account gets a handle, and an account without one gets its
first as it sets a password. The handle is private until its person
goes public (D5).
- `passwordSignIn.signUp` takes a handle. `passwordSignIn.checkHandle`
says whether a sign-up could take one, only while that sign-up's
mailed code waits (`codeExpired` otherwise), counted per code request
(30 an hour) and per network (60) (D29). Members ask the register.
- `password.set` takes the first handle of an account without one
(D28); `SignInWays.handle` tells the app whether there is one.
- Each checks the handle before the code is used, so a refusal leaves
the code for another try. An existing account at the address keeps
its own handle where it has one, and the typed handle is still
checked, so the answer says nothing about the address.
- `first_handle.dart` holds what SimpleLogin, the keys and passwords
share: `refusalOfNewHandle`, `insertFirstProfile`, `hasHandle`.
- halkyon_app: one `HandleField` with its `HandleCheckCubit` (asked
300 ms after typing pauses, only about the handle typed last; the
instance's suggestion is free without asking) (D30). The password
setup asks for the handle between the phrase check and the code, and
a refusal at the code sends back to it. SimpleLogin's sign-up and
keys steps use the same field and now check as it is typed.
- The module's README and ADR 0020 (D29, D30, the built state) amended.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
Every account has a way in, so the apps make no anonymous account any
more. The start screen shows whenever nobody is signed in, a first
start included, and offers SimpleLogin, a password and GitHub for those
who have it, with no start without an account. An instance out of reach
is said so, with Try again, and one offering no way to create an account
too. An anonymous account's session left from before is deleted as the
app starts (D25), falling back to signing out on the device.
What only anonymous accounts needed goes: signing in anonymously, the
signed-out mark, adding GitHub to an account and switching to a GitHub
account from the Profile tab (with its Cancel, the only one), an
anonymous device's own keys, the warning that signing out deletes the
account, and the texts about keeping progress. Settings says on which
instance the account is signed in. Learn's publishing, reports and
suggestions and its learner count no longer ask whether the person has
an identity: everyone signed in has one.
The server still offers anonymous sign-in until the next commit, so
older apps keep working until v0.20.0 raises the minimum build.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
halkyon_app reads where the device's person stands with SimpleLogin
(nothing to show, linked, or missing) and shows it in SimpleLoginSection,
which each app places above the password part: Add SimpleLogin, once
added one more way in. GitHub is added to nobody where SimpleLogin is
offered, and Learn's Profile offers an anonymous person SimpleLogin
alone there (D23).
No cut-off day, reminder or banner (D24): with the developer the only
person on learn.halkyon.eu, the cut-off is the operator taking GitHub's
OAuth app out of the deploy's settings once that account has SimpleLogin.
ADR 0020 records it and drops step 5.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
Someone identified was offered Add GitHub wherever GitHub signed people in,
and on an instance offering passwords the browser round trip ended in
"Couldn't sign in with GitHub.", as the instance adds GitHub to nobody there
(ADR 0017, D2; the end-to-end test of 21 Oct). The profile now shows the
GitHub row there only to whom it signs in already, and an anonymous
person's Sign in with GitHub, which still reaches the account someone has,
says why it didn't: a GitHub account nobody has, with the password beneath
in its place, or one that signs in with its password now.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
Where an instance offers password sign-in, GitHub is added to nobody (ADR
0017, D2), yet the start screen still said "then add GitHub" after a GitHub
account nobody has, and every refusal but an unknown account read
"Couldn't sign in with GitHub." (the end-to-end test of 21 Oct).
- The gateway tells from one read of the basics whether GitHub signs in and
whether it is added to people (`gitHubOffer`, in place of
`gitHubClientId`); the GitHub bloc keeps it (`Ready.linking`) for the
profile, with why an attempt failed (`Ready.problem`).
- The instance's `usePassword`, `deprecated` and `ended` become problems of
their own (`gitHubSignInProblemOf`), worded by `gitHubProblemText` and on
the start screen; an anonymous person refused a link is told the GitHub
account is nobody's and offered the password instead.
- Where passwords are offered, the start screen offers an account to create
in place of the app's hint on adding GitHub.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
The text for an account that signs in with GitHub alone now names the
deletion 30 days after GitHub's end (f7a3251); Learn's test of its
profile looked for the words before.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
The full reading's M1 and L6: once GitHub IDs were forgotten at
GITHUB_SIGN_IN_ENDS, an account that had signed in with GitHub alone
counted as anonymous, so a stolen session and any mailbox gave it a first
password and authenticator; and such accounts, with no way in left, were
never pruned. Now:
- at the end, the daily run that forgets the GitHub IDs first deletes the
accounts that sign in with GitHub alone (no address, so never a
password), with everything they have, members told (deletePerson); the
app tells them for the three months before that their account goes then
unless they set up a password (passwordSectionGitHubEndsDeletes, en/de);
- password.set adds an address without GitHub only for someone anonymous
where the session lives (anonymousHere, which a member tells the
register, as it tells freshGitHubSignIn); anyone else is refused before
any code is used.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
The fourth reading's first finding: password.set took a session alone,
so whoever took one made a GitHub-only account, or an address account
without a password, theirs for good (their address or password, their
authenticator; GitHub then refused the owner).
- An account with an address proves it anew: a code mailed to that
address for this (EmailCodePurpose.firstPassword, its own mail), never
the session alone, a code asked for anything else, or another address.
- An account that signs in with GitHub alone does it within 10 minutes of
a GitHub sign-in (the session's method and creation time, where the
session lives; members tell the register), refused signInAgain before
any code is used; the address it adds is proved as before.
- Anonymous people still become identified with a code to the address
they add.
The app mails the code to the person's own address (asking for it where
the device doesn't know it), offers a password right after a GitHub
sign-in (D2's "at their next sign-in") before the person's app, and asks
for a GitHub sign-in anew when the instance refuses an older one, keeping
the code typed.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
ADR 0017, step 3 (D4: nobody signs in with email codes yet, so the
password replaces them outright). `emailCode.verifyCode`,
`emailSignIn.signIn` and the switch token go, with the register's
`verifySignInCode` and `completeEmailSwitch` and their operations
between services. `emailCode.sendCode` stays, now without a session
(signing up and getting back in have none), as what proves an address
for a password's setup, a sign-up, a setup never finished and the
resets; `accountRecovery.sendCode`, which did that for the resets,
goes. The `switchChallengeId` column stays: Serverpod's challenges
still link a completion token, and older servers read it during a
deploy.
The apps: halkyon_app's email sign-in (its bloc, sheet, gateway calls
and the start screen's Continue with email) goes; Learn's profile and
Todo's account sheet show `AccountSecuritySection` (a password set up
by someone anonymous or signing in with GitHub, whose end it names;
the authenticators; changing the password; new recovery codes and
phrase), which reads anew after every change the repository makes.
BREAKING CHANGE: Learn's `minimumAppBuild` is 22: builds up to 21 sign
in with the endpoints that went. Todo was never released and stays at
build 1.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
The start screen's sentence after a GitHub account nobody here signs in
with named Learn's Profile screen. The package now says only that no
account signs in with it; the app's frame adds the rest as a sentence
of its own (thenAddGitHub), since the place takes its language's
grammar ("im Profil"). Learn's reads as before, which a test now pins.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
Its server, client, app and curator, and the tools that write its
assets (maps, Anki fixtures, icons), as they are; paths are fixed in
the commits that follow.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>