Context
Operator direction 2026-09-01, after the narrow-header finding on the Workstation: rather than an actions overflow, challenge the ui: 'inline' tab header itself — the horizontal padding is too much, the title is too big, and it should not be bold. Users can drag the splitter for the rest.
Live latest-open sweep: checked the latest 20 open issues at 2026-09-01T21:03:06Z, the last 30 A2A messages (all read-states), and the Knowledge Base ticket corpus; no equivalent. #17950 (merged) introduced the inline/standalone variants; #18020 (merged) fixed the drag proxy's density; neither touched title typography.
Body update 2026-09-01T22:20Z (author, PR #18048 round 1): the weight token's fallback row below was wrong as first written — an undefined custom property makes the declaration invalid at computed-value time and the title inherits the document's weight, it does not fall back to anything. The consumption site now carries the fallback explicitly, so the row is true by construction; a fifth engine theme without tab tokens (theme-cyberpunk) is the case that made it matter. Found by Grace.
The Problem
Measured on the Workstation (neo-dark theme, the "Queues" pane, header 180px wide, focus-revealed rail):
| Surface |
Today |
| inline tab button padding |
4px 12px 3px (--tab-button-padding: 4px var(--sem-spacing-small) 3px) |
| title font size |
16px (--tab-button-text-font-size → --sem-typo-label-regular-fontSize → --core-fontsize-body) |
| title font weight |
600 — inherited from --button-text-font-weight (--core-fontweight-semibold), because the tab header stylesheet sets a size token and no weight token |
| action cluster |
5 × 24px + 1px spacer = 121px |
| what the title gets |
the tab overflow plugin caps the active tab to the usable 59px → a 36px text box → "Q…" |
"Queues" at 16px/600 needs 59px. Any one lever alone does not fit that case; the three together do: at 13px/400 the title needs ~45px, and 8px horizontal padding leaves it 44px. The rail is focus-transient, so this is about the focused state reading well, not about reserving space for it.
The Architectural Reality
resources/scss/src/tab/header/Button.scss paints .neo-button-text with font-size: var(--tab-button-text-font-size) only; the weight falls through to the generic button rule (src/button/Base.scss, var(--button-text-font-weight)). Every theme that sets a semibold button weight therefore sets semibold tab titles by accident.
- The inline variant's padding lives per theme in the
neo-tab-container-inline blocks: neo themes 4px var(--sem-spacing-small) 3px, classic themes 7px 10px 6px (resources/scss/theme-*/tab/Container.scss).
- Emphasis for the active tab already has two carriers that cost no width: the indicator bar (
--tab-strip-height) and the Workstation's full-ink pressed color.
- The active-tab cap is the overflow plugin's contract (
src/tab/plugin/Overflow.mjs#applySplit), not a defect; it stays.
- Five themes build, four declare tab tokens.
theme-cyberpunk is a first-class build target with no tab/ directory: --tab-button-text-color and --tab-button-text-font-size are already undefined there and those two properties already inherit. A new tab-level font-weight rule at (0,3,0) outranks the button rule at (0,2,0), so without a fallback an undefined weight token would take away the one title property cyberpunk still got right.
The Fix
- Add
--tab-button-text-font-weight as the tab title's weight authority: declared in the four engine theme files with today's effective value (var(--button-text-font-weight), by reference), consumed in src/tab/header/Button.scss on .neo-button-text with the button family's weight as the var() fallback. No visual change for ui: null and standalone, in any theme — including one that declares no tab tokens.
- In the inline variant blocks (all four engine themes), set the trimmed values: regular weight, a smaller size (neo themes: a new label-small step,
--core-fontsize-small → --sem-typo-label-small-*; classic: the existing 11px is already small enough), and 8px horizontal padding (--sem-spacing-xsmall in the neo themes). The label-small step is declared as the full family/size/weight triple like the existing label steps — that is the design-token rule, so the family token is not dead weight.
- The Workstation inherits the engine tokens; if its density wants a different step, it sets the token in its own Viewport stylesheet — no engine special-casing.
- Screenshot receipts for operator acceptance: the "Queues" header at 180px, focused, before and after; one non-inline tab container to prove byte-identity.
Contract Ledger
| Target surface |
Source of authority |
Proposed behavior |
Fallback |
Docs |
Evidence |
--tab-button-text-font-weight (new token) |
resources/scss/src/tab/header/Button.scss + the four theme tab/header/Button.scss files |
sole weight authority for tab titles; inline variant overrides it to regular |
absent → the button family's weight (--button-text-font-weight) through the consumption-site var() fallback; a theme with no tab tokens (cyberpunk) keeps its titles byte-identical |
theme token comment |
component paint spec, incl. a no-tab-tokens theme arm |
| inline variant padding + size |
resources/scss/theme-*/tab/Container.scss inline blocks |
8px horizontal, one size step smaller |
none |
same |
component paint spec + screenshots |
Decision Record impact: none (ADR 0029 does not govern tab typography).
Acceptance Criteria
Out of Scope
- An actions overflow control for narrow headers (rejected for now: the rail is focus-transient and the splitter is the honest fix).
- The overflow plugin's active-tab cap.
- The standalone variant's geometry.
theme-cyberpunk's missing tab tokens for color and size (pre-existing: those two properties already inherit there today; this ticket only guarantees it loses nothing further).
Avoided Traps
- Fixing the Workstation only in its own stylesheet — the leak is an engine token gap and every consumer inherits it.
- Reducing
--tab-header-action-size to buy width — 24px is already the minimum honest hit target.
- Declaring the new token as a literal in the theme files — the identity with the button family would then hold only as of today; by reference it survives a future retune.
- Consuming the token without a fallback — a theme that never opted into tab tokens would have its titles regress silently, invisible to a four-theme matrix.
Related
Refs #17836 · #17950 (variants) · #18020 (proxy density) · #18039 (the finding's origin)
Origin Session ID: 6197a12f-acf2-478a-b05d-4ece32474259
Retrieval Hint: "inline tab header title weight token font-size padding trim narrow header cyberpunk fallback"
— Mnemosyne (Claude Fable 5.1 · Claude Code) · session 6197a12f-acf2-478a-b05d-4ece32474259 🪢
Context
Operator direction 2026-09-01, after the narrow-header finding on the Workstation: rather than an actions overflow, challenge the
ui: 'inline'tab header itself — the horizontal padding is too much, the title is too big, and it should not be bold. Users can drag the splitter for the rest.Live latest-open sweep: checked the latest 20 open issues at 2026-09-01T21:03:06Z, the last 30 A2A messages (all read-states), and the Knowledge Base ticket corpus; no equivalent.
#17950(merged) introduced the inline/standalone variants;#18020(merged) fixed the drag proxy's density; neither touched title typography.The Problem
Measured on the Workstation (neo-dark theme, the "Queues" pane, header 180px wide, focus-revealed rail):
4px 12px 3px(--tab-button-padding: 4px var(--sem-spacing-small) 3px)--tab-button-text-font-size→--sem-typo-label-regular-fontSize→--core-fontsize-body)--button-text-font-weight(--core-fontweight-semibold), because the tab header stylesheet sets a size token and no weight token"Queues" at 16px/600 needs 59px. Any one lever alone does not fit that case; the three together do: at 13px/400 the title needs ~45px, and 8px horizontal padding leaves it 44px. The rail is focus-transient, so this is about the focused state reading well, not about reserving space for it.
The Architectural Reality
resources/scss/src/tab/header/Button.scsspaints.neo-button-textwithfont-size: var(--tab-button-text-font-size)only; the weight falls through to the generic button rule (src/button/Base.scss,var(--button-text-font-weight)). Every theme that sets a semibold button weight therefore sets semibold tab titles by accident.neo-tab-container-inlineblocks: neo themes4px var(--sem-spacing-small) 3px, classic themes7px 10px 6px(resources/scss/theme-*/tab/Container.scss).--tab-strip-height) and the Workstation's full-inkpressedcolor.src/tab/plugin/Overflow.mjs#applySplit), not a defect; it stays.theme-cyberpunkis a first-class build target with notab/directory:--tab-button-text-colorand--tab-button-text-font-sizeare already undefined there and those two properties already inherit. A new tab-levelfont-weightrule at (0,3,0) outranks the button rule at (0,2,0), so without a fallback an undefined weight token would take away the one title property cyberpunk still got right.The Fix
--tab-button-text-font-weightas the tab title's weight authority: declared in the four engine theme files with today's effective value (var(--button-text-font-weight), by reference), consumed insrc/tab/header/Button.scsson.neo-button-textwith the button family's weight as thevar()fallback. No visual change forui: nullandstandalone, in any theme — including one that declares no tab tokens.--core-fontsize-small→--sem-typo-label-small-*; classic: the existing 11px is already small enough), and 8px horizontal padding (--sem-spacing-xsmallin the neo themes). The label-small step is declared as the full family/size/weight triple like the existing label steps — that is the design-token rule, so the family token is not dead weight.Contract Ledger
--tab-button-text-font-weight(new token)resources/scss/src/tab/header/Button.scss+ the four themetab/header/Button.scssfiles--button-text-font-weight) through the consumption-sitevar()fallback; a theme with no tab tokens (cyberpunk) keeps its titles byte-identicalresources/scss/theme-*/tab/Container.scssinline blocksDecision Record impact: none (ADR 0029 does not govern tab typography).
Acceptance Criteria
--tab-button-text-font-weighttoken exists in all four engine themes and is the only rule deciding a tab title's weight;ui: nullandstandalonecontainers render byte-identical to before (computed size, weight, padding compared intest/playwright/component/tab/ContainerUi.spec.mjs), and a theme that declares no tab tokens keeps the button family's weight through the fallback.#18020) keeps the same density as the header it left.Out of Scope
theme-cyberpunk's missing tab tokens for color and size (pre-existing: those two properties already inherit there today; this ticket only guarantees it loses nothing further).Avoided Traps
--tab-header-action-sizeto buy width — 24px is already the minimum honest hit target.Related
Refs #17836 · #17950 (variants) · #18020 (proxy density) · #18039 (the finding's origin)
Origin Session ID: 6197a12f-acf2-478a-b05d-4ece32474259
Retrieval Hint: "inline tab header title weight token font-size padding trim narrow header cyberpunk fallback"
— Mnemosyne (Claude Fable 5.1 · Claude Code) · session 6197a12f-acf2-478a-b05d-4ece32474259 🪢