Typography and element defaults

Source: src/styles/core.scs — the reset and the element defaults, the first thing in the cascade after the tokens.

A plain <p>, <h2>, <table> or <a> must already look right: pages are written in markdown and phtml, and most of them never reach for a class. Everything on this page is what you get with no class at all.

Margins Headings, paragraphs, lists and figures have no margin: spacing comes from the layout's gap, so nothing collapses twice. A documentation page like this one adds the reading rhythm back itself — see demo/www/styles/demo.scs.

Headings

The display face, tightened tracking, balanced wrapping. h6 is not a heading size: it is the eyebrow, the small uppercase label that opens a section.

Heading 1 · display

Heading 2 · section

Heading 3 · block

Heading 4

Heading 5
Heading 6 is the eyebrow

Text

A paragraph in the interface face, at the base size, with text-wrap: pretty so the last line is never left with a single word. The measure a paragraph should be read at is capped by its container, not by the element — see Prose for the long-form column.

A link, some strong text, some bold, some emphasis, some italics, a bit of small print, a highlighted run, an SCS abbreviation, a formula with a subscript 2 and a superscript 3, some inline code, a ⌘ K shortcut, a program output and some text with an underline.

Border, fill, radius and shadow each say “separate object”, so they are spent by role. A shadow on every block flattens the hierarchy instead of building one.

Code

code, kbd, samp and pre all take the mono family. A <pre> is a surface: it carries the panel's border and radius, and scrolls rather than clipping.

.card {
  @use lib::surface($radius.md)
  @use lib::col($space.md)
  padding: $space.lg
}

The documentation site also ships <mmo-code>, which highlights its content and, for language="html", toggles between the source and a live preview:

.button.success {@use filled($color.ok, lib::blend($color.ok, $color.text, 18%));}

Lists

Bare lists keep the browser's structure with the system's spacing and marker colour. The class-driven lists — .list, .menu, .tree — are on Lists.

  • An unordered item
  • Another one
    • and a nested one
  • A third
  1. First
  2. Second
  3. Third
A term
What it means.
Another term
What that one means.

Disclosure

A <details> is a surface with its own chevron: the marker is drawn, the browser's is hidden, and the open state is the browser's rather than a class to track.

What does a region rule not do?

It must not set display. One rule lists every optional region and turns it off; each template's section turns on the ones it uses.

Open by default

The open attribute, nothing else.

Media and figures

Images, video, canvas, svg and iframes are display: block with max-width: 100% — they never push a layout wider than its column.

A caption: the interface face, small, quiet.

Selection and focus

Selected text takes $color.selection. Focus is a two pixel outline in $color.focus, offset by two — and only for :focus-visible, so a mouse click never draws it. Tab into the controls below to see it.

a link

Motion

Everything that moves uses $motion.fast, $motion.base or $motion.slow with the shared easing — and all of it is cut to 0.01ms under prefers-reduced-motion: reduce, animations and smooth scrolling included.

The device name

body::after carries the breakpoint's name as content — phone, tablet, desktop, wide. MMO.window.device reads it and emits a device event when it changes: it is how an element knows it is on a phone without duplicating the breakpoints in javascript.