Skip to content
AstroCraft Docs
On this theme

Layout & Spacing

8-BitQuest keeps layout deliberately plain, because the visual interest comes from the pixel surfaces, not from an elaborate grid. There is one container, one shared vertical rhythm, and a small set of utility classes that the pages compose. Once you know them, every page reads the same way.

The container and the shell

The Header and Footer live in BaseLayout, so every route gets them for free — a page never imports them. Between them, BaseLayout renders a <main> with a single slot, and the page fills it.

The one width constraint is .site-container, defined in global.css:

.site-container { @apply mx-auto max-w-[1100px] px-4; }

It centres content, caps it at 1100px, and holds a consistent gutter on narrow screens. Almost every page opens with it, combined with the shared rhythm below.

The vertical rhythm

Pages compose their sections inside the container with one repeated flex-column pattern:

<div class="site-container flex flex-col gap-10 py-8 md:gap-12 md:py-12">
  <Hero />
  <DevProfile />
  <SkillTree />
</div>

The gap-10 md:gap-12 sets the space between sections, and py-8 md:py-12 sets the top and bottom breathing room. Sections themselves are layout-free — they own their internal spacing but not the space around them — so this one wrapper controls the page rhythm. Changing the whole-page spacing is an edit to this wrapper, not to every section.

Sections manage their own internal grid where they need one. The contact page, for instance, wraps its form and info column in a lg:grid-cols-[minmax(0,1fr)_340px] grid inside the container — a fluid form beside a fixed 340px sidebar that stacks below lg. That grid belongs to the section’s own markup, not to the shell.

The breakpoints

The breakpoints are declared explicitly in tailwind-theme.css, mirroring Tailwind’s defaults but adding one:

--breakpoint-xs: 400px;
--breakpoint-sm: 640px;
--breakpoint-md: 768px;
--breakpoint-lg: 1024px;
--breakpoint-xl: 1280px;
--breakpoint-2xl: 1536px;

The custom xs: 400px gives you a step below sm for the narrowest phones — useful when a row of pixel chips or a stats strip needs to reflow before 640px. The rest are declared rather than assumed so the whole set is visible in one place.

The pixel panel as a layout unit

Most of the site’s structure is carried by one primitive: ui/pixel-panel, the black-bordered surface with the hard offset shadow. It takes an as prop to render as a <section>, <article> or <div>, and an elevated boolean for the larger shadow. The project detail page, the cards, the contact info column and the hero are all pixel panels — so “add a boxed region” almost always means dropping a <PixelPanel> rather than composing borders and shadows by hand. See UI Components.

The shared utility classes

Beyond the container, global.css defines a handful of cross-cutting classes worth knowing, because reaching for them keeps a page consistent with the rest:

  • .h1 / .h2 / .h3 — the pixel heading scale. See Typography.
  • .description — the lede paragraph under a heading.
  • .blog-prose — the MDX article body treatment.
  • .pixel-btn (with --blue / --green modifiers) — the retro 8-bit button. See Colors.
  • .primary-focus — a visible keyboard focus ring, applied to custom interactive elements that are not already a primitive.
  • .main-text-gradient — a blue gradient clip for accent headings and tags.

These are the sanctioned use of @apply — genuinely cross-cutting patterns repeated across many unrelated elements. Anything with structure or variants should be a primitive or a tailwind-variants recipe instead, which is what the UI Components library provides.

Changing the layout

To widen or narrow the whole site, edit the max-w-[1100px] in .site-container. To change the page rhythm, edit the shared gap/py wrapper on the pages you want to affect. To change a single section’s internal spacing, edit that section — it owns its own rhythm, which is exactly why one section can be dense on one page and airy on another without a global toggle.

NEXT STEPUI Components