---
title: Supermail — Inbox Emails & Row Density
---
# Supermail — Inbox Emails & Row Density

## What it is

How Supermail's mail list looks and how much room each email takes: the configurable header layout, the row spacing control, the reply indicator on threads you have answered, the cleaner conversation header, sender brightness and the attachment paperclip, and the setting that bounds how many emails sit in the inbox.

## Where to find it

All of it is inside Supermail: the header above the email list, the rows themselves, and the reading pane.

## How it behaves

### What changed (layout polish — 2026-07-31)

The **Mail | Sessions** tab row that previously occupied ~160 px of sidebar space in the Mail
view has been moved into a compact header above the email list. The previously-empty sidebar
column is gone, giving the email list more horizontal room. Users who have the folder nav
pinned ("Show sidebar" ON in Supermail's own Settings → General → Personalization) still see their
folder list in that column — the change only eliminates the dead space when the nav is in
overlay mode (the default).

This was the precursor to the configurable **Header layout** setting below (added 2026-08-04):
the compact single-row header is now the default (`unified`), with the old two-row header still
available as `current`.

### Header layout (`supermailHeaderLayout`) — 2026-08-04

### What it does

Chooses how the **Mail | Sessions** switch and the mail toolbar are arranged. Three layouts:

- **Unified** (default) — ONE header row. The Mail/Sessions switch is hosted inside the mail app's
  own toolbar (a mail-app-native switch), so there is no separate Omniscio strip above it — the
  cleanest, lowest-chrome header.
- **Current** — the legacy two-row header: the Omniscio Mail/Sessions strip sits ABOVE the mail
  app's own toolbar.
- **Left rail** — the Mail/Sessions switch becomes a slim vertical icon rail on the LEFT of the mail
  app, freeing the whole top row.

Whichever layout is active, the switch drives the SAME single tab source (`supermailTab`), so
Mail/Sessions switching and the Sessions count badge behave identically. In the Sessions view (the
mail app is hidden there) the switch always renders as the Omniscio strip atop the session list —
horizontal for Current/Unified, vertical for Left rail.

### How to change it

**Settings → Email & Summaries → Header layout** — a Current / Unified / Left rail control. Requires
Supermail to be enabled.

- **Setting key:** `supermailHeaderLayout`
- **Values:** `'current' | 'unified' | 'rail'`
- **Default:** `'unified'`
- Takes effect immediately; no restart required.
- **How Unified works:** it edits the mail app's own toolbar to host the switch (a native
  component styled with the mail app's tokens, so the `.supermail-scope` typography never distorts
  it), driven by Omniscio through two bridge methods (`getSupermailHeaderState` + `setSupermailTab`)
  and a `supermail-header` push. Invariants + tests:
  `.claude/memory/contracts/supermail-start-session-contract.md` (`header-layout-setting`).

### Row spacing / density (`supermailDensity`)

### What it does

Controls how much vertical space sits between emails in the Supermail list. It is built as a
themeable **baseline** plus a per-level shift, so a custom theme controls the default spacing and
the picker still tightens/loosens on top of it. Five levels, tightest → roomiest:

- **Tight** — baseline − 6 px. On dense rows this removes the padding entirely (the floor is
  `max(0, …)`), for the most emails per screen.
- **Compact** — baseline − 3 px (tighter), so you see more emails at once.
- **Comfortable** (default) — the baseline spacing. With no custom theme this is each row
  variant's vendored default (dense rows 6 px, preview rows 12 px), so existing users see no
  change. A custom theme's `supermailRowSpacing` sets this baseline.
- **Spacious** — baseline + 8 px (roomier), for an airier list.
- **Roomy** — baseline + 16 px, the most breathing room per email.

**Why five (2026-09-05).** The original three spanned only −3 px…+8 px, so Compact vs Comfortable
differed by 3 px per side — a change small enough to read as "nothing happened", which is what made
the control look absent even to someone who found it. `tight` and `roomy` widen the ends; the
original three keep their EXACT prior deltas, so no stored choice moved and no migration was needed.

The overrides live in Omniscio's `globals.css` (not in the vendored Supermail source). The picker
sets `--supermail-row-delta` via a `data-density` attribute on the panel root; each row's padding
is `max(0, baseline + delta)`, scoped to the thread-list container so search results and pickers
are never touched. Each row variant keeps its own fallback, so a theme never flattens the dense
vs. preview layouts.

### Make it themeable (custom CSS / themes)

A user-applied **custom theme** controls the row-spacing baseline — i.e. the **default
(Comfortable)** spacing, which the other four levels then shift. A `.theme.json` sets the
`supermailRowSpacing` key (a CSS length such as `"10px"`), which Omniscio emits as the
`--supermail-row-py` CSS variable. This is the one themeable spacing token — see
`.claude/memory/contracts/custom-theme-tokens-contract.md`. It takes effect immediately on the
default view; picking any other level adjusts relative to the theme's baseline.

### How to change it

Two places, both driving the ONE `supermailDensity` setting (they stay in lock-step — change either
and the other reflects it):

- **In the Mail view (2026-08-10)** — open the **View options** menu in the inbox header (the same
  sort · group · unread menu) and pick a **Row spacing** level: Tight / Compact / Comfortable /
  Spacious / Roomy. This is the in-context control, reachable in every header layout — including the
  default Unified, which shows no Omniscio chrome in Mail mode. The active level is checkmarked; the
  menu deliberately stays OPEN on select, so the list behind it re-spaces immediately and levels can
  be compared by eye without reopening the menu. This is the live view against your real inbox.
- **Settings → Email & Summaries → Row spacing** — the same five levels, plus a **live preview**: three
  sample email rows that re-space as you pick. Settings sits nowhere near the mail list, so without
  the preview the control is blind. The preview is rendered by the SAME `globals.css` rule as the
  real thread list (`.supermail-density-preview` is joined into the dense-row selector and reads the
  same delta table), so it shows the actual resulting spacing, not an approximation — the two cannot
  drift. Requires Supermail to be enabled.

- **Setting key:** `supermailDensity`
- **Values:** `'tight' | 'compact' | 'comfortable' | 'spacious' | 'roomy'` (the tuple
  `SUPERMAIL_DENSITY_VALUES`, ordered tightest → roomiest; both pickers MAP it rather than
  re-listing the levels, so a new level cannot go missing from a picker)
- **Default:** `'comfortable'`
- Takes effect immediately; no restart required.
- **How the in-Mail control works:** the vendored View-options menu reads + writes `supermailDensity`
  through the header-state bridge — `getSupermailHeaderState` seeds the current level LIVE (so the
  checkmark is never stale) and `setSupermailDensity` writes the pick back — the same channel that
  carries the Header layout, so the menu and the Settings control can never disagree. Invariants +
  tests: `.claude/memory/contracts/supermail-start-session-contract.md` (`in-mail-row-density-control`).
- **Migration:** a legacy `supermailCompactDensity: true` install is migrated once to
  `supermailDensity: 'compact'` (the old boolean is then removed). Nothing migrates INTO `tight` or
  `roomy` — they are picker-only.
- **Adding a level:** add it to `SUPERMAIL_DENSITY_VALUES` **and** give it a `--supermail-row-delta`
  rule in `globals.css` for BOTH `.supermail-scope[data-density='…']` and
  `.supermail-density-preview[data-density='…']`, **and** add it to `VALID_DENSITIES` in the vendored
  `header-state-store.ts` (which cannot import the shared tuple). Miss the CSS and the level renders,
  persists and does nothing; miss the vendored copy and it is coerced back to Comfortable on the way
  into the mail app. Both failures are silent at runtime and are held by
  `tests/unit/lint/supermail-density-vendored-hooks.test.ts`.

### When you've replied (the reply indicator) — 2026-08-03

When the newest message in a thread is one **you** sent, the inbox row makes that obvious at a
glance (Gmail / Superhuman style):

- A small **reply arrow (↩)** marks the row.
- The preview is prefixed **"You:"** and shows your most recent reply.
- The row title stays the **other person's name** (not your own), so you still see who the thread
  is with — even on a thread with no subject line.

Details:

- **Keyed on your latest SENT message.** The indicator shows only when the newest **non-draft**
  message in the thread is from your signed-in account. An unsent draft never triggers it. If the
  other person replies after you, their message becomes the newest and the row shows them again.
- **A note-to-self shows no indicator.** An email with no other party — one you sent only to
  yourself — isn't a reply *to* anyone, so it shows neither the reply arrow nor "You:"; the row
  just reads **"Me"**. The indicator needs a real counterparty (a send that also goes to someone
  else still counts).
- **"You:" is neutral**, not colored — the reply arrow is the one accent mark.
- **No setting** — it's automatic whenever Supermail can tell you sent the latest message.
- **Works across data sources.** On the local-mirror (amc-gmail) path the other person's name is
  computed on read from the mirror — no re-sync, no migration; on the live path it's derived from
  the thread's own messages.

### Cleaner conversation header — 2026-08-03

The header atop each open message (avatar · sender · "to …" · time) was realigned: the avatar is
vertically centered against a two-line name / "to …" block, and the timestamp sits cleanly on the
right with more breathing room. Visual polish only — no behavior or setting change.

### Sender brightness & the attachment paperclip — 2026-08-07

Two small readability touches for the inbox list:

- **A read email's sender now matches its subject's brightness.** Previously a read email's sender
  name was dimmed to the same faint grey as the preview text, so it could look washed-out next to its
  own subject. It now sits on the same brighter ink as the subject. Read vs. unread still reads clearly
  — an unread sender is heavier (bold), not a different colour. Subjects and unread senders are
  unchanged.
- **A paperclip (📎) marks a thread with a file attachment.** The indicator already existed but never
  lit up on the local-mirror (amc-gmail) inbox, because that fast list carries no attachment data. It
  now shows on threads with a real file attached. Inline signature / logo images are ignored (matching
  Gmail), so a branded newsletter doesn't show a false paperclip. On the local-mirror path the flag
  fills in as your inbox finishes syncing, so a brand-new / cold inbox may take a moment before every
  paperclip appears.
- **No setting** — both are automatic.

### Emails in your inbox (`supermailEmailsInInbox`)

### What it does

When enabled, every incoming Supermail email creates a dismissible item in the Omniscio
unified inbox — the same inbox where sessions, approvals, SMS, and other sources appear.
Each inbox item carries an inline free-text reply box; submitting it sends your reply to
the sender of that thread in the background.

Key behaviors:

- **Opt-in, off by default.** Nothing appears in the inbox until you turn it on.
- **One card per thread.** The card uses a per-thread dedup key (`supermail-mail-<threadId>`),
  so a second email on the same thread updates the existing card rather than adding a new one.
- **Reply-to-sender only.** The reply goes to the last sender of the thread — never reply-all,
  never to an earlier participant. The main process resolves the sender at send time; a missing
  sender address is a clear error before any send attempt.
- **Counts toward "Needs You".** Email inbox items use `sourceKind: 'agent'` and therefore
  increment the Needs You badge on the project, the same as any other inbox item. This is the
  owner's deliberate choice (2026-07-31).
- **Reply is desktop-only.** The `SUPERMAIL_SEND_REPLY` IPC channel is in the web/mobile
  bridge's deny list — a paired phone cannot trigger a reply (the send path holds a credential
  that must never leave the main process).
- **No toast on arrival.** The inbox badge increments silently; a toast fires only when a reply
  is sent successfully.
- **Dedup note.** Archiving the card does not clear the dedup key — if a new email arrives on
  the same thread, the card is recreated (upsert). The user's previous reply text is not
  restored on the new card.

### How to turn it on

**Settings → Email & Summaries → Emails in inbox** toggle. Requires Supermail to be enabled.

- **Setting key:** `supermailEmailsInInbox`
- **Default:** `false` (off)
- Takes effect on the next incoming email; existing mail is not backfilled.

### How replies are sent

Submitting the inline reply form dispatches `IPC.SUPERMAIL_SEND_REPLY` to the main process,
which fetches the thread to resolve the last sender's address, HTML-escapes your plain-text
body, prepends "Re: " once (idempotent), and POSTs the reply to the Supermail backend. The
JWT credential never reaches the renderer.

## Related

- [supermail.md](supermail.md) — the full Supermail email client reference, including layout,
  filters, split inbox, and sidebar modes.
- [supermail-ai-filtering.md](supermail-ai-filtering.md) — AI-powered email triage (a separate
  feature).
- Contract: `.claude/memory/contracts/supermail-inbox-reply-contract.md` — invariants,
  guards, and tests for the inbox-email / reply feature.
