School’s Out design system
Foundations

Layout

The page grid, the page’s widths, spacing, and the pieces that place things on them.

Layout grid

Pages sit on fluid columns: 4 on phones, 8 from 768px, and 12 from 1200px of the page’s own width.

Compact and medium, under 768px
Expanded, 768px to 1199px
Wide, from 1200px
Show details
  • Turn on the grid overlay with Shift+G on any page, here or on the deployed site: it draws each page frame’s columns, gutters, margins, and the 4px baseline from the values the page lays out with.
  • To try other values, Shift+T opens the grid tuner on any page (October 15): the tile width, columns, gutters, margins, and maximum widths of the fluid, page, and column grids, applied live to the real pages with the overlay on. Copy link shares the experiment (it lives in the address as ?grid=, and in the tab until Reset); Copy changes lists what to edit in the code to keep it (packages/tokens/layout.css and layout.ts).
  • After Cosmos (cosmos.so): the columns stretch with the window. From Last design’s business page (Hannah, October 1).
  • Four size classes, measured on the page’s container rather than the window, so a page beside the docked assistant gets the grid for the room it has (October 14, the grid RFC): compact and medium take 4 columns, 12px gutters, and 24px margins; expanded (from 768px) 8 columns, 16px gutters, and 48px margins; wide (from 1200px) 12 columns, 24px gutters, and 240px margins.
  • Three page widths on one set of columns (Hannah, October 21 to 26, the column review), so every page lines up with the bar: the fluid grid, columns of at least 88px with 24px gutters and 24px margins at wide, two to an activity tile, the content stopping at 1680px and centering past it: 12 columns at 1440, with 212px tiles, and 14 from 1592px. Wide takes every column, for Explore alone, the one page with filters beside its tiles (1392px at 1440 with five tiles beside the filters, 1680px on a 1728px screen with six). Standard takes the middle twelve at most, for the activity page, business pages, Plans, and Collections (every column at 1440, 1436px at 1728), so on a 1440 laptop wide and standard are the same. Narrow takes the middle eight (Feed, Notifications, Settings, profiles, bookings, forms: 920px at 1440, 950px at 1728). Paragraphs stop at the measure, 52ch, about 66 to 73 characters, whatever the page width. Until October 21 a column was one 264px tile, and pages about one thing had six columns of their own on a 1312px page.
  • Two spacings across (Hannah and Andy, October 26, after 40px gutters made Explore too airy): the gutter, 24px on web, between columns and the tiles on them (Explore, Collections, shelves, saved tiles); and the region gap, 40px on web, between a page’s side-by-side regions (the planner’s welcome beside its updates, the activity page’s story beside its sessions, Settings’ menu beside its page). The side region takes the side span, a third of the page’s columns and at most four (448px at 1440), so it stands on the columns and the page’s outer edges stay on them; only the edge between the two regions moves in by the extra 16px. Rows of tiles sit 40px apart on web (the tile row gap), since words run under each photo; sections stay 48px apart.
  • Sections span whole columns, so edges line up down the page. From 768px, cards in a shelf or a results grid and the rails beside a page span whole columns, so they start on column lines.
  • A workspace (Mellow, and Explore in the app) makes the region beside its sidebar its own page frame, and its content takes the fluid grid for the region’s width. On web Explore is a wide page instead (October 16): its filters take the first two columns (a tile’s width since October 21) and its results the rest, on the page’s own column lines, so the bar’s logo and avatar are its edges. Focus cards and Mellow’s transcript keep their widths and carry a column grid of their own.
  • The business page header sits on the page’s columns from 880px (G6, October 15): its side a quarter of them, the hero the rest, Ask Mellow and What they offer splitting the left side.
Compact and medium, under 768px4 columns, 12px gutters, 24px margins
Expanded, 768px to 1199px8 columns, 16px gutters, 48px margins
Wide, from 1200px12 columns, 24px gutters, 240px margins

Container

The page’s width: the margins for its size class, a maximum width, and centering past it.

wide
standard
narrow
full
Show details
  • Wide is the fluid grid: the frame’s full width less 16px, 32px, or 24px margins, up to 1680px, in columns of at least 88px, two to a tile, with 40px gutters (October 23; 24px from October 21; a column per 264px tile from October 14, the 12 columns up to 1312px before). Standard is its middle ten columns at most (October 22 and 23: the same as wide at 1440, 1393px at 1728), centered, for the activity page, business pages, Plans, and Collections. Narrow is its middle six columns at wide (820px at 1440) and one 720px column below it, centered, for reading, settings, profiles, and every form and result. Narrow is a column frame whose columns are the fluid grid’s, so it stands on a wide page’s lines. Full is the page less its margins.
  • Paragraphs inside stop at the measure (52ch), whatever the width, so a wide page never sets a line too long to read.

Grid

The page’s columns as a component: each item covers whole columns at each size class.

Details: 7 of 12, 5 of 8
Dates: 5 of 12, 3 of 8
Tile 1
Tile 2
Tile 3
Tile 4
In a subgrid
Same columns
Own column 1
Own column 2
Own column 3
Own column 4
Own column 5
Own column 6
4 of the Grid’s 6 at wide, all of them below
Show details
  • Items cover whole columns, so their edges meet the page’s, the overlay’s (Shift+G), and Figma’s layout grid. /early lays its newest bracelets and its activity tiles on it (two across on a phone, three or four from 768px), and its Explore heading takes 7 of 12 columns beside the category filter.
  • A Grid can set its own column count with columns (October 15): one count, or one per size class. Its edges meet the page’s when the count divides the page’s (3 or 6 of 12); the overlay draws its columns in purple over the page’s, so a count that doesn’t divide shows where it parts.
  • For cards that should fill a row by a minimum width rather than by any columns, use Columns.

Stack

Pieces in a column or a row, on the spacing grid.

One
Two
A column, 8px apart
Ages 6–10Day campBefore care
A row that wraps, 8px apart
Show details
  • Since October 14 gap also takes a purpose: tight, default, or loose (8, 16, or 24px, the stack tokens), or section; and it can change with the page’s size class: gap={{ compact: 'tight', expanded: 'default' }}.
  • Most layout inside a page is a column or a row with a gap; Stack is that, so a screen never writes it by hand (October 11). gap is a step of the 4px grid, or section (32px on a phone, 48px from 768px) between a page’s sections.

Columns

Equal columns that wrap to fewer as the room narrows.

What to bring
Cancellation policy
Pickup
Show details
  • As many columns as fit at min, sharing the row, down to one; no breakpoint, the room decides (October 11). Plans, the child form’s groups, and Payments’ amounts use it.

Rail layout

Not in use yet

Retained for design review. No consumer screen uses this component.

Two regions side by side: a main column and a side column a third as wide, 40px apart on web, such as an activity’s details with its dates.

About

The overview card.

Location

The commute map.

Show details
  • The system’s side-by-side layout (Hannah and Andy, October 26): the rail takes the side span, a third of the page’s columns and at most four (448px at 1440, 463px at 1728 on a standard page), the region gap (40px on web) parts it from the main column, and the main column takes the rest. The live activity page, the planner, and Settings lay out their two regions the same way in their own stylesheets, so no screen renders RailLayout (Not in use yet).
  • Before October 26 the rail took the whole columns nearest 360px, a gutter from the main column.
  • From 800px of its own width: the main column, and the rail to its right, sticky as the page scrolls. Below that: the rail first, then the main column, or with tabs, one at a time under a pair of tabs (the activity page: Sessions, then Details).
  • side="start" (October 14, the activity page) puts the rail on the left, on the same side span and region gap, holding the page’s title card and the dates; it is a section, not an aside, since it leads the page. The activity page keeps it in place as the page scrolls (Hannah, October 12: a column moving as the page scrolled read as unsettled).

Spacing

Space by purpose: inside a container, inside a group, between sections, between columns, and at the page’s edge.

Inset, inside a container--schools-out-inset 24px (16px in a compact page), --schools-out-inset-compact 16px
Stack, inside a group--schools-out-stack-tight 8px, --schools-out-stack 16px, --schools-out-stack-loose 24px
Section, between a page’s sections--schools-out-section-gap 32px, 48px from expanded; a section’s heading sits --schools-out-section-head-gap (16px) above it
Gutter, between columns and the tiles on them--schools-out-grid-gutter 12px, 16px from expanded, 24px at wide; the fluid grid’s --schools-out-fluid-gutter 8px, 16px, then 24px
Region gap, between side-by-side regions--schools-out-region-gap 24px, 40px at wide (Hannah and Andy, October 26): a page’s side region beside its main one, never tiles
Side span, a page’s side region--schools-out-side-width: a third of the page’s columns, rounded, at most four (--schools-out-side-columns): 448px at 1440, 463px at 1728 on a standard page
Tile rows, between rows of tiles--schools-out-tile-row-gap 16px, 40px at wide (October 23 and 26): words run under each photo, so rows sit further apart than the gutter
Margin, the page’s edge--schools-out-page-margin 24px, 48px from expanded, 240px at wide
Fluid margin, a wide page’s edge--schools-out-fluid-margin 16px, 32px from expanded, 24px at wide (Hannah, October 21); the web bar’s logo and avatar sit on it (--schools-out-fluid-inset)
Fluid columns, every consumer page--schools-out-fluid-module 88px at least, two to an activity tile (--schools-out-fluid-tile-span), 24px gutters at wide (--schools-out-fluid-gutter-wide; 40px from October 23 to 26), up to 1680px of content (--schools-out-fluid-max-width): 12 columns of 94px at 1440, 14 from 1592px
Hairline, between controls in a track--schools-out-space-hairline 2px (Pagination, segments, faces, calendar dots and chips); text pairs take no gap
Measure, a paragraph’s line--schools-out-measure 52ch, about 66 to 73 characters of Body or Lead
Show details
  • Every space and box size is a multiple of 4 (October 14). Name the purpose, not the size: Panel pads by the inset, Stack gaps by tight, default, or loose, and sections by the section gap, so a retune changes every place that shares a purpose and nothing else.
  • Type line heights use the 4px grid: Body 16/24, Lead 18/28, and Small 14/20 at the default browser text size.

Surfaces and depth

Four levels from the page up, each one material, so depth reads the same everywhere.

0 · Page--schools-out-color-canvas, no shadow
1 · ContainerPanel: --schools-out-color-container, flat at rest
2 · Group in a containerA Panel inside a Panel: --schools-out-color-fill; or raised, a Panel over a photo, a map, or the glow
3 · FloatingSheet, Menu, Popover, Toast: --schools-out-color-surface-floating with --schools-out-shadow-floating, on a --schools-out-layer-* token
Pickup and drop-off
A Panel inside a Panel sits on the fill.
Show details
  • No container in a container in a container (October 9). A Panel inside a Panel sits on the fill, a group within the container rather than a second container; a third level warns in development.
  • Only what floats has a shadow. Raised is for a container over another surface, never one at rest on the page.
NextButtons and inputs →