Design System
Work in progress. I'm adding components as I go, following patterns from what's already documented. Nothing here is set in stone yet.
Atoms
Small, single-purpose elements. Some are structural (Button), others are chromatic (Tag) and pick up the accent color from their context.
Link
Atom
Inherits --accent-color from its section context, falling back to --light-color. External links are auto-detected from the URL and get an icon + target="_blank".
With Arrow
ArrowLink — directional arrow that animates on hover
<ArrowLink href="/articles" text="Read article" direction="back | forward" /> Back
BackLink — shorthand for ArrowLink direction=back
<BackLink href="/articles" text="Articles" /> External
ExternalLink — always opens in new tab with icon
<ExternalLink href="https://github.com" text="View on GitHub" /> Props
| Prop | Type | Default | Description |
|---|---|---|---|
href | string | required | URL |
text | string | required | Link text |
external | boolean | auto | Force external link behavior |
small | boolean | false | Smaller font size |
class | string | — | Additional CSS class |
Dropdown
Atom
Generic dropdown with trigger slot, click-outside close, and chevron indicator. Content is fully custom via children.
Preview
<Dropdown trigger={() => <span>Label</span>}>
<button class={dropdownStyles.option}>Option</button>
</Dropdown>Props
| Prop | Type | Description |
|---|---|---|
trigger | (open: Accessor<boolean>) => JSX.Element | Render function for the trigger content |
children | JSX.Element | Dropdown panel content |
class | string | Additional class on the wrapper |
Exported styles
| Class | Usage |
|---|---|
dropdownStyles.option | Standard option button |
dropdownStyles.optionActive | Active/selected option |
Tag
Atom
Passive metadata label. No hover state, no interactivity — just shows what something is. Picks up --accent-color from its section for the tint and left border.
Variants
Small
size="small" With Icon
icon={terminalSvg} Chromatic
Props
| Prop | Type | Default | Description |
|---|---|---|---|
title | string | required | The text content of the tag |
size | "default" | "small" | "default" | Compact variant |
icon | string | - | SVG icon as raw string |
highlight | boolean | false | Adds accent border |
outline | boolean | false | Transparent background with accent border |
badge | boolean | false | Solid accent background, black text |
animated | boolean | false | Starts hidden for reveal animation |
Responsive
| Property | Desktop | ≤900px | ≤600px |
|---|---|---|---|
font-size | 14px | ~13px | 12px |
padding | 8px 18px | 6px 12px | 4px 10px |
icon | 16px | 16px | 12px |
TagRow
Atom
Flex row for Tag components. Uses margin-top: auto to push down and padding-top for minimum spacing.
Preview
<TagRow><Tag title="React" /><Tag title="TypeScript" /></TagRow> Fluid spacing
| Property | Value | Min | Max |
|---|---|---|---|
| gap | clamp(6px, 0.32rem + 0.21vw, 8px) | 6px | 8px |
| padding-top | clamp(18px, 0.59rem + 1.89vw, 36px) | 18px | 36px |