← Back to Index
Page Template
Figma: template · main view-interior
page-template tier
Updated: 2026-06-26
Audited: 2026-06-26
Structural scaffold shared by every screen — top nav clearance, content area padding, bottom nav safe area, and interior sub-page controls bar
Confirmed across all 11 Figma screens: Home 4099:5229, KCM 4562:7572, Notifications 5060:14989, Internal Comms 4565:9260, Member Resources 4870:10671, Advocacy 4877:11274, Favorites 5287:15227, Flight Finder 4713:25117, MEC 4684:7914, Search 4951:11891, Airline Policies 4713:25321 · file key: psH738AqHDxuMyFm897f9r
Every page in the app uses this scaffold. The three-layer stack — fixed top nav,
scrollable content area, fixed bottom nav — is identical across all 11 audited screens.
Only the content area differs between a root section (no back button, content starts
immediately) and an interior sub-page (adds a 38px nav-controls bar with back button +
centered title + optional right icon). Agents building any page must use these measurements.
Live Preview
Root section
(Home, MEC, Favorites…)
Interior sub-page
(KCM, Airline Policies, Comms…)
Spacing Diagram
Top nav (white · drop-shadow 0 0 3.5px rgba(0,0,0,0.1))
120 px from top → content starts
↕ 120px top-nav clearance (pt-120px on content area)
status bar 54px · nav items ~34px · bottom overlap ~32px
24px px
Content area — bg: #f5f7fa · px: 24px (--medium) · gap: 10px between sections
Section / component slot (gap: 10px ↕)
Section / component slot
Section / component slot
↕ pb-96px on slot-main feed — scroll clearance above bottom nav
96px scroll buffer (slot-main feed pb)
↕ Bottom nav starts at y=770px (of 852px frame) → 82px height incl. safe area
Bottom nav (bg: #05273e · px: 16px --page-margins · pb: 8px --tiny)
5 nav items
Design Tokens
Frame Dimensions (iPhone 14 design target)
Content area width (available)
393 − 2×24 = 345 px
Top nav total clearance
120 px (status bar + nav bar height)
Bottom nav top edge
y = 770 px
Bottom nav height
82 px (852 − 770)
Visible scroll viewport
852 − 120 − 82 = 650 px
Content Area
Background
bg-no-img #f5f7fa (surface/page)
Padding-top
120 px — clears top nav completely
Padding-x (side margins)
24 px (--medium / --page-content-margins)
Padding-bottom
8 px (--tiny)
Gap between sections
10 px
Scroll clearance (slot-main feed pb)
96 px — keeps last content item above bottom nav
Overflow
overflow-x: clip · overflow-y: auto
Top Nav
Background
white/500 #ffffff
Drop shadow
0px 0px 3.5px rgba(0,0,0,0.1)
Padding-left
16 px (--xsmall)
Padding-right
16 px (--page-margins)
Padding-top
44 px (iOS status bar inset)
Nav item padding
px-8px py-16px (--tiny / --xsmall)
Position
absolute · top:0 · left:0 · z-index above content
Bottom Nav
Background
surface/brand #05273e
Padding-x
16 px (--page-margins)
Padding-bottom
8 px (--tiny) — home indicator clearance
Position
absolute · top:770px
Nav items
5 items · gap: 18px · icon 28px + label 12px
Nav label font
Futura PT Medium 12px · uppercase · white
Nav item gap (icon→label)
8 px (--tiny)
Spacing Token System
All spacing in the app is expressed via named tokens. Never use a raw pixel value when a token exists.
| Token name | Value | Where used |
--none | 0 px | Explicit zero gaps (e.g. pt-[var(--none,0px)] on template root) |
--tiny | 8 px | Nav item icon→label gap; content area pb; bottom nav pb; favorites wrapper margin; section gap fallback |
--xsmall | 16 px | Top nav pl; nav item px and py; card content pt |
--small | 16 px | Alias of xsmall in some contexts |
--medium | 24 px | Primary content horizontal padding — main view-interior px; card text wrapper px |
--page-margins | 16 px | Top nav pr; bottom nav px — the outermost edge margin |
--buttons-and-form-fields/horizontal-padding | 16 px | All button and form field horizontal padding |
--buttons-and-form-fields/vertical-padding | 16 px | All button and form field vertical padding |
--buttons-and-form-fields/icon-text-gap | 12 px | Gap between icon and text in any button or form field |
Template Variants
| Variant | Description | Nav-controls bar | Screens |
| Root section |
Primary tab destination; content fills directly after top-nav clearance |
None |
Home, MEC (My MEC), Favorites, Notifications, Flight Finder, FTDT |
| Interior sub-page |
Drilled into from a root section or list item; has back navigation |
38px bar: ‹ back · centered title · optional right icon |
KCM, Internal Comms, Member Resources, Advocacy, Airline Policies, Search |
Interior Nav-Controls Bar
Interior sub-pages prepend a 38px nav-controls bar inside the content area (inside the 24px side padding). It sits between pt-120px clearance and the first content item.
Dimensions
Total height
38 px (h-38px)
Border-bottom
1 px solid border/subtle #e3e3e3
Back button size
22×22 px (i-back icon)
Right icon size
22×22 px (optional — e.g. search mag)
Width
full width (inherits 24px side margins from content area)
Typography — Page Title
Font family
Afacad SemiBold
Font size
20 px (Body/L — font-size/body/l)
Color
text/primary #05273e
Alignment
center (title spans full width · back and right icon offset)
Layer Tree
Root section template
└── template · 393×852px · flex-col · overflow-x:clip overflow-y:auto
├── main view-interior · bg:#f5f7fa · flex-col · pt-120px · px-24px · pb-8px · gap-10px · flex:1
│ └── slot-main feed · flex-col · pb-96px (scroll buffer) · [page content here]
├── topNav · absolute · top:0 · left:0 · white · shadow · z-index:10 · w-393px
├── status bar · absolute · top:0 · 393px wide · h-54px
└── navBar-bottom · absolute · top:770px · left:0 · w-393px · bg:#05273e · px-16px · pb-8px
Interior sub-page template (adds nav-controls)
└── template · 393×852px · flex-col · overflow-x:clip overflow-y:auto
├── main view-interior · bg:#f5f7fa · flex-col · pt-120px · px-24px · pb-8px · gap-10px · flex:1
│ ├── nav controls · flex-row · h-38px · pb-4px · border-b-1px:#e3e3e3 · shrink-0
│ │ ├── [i-back] · 22×22px · left side
│ │ ├── [Page Title] · Afacad SemiBold 20px · center · flex:1
│ │ └── [right icon] · 22×22px · optional (search, filter, etc.)
│ └── slot-main feed · flex-col · pb-96px · [page content here]
├── topNav · absolute · top:0 · white · shadow · z-index:10
├── status bar · absolute · top:0
└── navBar-bottom · absolute · top:770px · bg:#05273e · px-16px · pb-8px
Developer Notes
- Top nav is absolutely positioned, not a sticky element: The
pt-120px on main view-interior is a hard offset that clears the nav. The nav itself is absolute; top:0 and scrolls with the page frame (not with content). This means the content area scrolls independently under the nav.
- The 120px figure is composite: iOS status bar (~54px) + nav items row (icon 22px + py-16px×2 = 54px) + a small overlap buffer = ~120px. This is baked into the design system — do not try to compute it dynamically; use
pt-120px.
- 96px scroll buffer is not the bottom nav height: The bottom nav is 82px (770→852). The 96px gives 14px of breathing room so the last item is not flush against the nav. Always apply
pb-96px to the innermost content slot (slot-main feed), not to the content area wrapper.
- Side margins are 24px, not 16px: The page content margin is
--medium = 24px. The --page-margins = 16px token is only for the top nav right padding and the bottom nav horizontal padding — the outermost chrome edges. Do not use 16px for content margins.
- Nav-controls bar is inside the 24px side margins: The bar inherits its width from
main view-interior's px-24px. The back button and right icon do not extend to the screen edge — they sit within the 345px content column.
- The background is #f5f7fa, not white: This is the
bg-no-img token. Individual components (cards, form fields) render white backgrounds on top of it, creating visual depth. Never set the page background to white.
- Gap between sections is 10px: The
gap-10px on main view-interior applies between direct children (content sections). Internal gaps within a section are governed by that section's own rules — do not add extra margin-top to the first child.
- Implementation gated: The Blazor Hybrid page scaffold implementation waits on Epic AB#2087 (Presentation Extraction). These measurements are the confirmed design baseline.
Blazor Page Structure (target)
Every page Razor component in ALPAMobile.HybridUi will wrap its content in the page template layout. The shared chrome (top nav, bottom nav) lives in a layout component; each page supplies only its slot-main content.
Root section page
@* Home.razor — root section: no nav-controls bar *@
@layout AlpaPageLayout
<div class="alpa-page__feed">
<!-- Components go here — carousel, cards, etc. -->
<AlpaCarousel Vm="@newAndNotable" />
<AlpaCarousel Vm="@feed" />
</div>
Interior sub-page
@* AirlinePolicies.razor — interior sub-page: nav-controls bar + content *@
@layout AlpaPageLayout
<AlpaNavControls Title="Airline Policies"
ShowSearch="true"
OnBack="@NavigateBack" />
<div class="alpa-page__feed">
@foreach (var airline in Airlines)
{
<AlpaFormField Vm="@airline" OnNavTap="@NavigateToPolicy" />
}
</div>
CSS Class Reference (target)
These classes will live in ALPAMobile.HybridUi/wwwroot/css/alpa-layout.css.
| Class | Element | Key rules |
.alpa-page | Page root wrapper | position:relative; width:393px; height:852px; overflow-x:clip; overflow-y:auto |
.alpa-page__content | Main content area (main view-interior) | background:#f5f7fa; display:flex; flex-direction:column; gap:10px; flex:1; padding-top:120px; padding-left:24px; padding-right:24px; padding-bottom:8px; min-height:100% |
.alpa-page__feed | Scrollable content slot (slot-main feed) | display:flex; flex-direction:column; padding-bottom:96px — always the direct child of .alpa-page__content |
.alpa-top-nav | Fixed top navigation bar | position:absolute; top:0; left:0; width:100%; background:white; box-shadow:0 0 3.5px rgba(0,0,0,0.1); padding-top:44px; padding-left:16px; padding-right:16px; display:flex; align-items:center; justify-content:space-between; z-index:10 |
.alpa-bottom-nav | Fixed bottom navigation bar | position:absolute; top:770px; left:0; width:100%; background:#05273e; display:flex; align-items:center; justify-content:space-around; padding:0 16px 8px |
.alpa-nav-controls | Interior sub-page header bar | display:flex; align-items:center; height:38px; padding-bottom:4px; border-bottom:1px solid #e3e3e3; flex-shrink:0; gap:0; width:100% |
.alpa-nav-controls__back | Back button icon | width:22px; height:22px; cursor:pointer; flex-shrink:0 |
.alpa-nav-controls__title | Centered page title | flex:1; text-align:center; font-family:var(--font-family/alt); font-weight:600; font-size:20px; color:var(--text-primary,#05273e); line-height:1.3 |
.alpa-nav-controls__action | Optional right icon (search, filter) | width:22px; height:22px; flex-shrink:0 |