aboutsummaryrefslogtreecommitdiffstats
path: root/docs/superpowers/specs
diff options
context:
space:
mode:
authorDanilo M. <danix@danix.xyz>2026-08-09 12:43:58 +0200
committerDanilo M. <danix@danix.xyz>2026-08-09 12:43:58 +0200
commit23d07f07562adbb349f7fe8b97e4f4e9ea6c6ebd (patch)
treebd160e61cbd78f96c1a06e73754ec945d3d4ae59 /docs/superpowers/specs
parentd990f7c6775b4b921c6d6d8d539c7018279346be (diff)
downloadqtmaildir-23d07f07562adbb349f7fe8b97e4f4e9ea6c6ebd.tar.gz
qtmaildir-23d07f07562adbb349f7fe8b97e4f4e9ea6c6ebd.zip
docs: make the account colour the card's accent, not a chip
The plan left the account chip unspecified, because where it sits on a card was never decided and inventing a place would have been a guess. The user's answer replaces it rather than placing it: a coloured bar down the card's left edge, the reply spines inheriting that colour, and matching swatches in the account dropdown. It is a net simplification. The chip ate a third of line 2 on every card to repeat a name the user already knows, which is the table-of-records texture item 53 is about; the bar says the same thing in a few pixels and leaves line 2 to the subject. Three details that are easy to get wrong and are specified rather than left to the implementer: - The raw account colour is never drawn as a line. It is chosen to be a chip's FILL, with text drawn on top in whatever stays legible against it. A thin line on the pane's own background has a different job: followable down a long expansion without competing with the senders beside it. The accent blends toward QPalette::Base by the same 0.35 weight threadLineColour() already uses, keeping the hue and dropping the shout. The dropdown swatch does use the raw colour, being a filled patch rather than a line. - A reply resolves its THREAD's colour by walking to the root. AccountColourRole is empty on a message row, so a spine reading its own index would fall back to the neutral line under an accented root and break the continuous edge the design is built on. - Reply cards carry no bar of their own. Two vertical lines a few pixels apart in one gutter is what option B looked like, and the spine already carries the accent. colourFor() never failing is kept deliberately: an account with no colour= key gets a stable colour derived from its tag name, so adding an account and forgetting to colour it degrades to something usable rather than to nothing. kAccentWidth ships at 3px as a starting value. Whether five accounts are tellable apart at that width, on this user's screen and theme, is not decidable from a mockup or a test, so Task 10 gains a step that settles it against real cards, in both themes, with the guidance to widen the bar before touching the user's own colour choices.
Diffstat (limited to 'docs/superpowers/specs')
-rw-r--r--docs/superpowers/specs/2026-08-09-card-list-design.md54
1 files changed, 51 insertions, 3 deletions
diff --git a/docs/superpowers/specs/2026-08-09-card-list-design.md b/docs/superpowers/specs/2026-08-09-card-list-design.md
index f231577..de13132 100644
--- a/docs/superpowers/specs/2026-08-09-card-list-design.md
+++ b/docs/superpowers/specs/2026-08-09-card-list-design.md
@@ -73,10 +73,56 @@ same places and lights up exactly where the user put a tag deliberately.
Computed in the model from data it already holds: `MessageNode::tags` against
the parent `ThreadSummary::tags`. **No worker change.**
+## The account accent
+
+**A thread card carries a vertical bar of its account's colour down its left
+edge.** A few pixels wide; the exact width is a judgement to make against real
+cards on the user's own screen and theme, not from a mockup, since five accounts
+is enough that two colours distinct as chips may read alike as thin stripes.
+
+**Reply cards carry no bar.** The account belongs to the conversation and is
+stated once at its head, and a second vertical line in a reply's gutter would
+sit a few pixels from the spine and compete with it.
+
+**Instead the spine inherits the account's colour**, so an expanded thread is
+bounded by one accent from its root to its last reply without drawing two lines
+anywhere.
+
+This **replaces the account chip** rather than joining it. The chip ate a third
+of line 2 on every card to repeat a name the user already knows, which is
+exactly the texture item 53 is about.
+
+**The colour is blended toward the background, never used raw.** An account
+colour is chosen to be a chip's fill, with text drawn on top in whatever stays
+legible against it (`TagColors::textColourOn`). The same colour as a thin line
+on the pane's own background is a different problem: it has to be followable
+down a long expansion without competing with the senders beside it, which is the
+constraint `threadLineColour()` already states and meets with a 0.35 weight
+toward the palette's text. The accent spine blends the account colour toward
+`QPalette::Base` by that same weight, so it keeps the hue that identifies the
+account and loses the saturation that would shout.
+
+**An account with no configured colour still gets one**, derived from the tag
+name by `TagColors::colourFor`, which never fails. That fallback is deliberate
+and is kept: a stable arbitrary colour is more useful than no accent, and it
+means adding an account to the config and forgetting to colour it degrades to
+something usable rather than to nothing.
+
+**The account dropdown carries the same colours.** `m_accountBox`
+(`mainwindow.cpp:399`) is filled in a plain loop over `m_config.accounts()`;
+each entry gets its account's colour as `Qt::DecorationRole`, which Qt renders
+as a swatch with no delegate. That is what makes the accent legible at all: a
+bar down a card means nothing until something says which account it is, and the
+dropdown is where the user already goes to think about accounts. Use the raw
+colour here, not the blended one: a swatch is a filled patch like a chip, not a
+thin line.
+
## The spine
Replies are indented by depth with a **continuous vertical line per depth
-level**, drawn the full height of each reply card, in `threadLineColour()`.
+level**, drawn the full height of each reply card, in the thread's blended
+account accent (above), falling back to `threadLineColour()` when there is no
+account tag at all.
No elbows, no horizontal tick into the card, and no different glyph on the last
child. The alternatives were shown and this one chosen: elbows would require the
@@ -172,8 +218,10 @@ painting the whole card, neither is reachable.
- Action scope by row kind, and the status-bar scope naming before and after an
action. No confirmation dialogs, per the standing rule.
- Undo through `TagChange::inverted()`.
-- The account chip, the `deletedColour()` / `spamColour()` row fills, and the
- unread/read weight and colour cues.
+- The `deletedColour()` / `spamColour()` row fills, and the unread/read weight
+ and colour cues.
+- `AccountLabelRole` and `AccountColourRole`, though what they feed changes: the
+ chip becomes the left accent bar and the dropdown's swatches.
- `setUniformRowHeights(true)`.
## New