The systemLumos 0.0.1
Building a layout
Section, ContentWrapper and Grid: the three components almost every page is made of.
Nearly every page in a Lumos site is the same three components nested in the same order. Once you can see that shape, building a page is choosing variants rather than constructing scaffolding.
Section the full-width band, its background, its vertical rhythm
container centred, max width, gap between children (automatic)
ContentWrapper how the content inside is arranged
Grid or a grid of repeated thingsSection is the band
A Section is one horizontal band of the page. It owns the background color, the space above and below, and the container that centres its contents. You never add a container yourself.
<Section theme="dark" paddingTop="large" paddingBottom="medium">
<Heading tag="h2">Everything here is centred and capped</Heading>
</Section>The vertical spacing comes from three tokens (small, medium, large) rather than numbers, so every section on the site sits in the same rhythm. even uses the site margin for a band that should feel inset rather than spacious, and none removes it entirely.
ContentWrapper is the arrangement
Inside a section, ContentWrapper decides how the content sits: stacked, in two columns, breaking out of the container, sticky as the page scrolls, or as a card. You change the layout by changing one word.
Two columns
The first column holds the default slot, the second holds whatever is passed to the column2 slot. Below 64rem they stack.
<ContentWrapper variant="columns">
<Heading tag="h3">Two columns</Heading>
<Paragraph>The first column holds the default slot.</Paragraph>
<Img slot="column2" src={visual} />
</ContentWrapper>The columns variant. Below the medium breakpoint the two columns stack.
Grid is for repeated things
When you have a list of similar items (cards, logos, team members), use Grid. Set a column count per breakpoint, or let it fit as many as will fit.
<Grid xsmall={2} medium={4}>
<Card heading="One" />
<Card heading="Two" />
</Grid>Two columns on small screens, four from the medium breakpoint up.
Column counts inherit upwards: set xsmall and medium and the sizes between them follow the nearest one below. You only declare the widths where the design actually changes.
The spacing you do not set
Three kinds of space are already handled, and knowing which is which saves a lot of nudging:
- Between sections: the section's own top and bottom padding.
- Between a section's children: the container's
gap, set with thegapprop. - Between a heading and the paragraph under it: the text styles' own margins, which are part of the type scale.
A full page
---
import BaseLayout from "@/layouts/BaseLayout.astro";
import Section from "@/components/Section.astro";
import ContentWrapper from "@/components/ContentWrapper.astro";
import Grid from "@/components/Grid.astro";
import Heading from "@/components/Heading.astro";
import Paragraph from "@/components/Paragraph.astro";
import Card from "@/components/Card.astro";
---
<BaseLayout title="Home" theme="dark">
<Section paddingTop="large">
<Heading tag="h1" variant="display">A headline</Heading>
<Paragraph variant="large" maxWidth={38}>A sentence under it.</Paragraph>
</Section>
<Section theme="light">
<ContentWrapper variant="columns">
<Heading tag="h2">Two columns</Heading>
<Paragraph>Text on the left, a visual on the right.</Paragraph>
<Img slot="column2" src={photo} alt="" />
</ContentWrapper>
</Section>
<Section>
<Grid xsmall={1} medium={3}>
<Card heading="One" text="…" />
<Card heading="Two" text="…" />
<Card heading="Three" text="…" />
</Grid>
</Section>
</BaseLayout>