School’s Out design system
Guidelines

Applying the system

How the pieces go together, so a page feels calm, clear, and a little delightful.

Calm first, then delight

A School’s Out page should feel clean and trustworthy at a glance, with one small moment of delight, never a page of them.

Quiet by defaultMost of a page is text in the ink, flat containers, and hairlines. Shadows, glass, and color are the exception, so they mean something.
One loud thingEach screen has at most one thing that shouts: its main Primary, a business’s color, or a photo. Everything else supports it.
One moment of delightAt most one per screen: a logo sticker’s peel, the note’s scribble, the glow on a focus screen. Routine controls only press and change color.
Gradients on the backgroundColor washes belong behind the page (the chat’s backdrop, the ambient glow), never inside a button, field, or pill. The one exception is the rainbow glow on the signed-out Sign up (Hannah, October 28).
The same piece, the same jobA Tag is always a label, a Chip always a choice, a Panel always plain content. Never restyle a library piece to do another’s job.
Show details
  • Hannah, October 9: the finish should be delightful but still clean and professional. Most of a page is quiet (flat fills, hairlines, one typeface, the ink); the delight lives in a few chosen places, so it still feels special.
  • After the button work of the same day: glass on every row, the hand-drawn line on every text button, and 44px pills everywhere read as busy, so each moved to where it earns its place.

How loud each action is

Match a button’s weight to how much the action matters on that screen. Most buttons are quiet.

PrimaryFinishes or moves a task forward: Save, Continue, Book for Maya. One per form, dialog, or step, and the loudest action on any page.
SecondaryNeeds presence: beside a Primary, leading a section, or on a photo or a business’s card.
SoftThe default. Any action inside content: a row, a card, a list, a sheet, a notice.
PlainCancel, Not now, Skip, Keep, and labeled toolbar actions.
TextA link inside a sentence, Back, See all.
PairsThe main action goes last: at the right on the web, at the bottom when stacked on a phone, nearest the thumb. At most three buttons together; more go in a More menu.
DeletingOnly for deleting something or removing someone’s access, always asked first. The button that confirms it is Secondary in the danger tone, so it reads red; Keep or Cancel sits beside it.

In practice

Hands-on Museum isn’t booked yet

Sun, Oct 11 · Theo

Is Maya registered for Beginner I?

From your email

Do: the row's action is Soft and small, so the content leads

Hands-on Museum isn’t booked yet

Sun, Oct 11 · Theo

Is Maya registered for Beginner I?

From your email

Don’t: glass on every row, at full size
Do: one main action, last, with a quiet way out
Don’t: three loud buttons asking at once
Do: the button that confirms a delete is red
Show details
  • From loudest to quietest: Primary (one per form, dialog, or step), Secondary in glass (an action that needs presence), Soft (the default, inside content), Plain (dismiss), Text (inline). The Button entry has every rule. The CTA, a pill with an arrow dot, was removed on October 23 (Hannah): booking takes the black Primary, and no screen used it.

Sizes by place

Size follows where a control sits, not how important it is. One scale for every control, so a row of chips, buttons, and fields lines up.

Small, 32pxRows, cards, tables, toolbars, filter pills, and most buttons on a phoneFinish booking in a list, Edit on a card
Medium, 40pxThe default on the web: forms, dialogs, page and section actionsSave changes, Add child
Large, 48pxThe one main action pinned to a phone’s foot, or alone on a sparse focus screenBook, Continue in onboarding
Touch, 44pxEvery tap area on a touch screen; chat pills draw at itSmall and medium grow their tap area, not their drawn size
Show details
  • The control scale (October 9): 32, 40, and 48px for buttons, icon buttons, chips, and segmented controls (--schools-out-control-height-*). It replaced the buttons’ 36, 44, and 52px. The tap area on touch screens is always at least 44px (--schools-out-touch-target).

Surfaces and depth

Build up from the page in as few layers as possible. Depth is for things that float, not for decoration.

LayersPage, then one container (Panel), then fills inside it. Never a container inside a container inside a container; split rows with hairlines instead.
ShadowsOnly what floats or lifts: sheets, menus, toasts, pills, and a card while it is hovered. A container at rest has no shadow and no hairline.
GlassLiquid glass for what floats over the page: the web bar, the tab bar, the footer, the map’s controls. Rim glass for glass buttons, photo labels, and cards over color or a photo. Never on a row, a field, or a container at rest on the plain page.
CornersControls are round (pills); containers use the container radius (24px); small labels and fields use 8 to 12px. Match the piece beside it.
Business colorA business’s color fills its page’s header and the vivid field behind an activity’s title, and its logo is a sticker. Everything else stays neutral, so every business page reads the same way.

In practice

Maya Okafor

Age 8 · 2nd grade

InterestsScience, TheaterCareQuiet breaks
Do: one container, rows split by hairlines

Maya Okafor

Interests: Science, Theater

Don’t: a container in a container in a container
Find an activity that fits my kids
Do: a pill floats on a shadow
Ages 6–10Day camp
Do: tags are quiet labels; chips are choices
Show details
  • The surface roles are on the Colors entry: page, container, fill, floating, field, and inverse. Vani’s chat work (October 9) added the pill shadows: pills sit on a shadow, never a border.

Spacing and type on a page

A steady rhythm and few type sizes make a page easy to scan.

Inside a piece4, 8, or 12px between its parts.
Between items12 or 16px between items in a group; 24px between groups.
Between sections32px on a phone and 48px from 768px; a page that splits sections with a hairline puts it halfway.
Page edges24px on a phone and 32px from 768px, then the fluid grid’s 24px at wide. Content in one of three widths on the same columns: wide (every column, up to 1680px; Explore only), standard (the middle ten at most; the activity page, business pages, Plans, Collections), or narrow (the middle six, 820px at 1440; everything you read or fill in). Columns are 40px apart.
TypeOne page title in Headline, section headings in the section step, body for nearly everything else. Weights after Partiful (Hannah, October 19): heavy type once a screen, on its hero name (an activity’s or business’s own title); Bold for page titles; Medium for names, titles in cards and rows, controls, labels, prices, dates, and section headings; Regular for everything read. Titles lead by ink and size, not by weight. Three sizes on a screen is plenty. Set type with the step tokens: a size with its own line height and a weight, never a size alone.
CopySentence case, plain words, one idea per line. Say what happens, then stop.
Show details
  • Values are the section rhythm tokens (October 11): sections 32px apart on a phone and 48px from 768px (--schools-out-section-gap), and a section’s heading 16px above its content (--schools-out-section-head-gap).

On a phone

Every component is designed for a phone too. Check each one with the Phone switch in the top bar, then on a real phone.

Tap areasAt least 44px for anything you tap. Small controls grow their tap area, not their drawn size.
Thumb reachA step’s main action is pinned at the foot of its sheet, full width. Dialogs rise from the bottom as sheets.
No hoverNothing a phone needs may live in a hover state or a tooltip. Menus and filter groups open as bottom sheets.
One columnLay pieces out by their container, never the window. Rows of chips scroll sideways with no scrollbar and fade the side with more to see.
ButtonsSmall inside rows and cards; large only for the one pinned action. Stacked groups put the main action last, at the bottom.
Fields16px text so the phone doesn’t zoom, the label always above, the right keyboard for the answer, and an error in words under the field.
The bottom barPlaces only: Search, Plans, Explore, Feed, Collections, and Mellow. The parent’s profile and account are the avatar at the top right of Plans. It tightens so every place shows; only if they still can’t fit does the pill scroll sideways, fading the side with more.
The end of a pageThe directory footer ends every page, on web and mobile web, except Mellow’s full view.

In practice

Who’s going

S.T.E.A.M. Discovery Camp · Fri, Oct 16

Do: a step’s main action pinned at the foot, in reach of a thumb
Do: stacked on a phone, the main action last, nearest the thumb
Do: small icon buttons still get a 44px tap area
Show details
  • Hannah, October 9: the components were designed on the web first; these rules make them translate. The Phone switch shows every example in a 390px frame; touch-only rules (the 44px tap areas, no hover) need a phone or the browser’s device mode.

Before you ship a screen

Seven questions to answer before a screen goes out.

  1. Is there one clear main action, and is everything else quieter than it?
  2. Does every piece come from the library, used for its own job?
  3. Is there at most one moment of delight, and is the rest calm?
  4. Does it read well on a phone: 44px tap areas, the main action in reach, nothing hidden behind hover?
  5. Does it work in light and dark, with text at 4.5:1 or more?
  6. Does every list show something while it loads and when it is empty?
  7. Is the copy plain, in sentence case, with nothing a parent has to decode?
Show details
  • npm run lint:ui (the UI rules, which every pull request runs) checks raw colors, other typefaces, off-grid spacing, hand-drawn focus rings, hover with no pointer check, window widths in components, containers drawn by hand, motion and layers outside the tokens, hand-made spinners, scarcity copy, screens reaching inside library pieces, and type set by hand. The UI audit (scripts/ui-audit.mjs) checks what needs a whole file: one scribble a file and lists with no empty state.
NextColor and type →