Typography

Schibsted Grotesk 800 cuts the mark; Instrument Sans carries the interface. The apps keep system faces (SF / Roboto) on purpose.

Web faces

Schibsted Grotesk

Display, 400–900 variable

SchibstedGrotesk.woff2

Instrument Sans

Body, 400–700

InstrumentSans.woff2

Web type scale

Display · 3rem / 800She picks up. The board fills itself.
Heading · 1.6rem / 600She picks up. The board fills itself.
Body · 1rem / 400She picks up. The board fills itself.
Small · .85rem / 400She picks up. The board fills itself.
Label · .72rem / 500She picks up. The board fills itself.

The apps keep system faces

Deliberate 2026-08-16 decision: the native and RN apps use SF on iOS, Roboto on Android, the system-ui stack on web app surfaces. The RN token export (dist/ts/tokens.ts) carries weights and sizes, never family names. Web marketing and admin surfaces use the two faces above, served locally.

Spacing

4pt grid: hairline 4 · tight 8 · snug 12 · regular 16 · roomy 24 · generous 32. Card radius 14 in the RN app; shadcn web keeps stock --radius: 0.625rem.

Screen & list anatomy (phone)

Measured 2026-09-02 against the retired native iOS app and the Airmond One mockup; every value is a layout.* token in dist/ts/tokens.ts, so a screen never carries its own number.

TokenValueRule
layout.gutter16Horizontal page gutter on every phone screen. Cards are the screen width minus two gutters.
layout.cardPadding16Inner padding of a grouped card; list rows sit inside it.
layout.listRowPaddingVertical12Vertical padding of a grouped-list row. Title + one caption = 66pt pitch; title + two-line caption = 82pt, the native numbers.
layout.listGlyphSlot28Width reserved for a row's leading glyph, centred.
layout.listRowGap12Gap between glyph slot and text column (and before the trailing chevron).
layout.listDividerInset40Where a grouped-list hairline starts, from the card's content edge: slot + gap. From the screen edge that is 16 + 16 + 40 = 72, native's exact inset.
layout.sectionTitleGap8Container gap between a sentence-case section title and its card (the heading's line-height adds ~3pt; reads as native's 11).
layout.sectionGap24Rhythm between titled sections.
layout.icon.row / tab / inline24 / 28 / 18Icon box by role. Stroke glyphs sit inside a 24-grid with padding, so the boxes run a step above native's SF Symbol ink (≈22pt in rows, ≈25pt in the tab bar).
layout.iconStroke.regular / emphasis2 / 2.4One stroke weight for the family; emphasis only on the selected tab.
Section titles are sentence case at the heading size in muted slate ("Reach her", "What she's learned") on every list screen — never an uppercase eyebrow. Eyebrows belong inside cards (a reference card's kind line), not above them.

Marketing display steps (2026-09-02)

The landing page needed two steps above the web scale's Display and two below the tile: they ship as --type-* variables and typographyMarketing in tokens.ts. Marketing web only. The app's list screens keep their own scales (typography, typographyWide) and never carry an uppercase eyebrow above a card.

StepSize / phoneLine heightWeightTrackingFace
--type-h156 / 401.04700-0.025emSchibsted Grotesk
--type-h242 / 301.1700-0.02emSchibsted Grotesk
--type-tile-title19 / 191.25700-0.01emSchibsted Grotesk
--type-label11 / 111.26000.08em, uppercase, in --confirmInstrument Sans
H1, 56 (40 on a phone)

A personal assistant you can just call.

H2, 42 (30)

What she does, day to day.

Tile title, 19, under the 11px label
Meetings

Add her to the invite

Section rhythm

--section-gap 112px between sections on a desk, --section-gap-phone 80px on a phone; --content-width 1120px on a 1440px canvas; --gutter-phone 16px. Radii: --radius-card 16px for tiles, 18 for the sign-up card, --radius-band 24px for large bands. --shadow-float 0 18px 50px rgba(24, 34, 43, 0.16) for the one floating element per screen.