Skip to content

The tab header is invisible at rest, and each tab carries its own title (#441) - #514

Merged
maximsan merged 7 commits into
mainfrom
feat/header-invisible-at-rest
Sep 5, 2026
Merged

The tab header is invisible at rest, and each tab carries its own title (#441)#514
maximsan merged 7 commits into
mainfrom
feat/header-invisible-at-rest

Conversation

@maximsan

@maximsan maximsan commented Sep 5, 2026

Copy link
Copy Markdown
Owner

Closes #441.

The design pairs an invisible header with a large title on the page. The app had the header always on and no large title anywhere, so the two ran opposite ways round — and every tab root was one title short.

The header floats over the tab now instead of standing above it. At rest it draws nothing but its entries, and each tab root opens with its own large title; past the design's 72 the bar fills, blurs and rules, and the compact title slides in to replace the large one that has gone under it. Cards regains the Collection heading #396 had to drop.

The SubHeader half of #245 is split out as #513, with the reason recorded there — different seam, fifteen screens, and its own scroll-flag problem.

Worth a look

  • The bar's painted half is laid beside its content, not around it. A DecoratedBox claims every hit inside its shape, so a bar wrapping its own contents swallows the drag meant to scroll the page beneath it. header_chrome_test.dart holds that down.
  • AppOverlay grows the saturation the design writes beside its blur, and an at(progress) that scales the whole token — so a bar fading in cannot fade the tint and snap the blur on behind it.
  • 0.18em leaves OffTokens for AppTracking.chrome. The tab label was the one component set at it until the header's compact eyebrow turned out to be too, and a width two things share is vocabulary rather than an exception.
  • FloatTopbar was filling with an opaque page and no blur where the design writes it with the header's own two constants — fixed here, since the token now exists. Its own test already called that value "the header fill".
  • Three tabs open their title below the entries, where the design opens only Path there. The bar floats over the tab, so nothing keeps the two apart, and the design never has to solve it — it freezes Learn's date to Friday, May 8. Measured in Fraunces, the widest date longDate can make sets 350.5pt where the entries begin 269pt in. Narrowing the title would make that date wrap, so Learn and Profile take Path's own paddingTop: 64 instead; Cards keeps the design's 24. Registered in OffTokens with the measurement, and pinned by a test.

Checks

dart format, flutter analyze, the metrics gate and the full suite (2511) all clean on the merge with main.

…n title (#441)

The design pairs an invisible header with a large title on the page; the app
had the header always on and no large title anywhere. So the two ran opposite
ways round — the design gains a title on scroll, the app lost an eyebrow.

The header now floats over the tab rather than standing above it: at rest it
draws nothing but its entries, and each tab root opens with its own large
title. Scrolled past the design's 72, `HeaderChrome` fills — the page pulled
over itself at 94%, blurred 16px and lifted back to its warmth, hairlined,
with the short gradient fading below — and `HeaderCompactTitle` slides in
carrying the title that has just gone under it.

Cards regains the `Collection` heading #396 had to drop.

The bar's painted half is laid beside its content and ignores the pointer: a
`DecoratedBox` claims every hit inside its shape, so a bar wrapping its own
contents would swallow the drag meant to scroll the page beneath it.

`AppOverlay` grows the saturation the design writes beside its blur, so
`blur(16px) saturate(1.3)` cannot be taken in halves. 0.18em leaves `OffTokens`
for `AppTracking.chrome`: the tab label was the one component set at it until
the compact eyebrow turned out to be too, and a width two things share is
vocabulary rather than an exception.

The `SubHeader` half of #245 is split out as #513, with the reason recorded
there.
…Path's own inset

Standards review:

- `ScrolledProgress` carries the reduced-motion rule for a bar's fade once,
  where the chrome, the compact title and the reward screens' bar each stated
  it. `AppOverlay.at` scales the whole token, so a call site no longer takes
  the tint apart to fade the blur with it — which is what CLAUDE.md's overlay
  rule says, and it now names both renderers.
- `_Paint` is a widget, so `_PaintedBar`; the compact title's builder no longer
  shadows its own `title`; `TabLargeTitle` takes an `AppRoute` rather than a
  path string, so a tab can only be named by the catalogue that defines it.

Spec review:

- `FloatTopbar` filled with an opaque page and no blur where the design writes
  it with the header's own `HEADER_FILL` and `HEADER_BLUR`. It takes
  `mood.headerFill` now — its own test already called that "the header fill".
- The design opens Path's title at 64 where the other three tabs open at 24,
  and the app opened all four at 24. `TabLargeTitle` takes the room its tab
  opens on, and Path's 64 is registered with its reason.
- The Path tally gap and the bar's two side insets say where they round and
  why, rather than diverging quietly.
…behind them

The bar floats over the tab now, so nothing lays the title and the entries out
against each other. The design does not have to solve that: it freezes Learn's
date to `Friday, May 8`. Measured in Fraunces at the display rung, the widest
date `longDate` can make sets 350.5pt, and on a 393pt phone the entries begin
269pt into the title — so an ordinary Wednesday loses its tail behind the two
buttons.

Narrowing the title to clear them would make that same date wrap, which is
worse. The design's own answer is the Path tab's `paddingTop: 64`, which opens
the title below the entries instead of beside them, and Learn and Profile take
it for the same reason: neither title is a fixed string. Cards keeps the
design's 24 — `Collection` is nowhere near that wide.

Registered as `tabTitleClearOfEntries` with the measurement, and pinned by a
test that walks the three tabs and asserts the title starts below the entries.
…-at-rest

# Conflicts:
#	CLAUDE.md
#	docs/CHANGELOG.md
@maximsan
maximsan merged commit 4e26d41 into main Sep 5, 2026
6 checks passed
@maximsan
maximsan deleted the feat/header-invisible-at-rest branch September 5, 2026 17:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

The tab header draws at rest where the design keeps it invisible until scroll

1 participant