Pelote
FR
Rules4 min

How a screen organises itself according to the available width. The thresholds follow the Material 3 window size classes; vps-admin is the reference implementation.

Width classes

Class Width Navigation Content
Compact under 600 px (phone) bottom bar, 3 to 5 destinations, the rest in a "More" sheet one column, 16px margins
Medium 600 to 839 px (portrait tablet, open fold) left rail (96 px) one wide column or two panes
Expanded 840 to 1199 px left rail two panes (list and detail) or a card grid
Large 1200 to 1499 px left rail full-width bento (overview) or content up to 1340 px
Extra-large 1500 px and above left rail full-width bento, or content up to 1340 px and a support pane on the right (300px widget bar)
  • The breakpoint is a choice: 600 px (M3 window size classes) or 760 px when navigation has more than four destinations or the content needs width. Both are accepted, but pick one per app; vps-admin and the Pelote site use 760 px.
  • Never a bottom bar on desktop, never a rail on a phone in portrait.
  • The snackbar and FABs sit above the bottom bar; with the rail, the snackbar centres on the content area.

Width on desktop: no dead space

The rule is not "never use the full width" but "never leave dead space". Two ways, depending on what the screen shows.

1. Full-width bento: when the screen is an overview

Dashboard, home, profile, project page: the content is a collection of modules.

  • The grid takes the whole width (24 to 32px side margins) with tiles of different sizes according to importance: the main metric in 2×2, charts in 2×1, small values in 1×1.
  • A 4-column grid in expanded, 6 in large, 8 to 12 in extra-large; tiles keep a column width between 160 and 320px and change size rather than stretch.
  • Rows fill without a hole: choose sizes so the grid lands exactly (grid-auto-flow: dense).
  • Text inside a tile stays short; a module with long text opens a detail.

2. Bounded width + pane: when reading or editing

List, detail, form, document, settings: the main content reads continuously.

  • Maximum width: body text 65 to 70 characters, form 640 px, list or table 1340 px (vps-admin).
  • The remaining space holds a useful pane that does not repeat the content: widget bar (vps-admin, from 1500 px, chosen and collapsible by the person), detail pane next to a list, preview next to a form.
  • If nothing useful can fill the space, the content centres. Never fill with decor.

In every case

  • Never identical cards stretched over 2560 px: either they change size (bento), or the content is bounded.
  • The decorative background (portfolio dot grid, shapes) may take the full width.
  • An app can mix both: vps-admin's overview can switch to a full-width bento, its detail pages keep the bounded width and the widget bar.

Foldable screens

  • Closed fold: compact, like a phone.
  • Open fold, flat (about 700 to 900 px): medium or expanded. Left rail and two panes, one on each side of the hinge.
  • Hinge: no text, button or important image crosses it. Web: @media (horizontal-viewport-segments: 2) and env(viewport-segment-width 0 0) to place the panes on either side. Flutter: MediaQuery.displayFeatures and DisplayFeatureSubScreen.
  • Tabletop posture (half folded, horizontal): content to read on top, controls at the bottom, exactly like the 3DS two-screen pattern (pz-dual in Plaza).
  • Moving from one posture to another keeps state: no reload, the selection stays selected.

Empty space

  • A screen with no content yet shows an empty state that guides (what to do, how long it takes), never a large white area.
  • In a card, no short element alone on its line (see UX rules).
  • In a grid, cards in the same row have the same content height; no empty cell dangling at the end of the grid: the column adapts to the number of items.

Height and scrolling

  • The navigation bar (rail or bottom bar) stays fixed; the content scrolls.
  • The support pane scrolls independently (vps-admin: widget bar in position: sticky, screen height).
  • On mobile, respect the safe areas (env(safe-area-inset-*)): the bottom bar adds the bottom inset to its padding.

More

TokensAssetsLicense GitHub

Appearance

The choice applies immediately and stays on this device.

Mode
Theme colour Every role is regenerated from this source colour.
Style The material changes, components and roles stay the same.
Material YouOn the web, the wallpaper colour is not available. Pick a source colour above; in Android 12+ apps, Material You follows the wallpaper.