owEYzHf7FrHRvWC2u82UOl (ALPA mobile app) — typography read from Figma variable definitions via get_variable_defs, 2026-07-30. Every node id cited below was resolved against that file on that date. Font-file facts read directly from the shipped binaries' name and OS/2 tables. Render behaviour measured on the iOS simulator in the Blazor WebView.Read from the binaries themselves, not from filenames — the filename is not authoritative and had previously been recorded incorrectly.
| File | Family (name ID 1) | Subfamily (name ID 2) | usWeightClass | Path |
|---|---|---|---|---|
FuturaPT-Book.otf | Futura PT | Book | 400 | ALPAMobile.Presentation/wwwroot/fonts/ |
FuturaPT-Bold.otf | Futura PT | Bold | 700 | ALPAMobile.Presentation/wwwroot/fonts/ |
Registered via @font-face in alpa-components.css (two rules, one per weight). The native side registers the .ttf equivalents in MauiProgram.cs as FuturaPTBook / FuturaPTBold.
The design system defines 8 type styles across 4 families. Family is itself tokenised for three roles; Body and Button carry their family as a literal inside the type style rather than as a token.
| Type style | Family | Style | Weight | Size | Line height | Letter spacing |
|---|---|---|---|---|---|---|
Display/M | Lora (token Font Family/Heading) | SemiBold | 600 (token Font Weight/Heading) | 24 | 1.2 | 0 |
Display/S | Lora (token Font Family/Heading) | SemiBold | 600 | 20 | 1.2 | 0 |
Body/Body L | Futura (literal) | Medium | 500 | 20 | 1.3 | 0 |
Body/Body M | Futura (literal) | Medium | 500 | 18 | 1.2 | 0 |
Body/Body S | Futura (literal) | Medium | 500 | 12 | 1.2 | 0 |
Other/Eyebrow | Inter (token Font Family/Eyebrow) | Bold | 700 | 12 | 1.4 | 5 % |
Other/Caption | Inter (token Font Family/Caption) | Regular | 400 (token Font Weight/Caption) | 14 | 1.5 | 0 |
Other/Button | League Spartan (literal) | Regular | 400 | 15 | 1.0 | 4 % |
Line heights are ratios and letter spacing is a percentage. Both reproduce the values observed in Figma Dev Mode exactly: 20 × 1.2 = 24, 18 × 1.2 = 21.6, 12 × 1.4 = 16.8; 5 % of 12px = 0.6px.
Each type style below was read from the variable definitions attached to these component nodes in owEYzHf7FrHRvWC2u82UOl.
| Node id | Component | Type styles / font variables observed |
|---|---|---|
4033:1436 | card-lg | Font Family/Heading=Lora · Font Weight/Heading=600 · Display/S · Font Family/Eyebrow=Inter · Other/Eyebrow · Body/Body M |
4153:8817 | profile | Display/M · Display/S · Body/Body L · Body/Body M · Other/Button (League Spartan) |
4718:11125 | card-md | Other/Eyebrow · Display/S · Body/Body M |
4864:31901 | card-notification | Other/Eyebrow · Display/S · Body/Body L |
5172:15482 | listy card generic | Font Family/Caption=Inter · Font Weight/Caption=400 · Other/Caption · Body/Body M |
4047:4230 | horizontal scrolling feed | Display/S · Body/Body M · Other/Eyebrow |
4737:13038 | card-btn | Body/Body M |
5512:12925 | banner | Body/Body S |
4245:5754 | button pill | Other/Button |
4361:8479 | tab group | Other/Button |
4450:9884 | flight card-saved & recent searches | Other/Button |
4537:14830 | progress bar & labels | Body/Body M |
Queried and returned no typography variables (size tokens only, or colour/spacing only): 4128:7717 button-sm · 4128:7690 profile info block · 4555:7483 flight segment card · 4596:11818 section title · 4038:1037 navBar-bottom · 5251:15088 button link.
| Figma declares | Weight | Maps to | Rationale |
|---|---|---|---|
Lora SemiBold — Display/M, Display/S | 600 | Futura PT Bold 700 | Nearest available above. Title emphasis is carried by weight once the serif is gone. |
Futura Medium — Body L, Body M, Body S | 500 | Futura PT Book 400 | Nearest available below. Bold would overshoot a light emphasis. |
Inter Bold — Other/Eyebrow | 700 | Futura PT Bold 700 | Exact weight match. |
Inter Regular — Other/Caption | 400 | Futura PT Book 400 | Exact weight match. |
League Spartan Regular — Other/Button | 400 | Futura PT Book 400 | Exact weight match. |
All values belong in alpa-components.css and must route through the family tokens (--font-heading-family, --font-body-family, --alpa-eyebrow). No inline style= attributes and no literal family stacks in component rules.
Measured on device by rendering identical text at each weight in Futura PT and comparing rendered widths:
| Requested weight | Rendered width | Face actually used |
|---|---|---|
| 300 · 400 · 500 | 516.960 px | Book 400 |
| 600 · 700 · 800 · 900 | 579.400 px | Bold 700 |
The browser already applies exactly this mapping through CSS font matching. Writing it into the stylesheet makes explicit what already happens at render time — it does not change how anything looks.
Verified against the My MEC card, whose three roles exercise three different families.
| Role | Figma | Mapped | Remains distinct by |
|---|---|---|---|
| Eyebrow | Inter Bold 700 · 12px · uppercase · ls 0.6px · opacity 0.5 | Bold 700 | size, casing, letter-spacing, secondary colour |
| Card title | Lora SemiBold 600 · 20 / 24 | Bold 700 | 20px, primary colour |
| Body | Futura Medium 500 · 18 / 21.6 | Book 400 | weight contrast against the title |
Serif/sans contrast is lost. The title-versus-body hierarchy survives, re-expressed as Bold-versus-Book. Title and eyebrow both land on Bold 700 but stay clearly separated by size, casing and colour.
| Family | Where | Actually renders? |
|---|---|---|
| Inter — Google Fonts | --alpa-eyebrow, consumed by 34 rules | Yes — eyebrow text is currently drawn in a non-provided typeface |
| Georgia, serif — literal | .alpa-radar-title | Yes |
| "Futura LT Pro" — literal | .alpa-profile-label, .alpa-profile-nav-row-label | No — falls through to Futura PT |
| Lora — Google Fonts | fetched; referenced by zero rules | No — also fails to resolve (document.fonts.check = false) |
| Roboto — Google Fonts | fetched; unreferenced | No |
ALPAMobile/wwwroot/index.html:13,15 and home.html:17 fetch Lora, Inter and Roboto from fonts.googleapis.com at runtime. Typography therefore depends on connectivity, and the app makes third-party requests on launch. Futura PT is correctly self-hosted via @font-face.
Declarations asking for a weight with no corresponding file. Each already resolves to Book 400 or Bold 700 by the rule in §3.
| File | font-weight declarations | Off-palette |
|---|---|---|
ALPAMobile.Presentation/wwwroot/css/alpa-components.css | 133 | 71 |
ALPAMobile/wwwroot/css/ftdt.css | 46 | 36 |
ALPAMobile/wwwroot/css/widget.css | 7 | 2 |
| Total | 186 | 109 |
The /dev/font-specimen demo ladder is excluded from these counts — it declares 300/500/600/800 deliberately, to demonstrate the gap.
| Change | Visual impact |
|---|---|
| Normalise the 109 weight declarations | None — proven by measurement (§3.1) |
| Drop the Lora + Roboto fetches | None — unreferenced |
Route the literal Futura LT Pro stacks through tokens | None — already falls back |
| Drop Inter | Visible — 34 eyebrow rules change typeface |
.alpa-radar-title Georgia → token | Visible — 1 rule |
docs/ui-refresh-1821/figma-component-specs.json records _resync.source.file = psH738AqHDxuMyFm897f9r, revision 2026-06-17. The working file is owEYzHf7FrHRvWC2u82UOl. Every typography claim derived from that capture is therefore unverified against current design.
25 docs carry family claims inherited from that capture — Lora ×51, Inter ×47, Futura LT Pro ×23, SF Pro ×2, Hind ×3 (counts exclude each document's own <style> block, so these are content assertions, not page styling). Highest-authority affected: design-tokens.html, design-questions.html, home-page-audit.html, the card-* and button-* specs, list-component.html, naming-decisions-record.html.
The census found no Futura LT Pro and no SF Pro anywhere in the working file's typography. Both should be treated as obsolete in the documentation.
This retires an earlier concern: the docs' apparent "two Futura cuts in one design" is a stale-capture artifact, not a real design inconsistency. All three components the old capture attributed to Futura LT Pro — search bar, mobile nav, mobile hero — no longer resolve at their captured node ids.
League Spartan is absent from every document in /docs, yet it is the current, live font for every button in the design system (Other/Button, five components in §2.1). The documentation gap is real even though the mapping outcome is unchanged.
| Captured node id | Component |
|---|---|
4055:6042 | search bar |
4021:668 | mobile nav |
4055:5564 | mobile hero |
4038:221 | card-sm |
5452:679 | flight card-og |
4864:32242 | topNav |
5452:434 | card-button |
flight card-og is the counter-example: captured id 5452:679 is invalid, yet a frame named flight card-og resolves at 4713:19868. Specs derived from the dead ids should be re-sourced before being relied on, not assumed removed.
Body/Body M (18px) is the page default, settling which source is authoritative. design-tokens.html has been corrected: body L 16→20px, body M 14→18px, body line-height 1.6→1.2, button 12→15px, plus a missing --font-caption-size (14px). --font-title-lg-size (28px) remains unconfirmed — see the last row. Design also answered the paired scaling question (DQ-21): the app should honour the OS text-size setting, tracked on AB#2391.
design-tokens.html predated this census and its typography scale did not correspond to the current type-style set. The differences found are below.
| design-tokens.html | Value | Nearest census style | Value | Status |
|---|---|---|---|---|
--font-eyebrow-size / -weight / -ls | 12px / 700 / 0.05em | Other/Eyebrow | 12 / 700 / 5 % | matches |
--font-title-md-size | 20px | Display/S | 20 | matches |
--font-body-sm-size | 12px | Body/Body S | 12 | matches |
--font-body-md-size | 14px | Body/Body M | 18 | differs |
--font-body-lg-size | 16px | Body/Body L | 20 | differs |
--font-body-lh | 1.6 | Body/* | 1.2 – 1.3 | differs |
--font-button-size | 12px | Other/Button | 15 | differs |
--font-title-lg-size | 28px | Display/M = 24 | 24 | unconfirmed |
The last row is marked unconfirmed rather than differing: a larger display style (Display/L or above) may exist that this census did not surface, in which case 28px may map to it correctly.
Typography was read from Figma variable definitions (get_variable_defs), which are reachable remotely and return the design system's type styles directly. That makes this census authoritative for the type-style set.
21223:222 is unreachable — the My MEC card the mapping was validated against. Its id postdates the snapshot the connector serves, so its values were supplied from Figma Dev Mode output rather than read directly. They agree with the census exactly.get_design_context requires the page open in the Figma desktop app; it returns "invalid node selection" for nodes not visible on canvas, so it could not be used for a bulk sweep.list_file_components_for_code_connect requires a Dev or Full seat on an Organization/Enterprise plan.0:1 💅 Thumbnail, so components were reached by node id rather than by walking pages.In scope for this document — the mapping (§3), the census (§2), and the record of code and documentation departures (§4, §5).
Not in scope — applying the mapping. No CSS has been changed. Weight normalisation, Inter/Georgia removal, the design-tokens.html scale reconciliation, and correcting the 25 affected docs are follow-on work.