Compact-slot typography rule (the 16px board card title needs a rule, not an exception) #232

Open
opened 2026-10-27 22:48:50 +00:00 by peterswimm · 1 comment
Owner

Split out from Toilville/toilville_rituals#619's design issue — #231's decision comment records this as "a separate follow-up" without filing one.

The decision that created this

#231 accepted 16px board card titles as the design direction for compact board slots, and was explicit that this does not change the ratified global title rule:

Board card titles are 16px. This is accepted as the design direction for compact board slots. #231 does not change the ratified global title rule. The need for a compact-slot typography rule is recorded as a separate follow-up.

So there is now one accepted exception and no rule that contains it. That is the gap.

What to decide

  • Is "compact slot" a density concern or a container concern? SHAPES.md §13 already carries "Density modes (compact / comfortable / spacious): not yet specified. Likely a runtime preference rather than a schema concern." A compact-slot type rule either answers part of that open question or deliberately sits beside it.
  • Which type tokens does a compact slot get — a full parallel ramp, or a small set of overrides on the existing ramp?
  • What counts as a compact slot? A Kanban card is one. Is an inbox row? A calendar event? If the answer is "any slot the author marks compact", that is a schema flag, not a design rule.
  • Does the existing ForgeSlotDensity flag (already read by all 12 block renderers, per toilville_rituals#171) carry this, or is it a separate axis?

Why it matters beyond one number

The ratified global title rule stands, and board cards now contradict it by agreement. Until the exception is expressed as a rule, there is nothing to check a second compact surface against, and the next one will be argued from this one's screenshot rather than from a token.

Acceptance

  • A written rule that covers the 16px board card title as an instance, not as an exception.
  • The rule names its tokens, and any new token is registered in packages/udg/lib/src/token_manifest.dart with contrast-pair coverage in both themes (toilville_rituals CLAUDE.md, "Adding or changing a color token" — the same discipline applies to type).
  • SHAPES.md §13's density bullet is updated to point here, or explicitly scoped away from it.
Split out from Toilville/toilville_rituals#619's design issue — #231's decision comment records this as "a separate follow-up" without filing one. ## The decision that created this #231 accepted **16px board card titles** as the design direction for compact board slots, and was explicit that this does *not* change the ratified global title rule: > **Board card titles are 16px.** This is accepted as the design direction for compact board slots. #231 does not change the ratified global title rule. The need for a compact-slot typography rule is recorded as a separate follow-up. So there is now one accepted exception and no rule that contains it. That is the gap. ## What to decide - Is "compact slot" a **density** concern or a **container** concern? `SHAPES.md` §13 already carries "Density modes (compact / comfortable / spacious): not yet specified. Likely a runtime preference rather than a schema concern." A compact-slot type rule either answers part of that open question or deliberately sits beside it. - Which type tokens does a compact slot get — a full parallel ramp, or a small set of overrides on the existing ramp? - What counts as a compact slot? A Kanban card is one. Is an inbox row? A calendar event? If the answer is "any slot the author marks compact", that is a schema flag, not a design rule. - Does the existing `ForgeSlotDensity` flag (already read by all 12 block renderers, per toilville_rituals#171) carry this, or is it a separate axis? ## Why it matters beyond one number The ratified global title rule stands, and board cards now contradict it by agreement. Until the exception is expressed as a rule, there is nothing to check a *second* compact surface against, and the next one will be argued from this one's screenshot rather than from a token. ## Acceptance - [ ] A written rule that covers the 16px board card title as an instance, not as an exception. - [ ] The rule names its tokens, and any new token is registered in `packages/udg/lib/src/token_manifest.dart` with contrast-pair coverage in both themes (toilville_rituals `CLAUDE.md`, "Adding or changing a color token" — the same discipline applies to type). - [ ] `SHAPES.md` §13's density bullet is updated to point here, or explicitly scoped away from it.
Member

Decision for #232: the compact-slot title

This is Ville's design decision. The technical shape of the mechanism goes to the implementation issue, where Peter's precedence rule applies.

Decision

A narrow, repeated card slot renders its title with one semantic token, titleCompact: 16px (size.body), weight 600, leading.snug. Every other slot keeps headingSm (20px, 600). The global title rule is unchanged. The 16px board card title becomes the first instance of this rule. It is no longer an exception.

Why

Board cards are horizontally constrained. At the normal 20px title size, ordinary multi-word run titles wrap too aggressively. They can become three one-word lines. The title then dominates the card. Cards get taller, fewer runs fit on screen, and the board is harder to scan. The compact title keeps a useful line length in narrow, repeated cards.

In the wireframes, two cards wrap to three lines at 20px ("Add dark / mode to / settings" and "Weekly / dependency / bump"). At 16px only the Weekly card does.

The alternative I rejected

I considered making board cards larger to fit the normal title size. A board is valuable because it shows many runs and their state at once. Bigger cards would show less of the board at a glance. I prefer compact cards and more runs on screen.

So the 16px title is a deliberate hierarchy tradeoff. Each card gives up some title prominence. The board gains information density and scanability. This is a design choice. It is not a technical constraint.

Answers to the questions in this issue

  1. Density or container? Container. A compact slot is a small, repeated collection container with a constrained hierarchy. The actor's density preference does not decide whether a container is a compact slot. Density may later change spacing inside a container. It never picks the title token. SHAPES §13 stays "a runtime preference" and does not select a type role.
  2. A full parallel ramp or overrides? Neither. One semantic token, built from primitives that already exist: size.body, weight 600 and leading.snug. No new size, no new weight and no new colour.
  3. What counts as a compact slot?
    • A Kanban card is one.
    • An inbox row is not. It keeps headingSm, as BLOCK_RENDERING_PRINCIPLES §1 already says for dense rows.
    • A calendar event is outside this rule. It is a single-line label, not a card. It stays at its label size.
  4. Does ForgeSlotDensity carry it? No. This is a separate axis. The existing mechanism answers a different question:
    • Flutter sets it from the platform surface (flutterCompact), which is viewport identity.
    • An author hint (surface_hints.flutter.compact) overrides it.
    • It collapses the forensic strip and tightens padding. It has never changed title size.
    • macOS sets isCompactSlot on inbox rows (PresentationShared.swift:140). Those rows must keep their 20px title. Reusing it would shrink them.

No author flag

The container decides, not the author. There is no compact=true schema flag for typography. An author cannot make an inbox row or a calendar event a compact slot.

Acceptance for this issue

  • The rule above covers the 16px board card title as an instance. It names titleCompact and its primitives.
  • titleCompact is registered where the other type tokens are, including packages/udg/lib/src/token_manifest.dart. The colour pair on a card is textPrimary on bgSurfaceCard. The existing contrast tests already cover that pair in both themes (8.52:1 light, 9.17:1 dark). #233 decides the card surface itself.
  • SHAPES §13: the density bullet points here and says density never selects a type role.
  • BLOCK_RENDERING_PRINCIPLES §1 ("title prominence is constant across slots") gains one exception: the compact-slot title.

Implementation, for the follow-up issue

  • The container's slot class picks the title token. The channel is host-injected, in the same style as ForgeSlotDensity. It carries a role, not a boolean, and it has no author override.
  • Each port needs the channel: Flutter and macOS. A parity test holds them to one answer.
  • Peter's precedence rule applies to the shape of this mechanism.
**Decision for #232: the compact-slot title** This is Ville's design decision. The technical shape of the mechanism goes to the implementation issue, where Peter's precedence rule applies. **Decision** A narrow, repeated card slot renders its title with one semantic token, `titleCompact`: 16px (`size.body`), weight 600, `leading.snug`. Every other slot keeps `headingSm` (20px, 600). The global title rule is unchanged. The 16px board card title becomes the first instance of this rule. It is no longer an exception. **Why** Board cards are horizontally constrained. At the normal 20px title size, ordinary multi-word run titles wrap too aggressively. They can become three one-word lines. The title then dominates the card. Cards get taller, fewer runs fit on screen, and the board is harder to scan. The compact title keeps a useful line length in narrow, repeated cards. In the wireframes, two cards wrap to three lines at 20px ("Add dark / mode to / settings" and "Weekly / dependency / bump"). At 16px only the Weekly card does. **The alternative I rejected** I considered making board cards larger to fit the normal title size. A board is valuable because it shows many runs and their state at once. Bigger cards would show less of the board at a glance. I prefer compact cards and more runs on screen. So the 16px title is a deliberate hierarchy tradeoff. Each card gives up some title prominence. The board gains information density and scanability. This is a design choice. It is not a technical constraint. **Answers to the questions in this issue** 1. **Density or container?** Container. A compact slot is a small, repeated collection container with a constrained hierarchy. The actor's density preference does not decide whether a container is a compact slot. Density may later change spacing inside a container. It never picks the title token. SHAPES §13 stays "a runtime preference" and does not select a type role. 2. **A full parallel ramp or overrides?** Neither. One semantic token, built from primitives that already exist: `size.body`, weight 600 and `leading.snug`. No new size, no new weight and no new colour. 3. **What counts as a compact slot?** - A Kanban card is one. - An inbox row is not. It keeps `headingSm`, as BLOCK_RENDERING_PRINCIPLES §1 already says for dense rows. - A calendar event is outside this rule. It is a single-line label, not a card. It stays at its label size. 4. **Does `ForgeSlotDensity` carry it?** No. This is a separate axis. The existing mechanism answers a different question: - Flutter sets it from the platform surface (`flutterCompact`), which is viewport identity. - An author hint (`surface_hints.flutter.compact`) overrides it. - It collapses the forensic strip and tightens padding. It has never changed title size. - macOS sets `isCompactSlot` on inbox rows (`PresentationShared.swift:140`). Those rows must keep their 20px title. Reusing it would shrink them. **No author flag** The container decides, not the author. There is no `compact=true` schema flag for typography. An author cannot make an inbox row or a calendar event a compact slot. **Acceptance for this issue** - The rule above covers the 16px board card title as an instance. It names `titleCompact` and its primitives. - `titleCompact` is registered where the other type tokens are, including `packages/udg/lib/src/token_manifest.dart`. The colour pair on a card is `textPrimary` on `bgSurfaceCard`. The existing contrast tests already cover that pair in both themes (8.52:1 light, 9.17:1 dark). #233 decides the card surface itself. - SHAPES §13: the density bullet points here and says density never selects a type role. - BLOCK_RENDERING_PRINCIPLES §1 ("title prominence is constant across slots") gains one exception: the compact-slot title. **Implementation, for the follow-up issue** - The container's slot class picks the title token. The channel is host-injected, in the same style as `ForgeSlotDensity`. It carries a role, not a boolean, and it has no author override. - Each port needs the channel: Flutter and macOS. A parity test holds them to one answer. - Peter's precedence rule applies to the shape of this mechanism.
Sign in to join this conversation.
No description provided.