feat(projects): section headings you can count at a glance, and an Inbox that speaks the language

Two from use.

Section headings were small uppercase text over a hairline — a heading you have to
look for. A project with four sections is four groups, and the eye should be able
to count them without reading a word, so the heading gets a ground of its own and
the rows sit against the page. `--surface` rather than a tint of the accent: the
colour on that page belongs to the project, and a section is not a second thing to
colour. A step in lightness separates them in all five themes without anybody
measuring anything.

And the Inbox. The server names it at account creation, before anybody has seen a
settings page, so it is the one project name nobody chose — and an account made in
Danish went on saying "Indbakke" inside an English interface, which reads as a
string somebody forgot to translate. It was. `projectName()` translates it while it
still carries the name the server gave it; rename it and that is your name for it,
in every language, like any other project. The rename field keeps the raw name, or
editing a translated label would save the translation.

The screenshot set gains the list view, which is where sections read as bands
rather than as columns — and the shape most people actually work in.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Kristian Wind
2026-08-18 12:02:56 +02:00
co-authored by Claude Opus 5
parent fe52818ab6
commit 19aa02e80c
32 changed files with 70 additions and 15 deletions
+22
View File
@@ -620,6 +620,28 @@ class AppState {
}
}
/**
* What to call a project on screen.
*
* Almost always its own name — somebody wrote it and it is theirs. The Inbox is the
* exception: the server names it at account creation, before anybody has seen a
* settings page, so it is the one project name nobody chose. Leaving it as stored
* meant an account created in Danish said "Indbakke" in an English interface, which
* reads as a string somebody forgot to translate. It was.
*
* Only while it still carries a name the server gave it. Rename it and that is your
* name for it, in every language — the same rule as any other project.
*/
const SYSTEM_INBOX_NAMES = new Set(['indbakke', 'inbox']);
export function projectName(project) {
if (!project) return '';
if (project.is_inbox && SYSTEM_INBOX_NAMES.has(project.name.trim().toLowerCase())) {
return t('nav.inbox');
}
return project.name;
}
/** Enough of a task's title to recognise it, without a toast the width of the page. */
function truncate(text, max = 40) {
const trimmed = text.trim();