half-built-ui

About

This page renders every component in the half-built design system, one instance of each. The system was extracted from half-built-robots.com, which still runs on it. All three packages are published on npm under MIT.

The palette editor in the corner rewrites the theming variables live and prints a block ready to paste into a stylesheet. That block is the entire theming surface, eight brand stops plus the four values behind the code viewer. The viewer highlights through those variables, so syntax colors and the block they sit on follow the palette as well.

npm install @half-built/css @half-built/astro @half-built/tooling

Frame

The header and footer come from the package and know nothing about the site around them. The site name and the rest of the identity arrive as typed props. The theme toggle sits in the header, and the palette panel carries a second instance beside the color pickers. Every toggle on a page stays in step, so flipping either one moves the other.

Show imports
import Masthead from "@half-built/astro/components/Masthead.astro";
import Footer from "@half-built/astro/components/Footer.astro";
import ThemeToggle from "@half-built/astro/components/ThemeToggle.astro";

Cards

PostCard is the card an archive page is made of. The second one here is flagged as a draft, and that badge exists so an unfinished post can ship where people can see it. The third wears the corner badges, one for an AI-generated image and one for a post carrying an interactive demo. CategoryCard is the smaller tile, an image with the category name chipped over its bottom edge.

Show imports
import PostCard from "@half-built/astro/components/PostCard.astro";
import CategoryCard from "@half-built/astro/components/CategoryCard.astro";

Post cards

Category cards

Components

The rest of the package, from the navigation rows to the blocks a post body is built from. Imports split between components/ and content/, which is a packaging detail rather than a distinction worth reading into. Nothing here caps the width of the text, and nothing anywhere in this system does. The layout's column is the only width authority. Every image below is a generated placeholder.

Show imports
import Pagination from "@half-built/astro/components/Pagination.astro";
import PostNavigation from "@half-built/astro/components/PostNavigation.astro";
import Widget from "@half-built/astro/components/Widget.astro";
import LinkListWidget from "@half-built/astro/components/LinkListWidget.astro";
import Subscribe from "@half-built/astro/components/Subscribe.astro";
import Button from "@half-built/astro/content/Button.astro";
import Callout from "@half-built/astro/content/Callout.astro";
import EditorNote from "@half-built/astro/content/EditorNote.astro";
import Group from "@half-built/astro/content/Group.astro";
import CodeBlock from "@half-built/astro/content/CodeBlock.astro";
import Spacer from "@half-built/astro/content/Spacer.astro";
import Quote from "@half-built/astro/content/Quote.astro";
import Walkthrough from "@half-built/astro/content/Walkthrough.astro";
import Step from "@half-built/astro/content/Step.astro";
import Gallery from "@half-built/astro/content/Gallery.astro";
import GalleryImage from "@half-built/astro/content/GalleryImage.astro";
import BlogImage from "@half-built/astro/content/BlogImage.astro";
import MediaText from "@half-built/astro/content/MediaText.astro";

Pagination

The numbered row at the foot of an archive. It renders nothing when there is only one page.

Post navigation

The pair of links at the end of a post. The newer post sits on the left and the older one on the right, matching the newest-first order the archives read in.

Link list widget and Widget

Widget is a heading over whatever sits in its body. LinkListWidget is that same block filled with links and their counts.

Sample links

Plain widget

A Widget with arbitrary content in its body, rather than the link-list shape above.

Subscribe

A real form with a method and an action, which submits with JavaScript turned off. Its copy sits in named slots, so the words can be overridden without forking the component.

Button

Four variants, two sizes.

Callout

note
A note callout, the default look.
Tip
A tip callout, wearing the first accent.
success
A success callout, wearing the second accent.
error
An error callout, in the red family.

Editor's note

The reminder that never ships. By default it renders only on a dev server. A deploy build emits nothing for it, so a note can sit in published content as a standing to-do. This one is forced visible with the shown prop so the page can show it.

Editor's Note: Demo
A demo note, forced visible. The dashed rule is the tell. Nothing else in the system is dashed.

Group

A boxed prose container, no label and no tint, the plain sibling of Callout's box.

Code block

def read_ir(code):
    return "power" if code == 0x40BF else "unknown"

Spacer

A fixed-height spacer sits below this paragraph.

Normal flow resumes here, after the spacer.

Quote

A quoted line, with an attribution footer.
~ Demo Author, 2026

Walkthrough and Step

  1. First step. One placeholder photo beside its text.
  2. Second step. Numbering runs down the media column's corner chip.

Gallery

Blog image

Wide placeholder image
A full-width figure with a caption.

Media text

Media on one side, prose on the other. This is the caption slot, and it takes a short paragraph rather than a single line.

CSS primitives

The tokens are the variables everything else reads, and every color on this page resolves through them. The palette editor repaints the page by setting twelve. Each value is tuned to clear WCAG AA against the ground it sits on. The prose and pattern sheets carry the rest, the paragraph rhythm and the boxes.

Show imports
import "@half-built/css/tokens";
import "@half-built/css/prose.css";
import "@half-built/css/patterns.css";
import Palette from "@half-built/astro/content/Palette.astro";

Tokens

Swatch Role Hex Used for
--ink Body text and rules
--surface The page ground
--rule Borders and frames
--accent-1 Accent 1 lines and fills
--accent-1-ink Accent 1 as readable text
--accent-2 Accent 2 lines and fills
--accent-2-ink Accent 2 as readable text
--code-token-function Function names in code
--code-token-string Strings and constants in code

Prose specimen

Placeholder body copy, demonstrating paragraph rhythm, inline code, and a placeholder link.

A placeholder blockquote, boxed on the gray band.
  • Placeholder list item one
  • Placeholder list item two

Patterns

SpecimenClassUsed for
Chip .chip Filled label. The read-time chip and the category card's name.
Boxed label .boxed-label Bordered box, typically straddling a frame rule. The header's date box and widget titles.
.icon-box Bordered interactive square. Social icons, the search magnifier, the palette panel's close box.
Micro label .micro-label Small bold tracked line. Plate labels and the lightbox's HOME box.
Caption text, quiet and small. .caption The quiet line under an image, beside media text, or after a quote.