The setup screen showed the secret and the otpauth URI as text and asked
you to scan — with nothing to scan. It renders the URI as a QR now, an SVG
(one dark path on a white card, so it reads in either theme) generated from
the barcode encoder already in the module graph via pquerna/otp. The secret
stays below it for a device that cannot scan.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
A save made while the connection blips for a few seconds is retried rather
than reverted: the request layer keeps trying a network failure for a
fifteen-second window, waking the instant the OS reports a link again, and
only falls back to the existing error path if the drop outlasts it. A quiet
"reconnecting" pill appears if the wait passes about a second, and leaves
the moment it heals — so a two-second blip is felt as nothing at all.
This is deliberately not offline mode: the app is a live view of a shared
list, so there is no cache to work in with no server and no write log to
reconcile. It is only the blip, ridden out. A server error (4xx/5xx) is the
server answering and is not retried; an aborted request (a superseded
search) is left to propagate.
Kristian: an offline function for when the net drops for short periods,
seconds. Shared items stay server-authoritative — nothing is edited against
a stale copy for longer than the blip.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The Wunjo rune sat left of centre and thin. It is heavier now (a 6.5
stroke), bigger, and nudged right of the geometric centre so the heavy
stave and the light flag balance about the middle of the tile — so it
reads clearly as a home-screen icon.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Each note is three lines now: the title, then the date and the excerpt,
then where the note is filed — a folder like the menu's groups and the
project's name, the owner's when it is someone else's, or simply "Noter"
when it belongs to no project. The date leads the second line, left
aligned, instead of being pushed to the right of the title. A faint
hairline separates one note from the next, and a month heading is
capitalised ("August 2026", not "august 2026").
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
It carried class="ghost", which nothing in the data page styles — so it
fell back to the browser's blue underline while every link beside it is
the accent-coloured .link. Now it matches them.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Same as the sidebar: the box folds on a click, the star and people icon
are the marks that mean something, and a date group keeps an empty spacer
so every label still starts at the same place.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The note list still wore the old faint-uppercase group header beside the
sidebar's bold plain-case one, so the two columns read as two apps. The
group headers are bold, plainly cased and in the reading ink now, at
menu size, and their separator boxes carry the same rounded corner as an
active menu item — the hard rule underneath is gone, the box is the
separation. The disclosure mark stays: unlike a sidebar section, a
time-group has no icon, so it is the only thing that says "this folds".
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The chevron beside every section and group was saying "clickable" a
second time next to an icon and a bold name that already said it. Gone
now: a system section folds from anywhere on its heading, and a group
folds from its folder icon while the name still opens the group's page.
No arrow on the rail.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The calendar was a grey grid where every event was the same sunken block
edged in a colour you had to already know. Now the day itself is the
brightest surface and each event is a soft, dusty wash of its own
calendar's colour — so a screen of them reads as colour laid on white,
and two calendars are told apart at a glance. Tasks stay outlined cards,
the thing you can pick up, against the solid washes you cannot.
Today is marked where the day is named: its number sits in a filled disc
at the top of the column, the same one the month grid gives it, over a
faint wash down the whole column.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The scrollbar thumb centred a 4px bar in a 10px track behind a
transparent border, so it floated three pixels shy of the right edge.
The thumb is the track now — a thin 6px rounded bar sitting flush
against the divider line, where a scrollbar belongs.
The group heading is a heading now, not a project row: the smoke test
measured a group against the projects filed under it and read the
section icon as a dot. It measures a group against "Projekter" — the
tier it shares — and reads the icon both headings carry.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
System sections (Projects, Filters, Labels) and user groups (Work,
Home) now share one design: a bold label at menu size, a leading
folder/funnel/tag/people icon, and an always-visible fold chevron.
Groups drop their colour dot for the same folder icon, so the sidebar
reads as one consistent hierarchy instead of two visual languages.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
It sat a pad-width inside the right edge because the scroller lives inside the
sidebar's padding, so it read as floating in the middle. Pull the scroller out
to the border and pad the content back — the rows do not move — and make the
bar thin and dim so it is present without drawing the eye.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
A native HTML5 drag occasionally does not register under CI load, leaving
the group empty and the group-page assertion failing for a reason unrelated
to the test. Retry the drop until the project actually sits under the group.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Following the Things pass, four bits of polish:
- The fixed views carry their own colour — amber star for Today, blue tray
for the Inbox, red Upcoming, violet Waiting on others, teal Notes, indigo
Calendar — and keep it whether or not they are the active row.
- The active row was all but invisible on the dark sidebar (a half-step of
surface); it is now an accent-tinted selection that reads in both themes.
- The Projekter heading — the only place to add a project or a group — no
longer scrolls away with a long list; it is pinned to the top of the
scroller.
- The note list and the editor lift off the page: white in light, a nuance
lighter than the ground in dark, so the two read as one writing surface.
Screenshots regenerated.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The sidebar redesign puts every project at the same left edge; flip the
assertion from "indented more than a fixed view" to "in line with it".
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Toward Things' calm: the fixed views carry icons instead of dots — a star
for Today, a calendar for Upcoming, a person for Waiting on others, a tray
for the Inbox. Areas (the user's groups) are set in bold, plainly cased, so
the eye lands on them the way it lands on an area in Things; the system
sections (Projekter, Filtre, Etiketter) stay quiet. And projects sit at the
same left margin whether or not they are in an area — one straight edge down
the sidebar rather than a staircase, with the bold heading doing the
grouping the indent used to.
Screenshots regenerated to match.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The sidebar read as muted 13px; the menu items now use their own size at
medium weight so they carry at a glance (Todoist-ish). Both sizes are
choices under Settings → Appearance:
- Menu font size drives a dedicated --menu-size the sidebar uses.
- Body text size re-scales the shared type tokens (the list and the notes),
the same mechanism a look uses.
The two are independent on purpose — one is a glance down a list of names,
the other a paragraph you read. Kept in localStorage like theme and look,
and applied in app.html before first paint so a chosen size does not flash
in and resize. Four steps each (Small/Default/Large/Largest); Default
carries no attribute so the base tokens stand.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Andreas signed up as "andreas" and was shown that way everywhere. A name
is now capitalised on the way in — the first letter of each word raised,
the rest left as typed — in CreateUser (signup and invite-accept) and
UpdateProfile, so display, mail and export all agree.
Existing accounts are fixed by an idempotent startup pass
(NormalizeUserNames), the same shape as SealNotes: the rule is Unicode-aware
and per word, which SQLite's UPPER cannot spell, so it lives in Go rather
than a migration.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The first cut put an open-button overlay over the row, which intercepted
every click on the title text — nine smoke tests (and real users) open a
task by clicking its text, and the overlay stole those clicks. Make the
body a role=button instead, with each link stopping its own click from
bubbling: plain text opens the task, a link opens the page.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
A task is plain text — the title is an input, the description a textarea —
so a pasted URL just sat there as words. It is now caught at display time
and shown as a link in the list and on the board, without the stored text
ever being anything but plain text.
The link cannot live inside the row's open-button (an <a> in a <button> is
invalid), so the body is a container with the open action as an overlay
behind it: plain text and the meta row still open the task, links are
raised above and take their own click. Conservative about what counts —
an explicit http(s):// or a bare www. host, not every dotted word.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
A donate link belongs in Settings and nowhere in the way — so it sits last,
understated, below the device list. A plain anchor with an inline SVG cup:
no third-party script, no webfont, no tracking, so it works offline and
cannot phone home. Wording says the app is MIT with nothing held back and
that nothing changes if you don't pay.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Yggdrasil is self-hosting too, so labelling only the Docker page
"Self-hosting" was misleading and put it above the Rune it was built for.
Reorder "As a Rune" above the Docker page, rename that page "With Docker",
and make the landing hero's primary call to action the Rune, with Docker
beside it.
Also drop the "the grammar is Todoist's" line from the filters page — the
factual import/export interoperability keeps naming Todoist, but the
positioning and soft comparisons do not.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claiming to be Todoist Pro is both inaccurate and an invitation to a
trademark complaint. Describe verdande on its own terms — a fast,
self-hosted task manager — and keep the Todoist references to what they
factually are: import/export interop, and a filter grammar close enough
that people coming from there already know it.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The landing page and the docs now show and describe what has landed since
the last site update:
- the delegated-task marker (an arrow to whoever has it) — visible now in
the board, list and Waiting-on-others shots
- snooze — one seeded task is parked so the board shows a card greyed at
the foot of its column
- Web Push reminders to iPhone and Mac, dated tasks in a subscribed
calendar, task durations on the calendar, and per-person note sharing
Screenshots regenerated against the current UI (PNG for docs/README, WebP
for the landing page, from the one capture). "Lately" brought current.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The assignee chip reads as a delegation now, so its title changed from
"Ansvarlig: {name}" to "Uddelegeret til {name}". Point the role-edit
smoke test at the new title.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
A task assigned to somebody who is not you is out of your hands and into
theirs, but the row only showed their name — the same weight as any
other meta. The assignee is now a bordered chip led by an outgoing arrow
in the accent colour, so a list reads at a glance as which tasks are
yours to do and which you are waiting on. Covers the board too: its
cards render a TaskRow.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
On a phone the detail drawer's field grid stayed two columns, so each
field got half the viewport. Prioritet collapsed to "Ing" and the due
row — a date input plus fixed-width time and duration fields — ran off
the right edge. Below 560px the grid now stacks to one column per field
and the due row wraps.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Snooze puts a task out of the way without finishing it or filing it: it sinks to
the bottom of its list and greys, and comes back on its own when its time passes.
No job wakes it — "snoozed" is just snoozed_until being still in the future, read
against the clock each time the list is ordered.
- `snoozed_until` on tasks (migration 0031); the list order sinks a still-snoozed
task below everything, and it rejoins its place the moment the time passes.
- POST /tasks/{id}/snooze {until} — an RFC3339 time to snooze to, or empty to wake.
Nothing else about the task moves; a snooze is about when you want to see it, not
when it is due.
- The task drawer gains quick picks (this evening / tomorrow / next week) and a
custom time, and a Wake now once it is snoozed. The row dims and carries a
"snoozed until X" mark, and the list keeps snoozed tasks at the foot — the client
sorts the same way the server does, so a drag-sorted list does not jump on reload.
Tests: snooze sinks a task below one made after it and waking returns it (Go); and
from the drawer the row greys, shows the mark, and un-greys on wake (e2e). Full
suites green.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The calendar feed emitted every task as a VTODO and, on top of that, an event only
for tasks that carried a clock time. But a subscribed calendar in Apple Calendar or
Google ignores VTODO entirely and draws only events — so a task with just a due
date, which is most of them, appeared in the verdande app's own calendar and
nowhere in the calendar it had been subscribed into. "Verdande does not update in my
calendar, only in the verdande app."
Every dated, unfinished task is an event now: a clock time makes a timed event as
before, a bare date an all-day one (a DATE start and an exclusive next-day end, so
it stays on its own day). Finished tasks stay off the calendar, as they were.
Test updated: the sample's timed task and its two date-only tasks all become events
now, the all-day ones in the DATE form, and the finished one still makes none.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>