Surfaces, chrome and feedback
Source: src/styles/parts/chrome.scs — and lib::surface,
lib::raised, lib::floating, controls::tabs,
controls::tag for the same objects inside a shadow root.
Border, fill, radius and shadow each say “separate object”, so they are spent by role. A
.card and a .panel are bordered surfaces with no shadow: they sit in
the page. Popovers, drawers and toasts get a shadow, because they genuinely float above it. A shadow on
every block flattens the hierarchy instead of building one.
Cards
A card
newThe body is whatever the page puts in it: the card only supplies the surface, the padding and the gap between its children.
.card.link
A card that is itself the link: it lifts on hover instead of underlining.
.card.flat
No hairline, a quieter ground: a card inside another surface, where a second border would only add noise.
One
280px minimum, then as many per row as fit.
Two
The gap is the section gap.
Three
Resize the window to see it reflow.
Panels
A panel is a card whose header and body are separated by a hairline rather than by padding: it is the
frame around a table, a chart or a form, where the content runs to the edges.
.panel-head, .panel-body and .panel-foot are there for a markup
that cannot use <header> and <footer>.
Recent activity
A panel's body is padded; a table or a list put straight inside the panel is not, and runs to the hairlines.
Widgets
The figure tile of a dashboard: a quiet header, one big number, and the change that number just made.
.delta.up and .delta.down are the only two colours on it.
The draggable, resizable version is the element <mmo-widget>, inside an <mmo-grid>.
Tabs
A strip is a segmented control: a track, with the active tab filled with the accent. That is the
default because a tab almost always switches a view of the same thing, where nobody should have to look
for which one is on — and because the fill means the same thing in both themes, which a pill
raised out of the track does not. Mark the active one with .active,
aria-selected="true" or aria-current — all three are painted.
.line is the quiet variant, for navigating rather than switching: the underline belongs to
the strip, so the active tab sits on the content rather than above it.
The same two forms are what <mmo-tabs>
paints in its own shadow root, from the same controls::tab* fragments — a tab looks
like a tab whether a page wrote it or an element did.
Toolbars
Tags and status
State reads at a glance because it has a shape as well as a colour — a dot for live state, a plain pill for a label. Colour alone would carry nothing for a colour-blind reader.
Callouts
A note inside the flow: a left rule in the tone's colour, the tone's soft ground, and a
.title line that says what it is.
Floating surfaces
These carry lib::floating: the surface, a hairline and the large shadow. They are shown
here in place; in an application they are positioned by the element that opens them.
A popover is the same floating surface with whatever the page puts in it.
The behaviour — anchoring, opening, closing on an outside click — belongs to <mmo-dropdown>.
Overlays
.backdrop, .drawer, <dialog> and .modal are
fixed to the viewport, so these two specimens really open them — and the html is what opens them.
Toasts
Feedback stacks from the bottom right, newest nearest the cursor, and says what happened — not “success”. The tone is carried by the left rule alone.
In an application the shell owns the stack: MMO.app.notify(…) and
<mmo-notification>.
Loading
A skeleton keeps the layout it will be replaced by, so nothing jumps when the data lands. It is a shimmer over the two quiet grounds, and it swallows pointer events.
Avatars
The sticky aside
.aside is a column that sticks to the top of its container and never stretches to its
height — the rail beside an article, the summary beside a form.
The column the reader is in. The block on the right is an .aside:
scroll a long page and it stays with them.
Highlighting a target
Anything linked to by a fragment — :target — or given
.highlight-target flashes the warning ground once and fades out, so a reader who followed a
deep link sees where they landed.