Skip to content
Fleetline

Application shell

Usage

The shell is the frame every signed-in Fleetline screen sits in. It only places components; it adds no colors, borders or type of its own.

Anatomy

  1. Skip link — a.skip-link[href="#main"], first in the body
  2. Header — header.top-nav.top-nav--sticky.app-shell__header (banner landmark)
  3. Side navigation — nav.side-nav.app-shell__nav with its own aria-label (sidebar variant, ≥ 64rem)
  4. Main — main#main.app-shell__main[tabindex=-1]: page header, then content
  5. Aside (optional) — aside.app-shell__aside for related, non-essential content
  6. Footer (optional) — footer.app-shell__footer: version, status link

Examples

Each composition renders in a fixed-height frame that scrolls like a browser window. The shell reacts to its own width (container query), so the frames show the real breakpoints.

Application shell

variant:sidebar — dispatch dashboard

Fleetline
Vehicles on road
94of 128

Up 6 vs yesterday

Overdue services
7

Up 2 since Monday

Oldest: Truck TR-077, 9 days

Open work orders
23

Same as last week

Today's work orders

Sorted by due time

Work orderVehicleMechanicStatusDue
WO-4185Truck TR-077Volvo FH, 312,940 kmIdris OkaforOverdue
WO-4182Van KX-219Ford Transit, 84,212 kmMarta QuinteroIn progress
WO-4191Van KX-224Mercedes Sprinter, 51,006 kmLena BrandtWaiting for parts
WO-4193Pickup PU-012Toyota Hilux, 140,377 kmMarta QuinteroDone

Desktop: header + side nav + main. Narrow the window below 64rem and the side nav steps aside for the top-nav Menu.

variant:top-nav-only — mechanic's job list with aside

Jobs assigned to Lena Brandt today
JobVehicleStatusLabour (h)
Brake pads, front axleVan KX-224Waiting for parts1.25
60,000 km serviceVan KX-231Not started3.0
Tachograph checkTruck TR-081Not started0.75

No side nav: the main column is capped at the extra-large container; the aside sits beside main from 64rem and drops below it on narrower screens.

variant:mobile — 24rem frame

Fleetline
Vehicles on road
94of 128
Overdue services
7

Up 2 since Monday

WO-4185 · Truck TR-077

Idris Okafor · due 08:00

Overdue

WO-4182 · Van KX-219

Marta Quintero · due 11:30

In progress

Below 48rem the top nav folds links and search behind Menu; the side nav is hidden and work orders render as cards instead of a wide table.

<body>
  <a class="skip-link" href="#main">Skip to main content</a>
  <div class="app-shell">
    <header class="top-nav top-nav--sticky app-shell__header">…</header>
    <div class="app-shell__body">
      <nav class="side-nav app-shell__nav" aria-label="Dispatch">…</nav>
      <main class="app-shell__main" id="main" tabindex="-1">
        <header class="page-header">…<h1 class="page-header__title">Dispatch board</h1>…</header>
        …
      </main>
      <aside class="app-shell__aside" aria-label="Parts arriving today">…</aside>   <!-- optional -->
    </div>
    <footer class="app-shell__footer">…</footer>
  </div>
</body>

<!-- Top-nav only: add .app-shell--top-nav-only and leave out the side nav. -->

API

HookValuesPurpose
.app-shellblockGrid rows header / body / footer; size container for the breakpoints
.app-shell__bodypartColumns nav / main / aside (aside column appears when an .app-shell__aside child exists)
.app-shell__header | __nav | __main | __aside | __footerpartsGrid placement only, added next to the component class
.app-shell--top-nav-onlymodifierNo side nav; main capped at --size-container-xl
--app-shell-min-block-sizecustom propertyMinimum height (default 100dvh)
64rem / 40remcontainer breakpointsSide nav hides below lg; tighter gutters below sm

Do and don't

Do let the document scroll and keep only the top nav sticky, with html { scroll-padding-top } set to its height.
Don't make main a fixed-height scroll box inside the viewport: it breaks zoom, find-in-page and mobile address-bar collapse.

Accessibility

Landmarks in reading order
ElementLandmarkNotes
a.skip-link—First tab stop; moves focus to #main (which has tabindex="-1")
header.top-navbannerOnly when it is a direct child of body (not inside main)
nav.top-nav__nav, nav.side-navnavigationEach with a distinct aria-label ("Main", "Dispatch")
main#mainmainExactly one per document; holds the page's h1
asidecomplementaryName it with aria-labelledby
footercontentinfoOnly when a direct child of body

Source order equals visual and tab order in every variant (no order or reversed grid areas). The sticky top nav needs scroll-padding-top so focused elements are never hidden under it (WCAG 2.4.11). At 320px wide and 400% zoom the shell is a single column with no horizontal scroll.

Tokens

Custom propertyPurpose
--space-4, --space-6, --space-8, --space-10Main gutters and gap between page sections
--size-container-xlMax width of main in the top-nav-only variant
--breakpoint-lg, --breakpoint-smCopied as literal 64rem / 40rem in the container queries