chore: update docs dcb9fcb8
Steve · 2026-04-19 07:40 4 file(s) · +76 −219
Cargo.lock +2 −2
695 695
696 696
[[package]]
697 697
name = "cellar"
698 -
version = "0.2.0"
698 +
version = "0.2.1"
699 699
dependencies = [
700 700
 "andromeda-auth",
701 701
 "andromeda-darkmatter-css",
3147 3147
3148 3148
[[package]]
3149 3149
name = "posts"
3150 -
version = "0.1.4"
3150 +
version = "0.1.5"
3151 3151
dependencies = [
3152 3152
 "andromeda-auth",
3153 3153
 "andromeda-darkmatter-css",
docs/docs/pages/diy/skills.mdx +2 −0
19 19
20 20
[`darkmatter-styles`](https://github.com/stevedylandev/andromeda/tree/main/skills/darkmatter-styles/SKILL.md) applies the shared Andromeda aesthetic: dark background, white borders, Commit Mono, minimal layout, no frameworks. Use it when building new pages or components that need to match the rest of the lineup.
21 21
22 +
The canonical CSS and fonts live in the [`andromeda-darkmatter-css`](https://github.com/stevedylandev/andromeda/tree/main/crates/darkmatter-css) crate. Mount its router and link `/assets/darkmatter.css` from your templates — the skill guides style decisions while the crate serves the actual bytes.
23 +
22 24
## Installing
23 25
24 26
Use [`npx skills add`](https://github.com/vercel-labs/skills) to pull either skill directly from the repo:
docs/docs/pages/diy/stack.mdx +18 −0
59 59
- Optional Axum integration (`axum` feature) for `IntoResponse` on errors
60 60
- Optional session management (`session` feature)
61 61
62 +
### andromeda-darkmatter-css
63 +
64 +
The `andromeda-darkmatter-css` crate ships the canonical Darkmatter stylesheet and Commit Mono fonts as an embedded Axum router. Mount it once and every app inherits the shared aesthetic:
65 +
66 +
- `/assets/darkmatter.css` — reset, tokens, and shared component styles
67 +
- `/assets/fonts/*` — Commit Mono 400/700
68 +
- `/darkmatter` — live component gallery
69 +
70 +
```rust
71 +
use andromeda_darkmatter_css;
72 +
73 +
let app = Router::new()
74 +
    .route("/", get(index))
75 +
    .merge(andromeda_darkmatter_css::router());
76 +
```
77 +
78 +
Then reference `/assets/darkmatter.css` from your templates instead of duplicating the styles per app.
79 +
62 80
## App Pattern
63 81
64 82
Every app follows a consistent structure:
skills/darkmatter-styles/SKILL.md +54 −217
9 9
10 10
The Darkmatter aesthetic: dark, minimal, monospace. No frameworks, no decorative flourishes. Everything is functional and stark.
11 11
12 +
The canonical reset, tokens, fonts, and component styles ship in the [`andromeda-darkmatter-css`](https://github.com/stevedylandev/andromeda/tree/main/crates/darkmatter-css) crate. **Do not duplicate the CSS per app** — mount the crate's router and link its stylesheet.
13 +
14 +
## Using the Crate
15 +
16 +
Add to `Cargo.toml`:
17 +
18 +
```toml
19 +
[dependencies]
20 +
andromeda-darkmatter-css = { path = "../../crates/darkmatter-css" }
21 +
```
22 +
23 +
Mount in the Axum app:
24 +
25 +
```rust
26 +
let app = Router::new()
27 +
    .route("/", get(index))
28 +
    .merge(andromeda_darkmatter_css::router());
29 +
```
30 +
31 +
Link from templates:
32 +
33 +
```html
34 +
<link rel="stylesheet" href="/assets/darkmatter.css" />
35 +
<meta name="theme-color" content="#121113" />
36 +
```
37 +
38 +
The crate serves:
39 +
40 +
- `/assets/darkmatter.css` — full stylesheet (reset + tokens + components)
41 +
- `/assets/fonts/CommitMono-400-Regular.otf`, `…-700-Regular.otf`
42 +
- `/darkmatter` — live component gallery (reference when building)
43 +
12 44
## Core Palette
13 45
14 46
| Token | Value | Usage |
38 70
39 71
## Typography
40 72
41 -
- **Font:** `"Commit Mono"` (self-hosted .otf), fallback `monospace, sans-serif`
42 -
- Applied globally via `* { font-family: ... }`
73 +
- **Font:** `"Commit Mono"` (served by the crate), fallback `monospace, sans-serif`
74 +
- Applied globally via the crate's `* { font-family: ... }`
43 75
- **Body font-size:** 14px
44 76
- **Line-height:** 1.6
45 77
55 87
| 13px | Inline code, error messages |
56 88
| 12px | Nav links, form labels, metadata, dates, table headers, action links |
57 89
58 -
### Font Face Declarations
59 -
60 -
```css
61 -
@font-face {
62 -
  font-family: "Commit Mono";
63 -
  src: url("/static/fonts/CommitMono-400-Regular.otf") format("opentype");
64 -
  font-weight: 400;
65 -
  font-style: normal;
66 -
}
67 -
68 -
@font-face {
69 -
  font-family: "Commit Mono";
70 -
  src: url("/static/fonts/CommitMono-700-Regular.otf") format("opentype");
71 -
  font-weight: 700;
72 -
  font-style: normal;
73 -
}
74 -
```
75 -
76 -
## Base Reset
77 -
78 -
```css
79 -
* {
80 -
  padding: 0;
81 -
  margin: 0;
82 -
  box-sizing: border-box;
83 -
  font-family: "Commit Mono", monospace, sans-serif;
84 -
  scrollbar-width: none;
85 -
  -ms-overflow-style: none;
86 -
}
87 -
88 -
html {
89 -
  background: #121113;
90 -
  color: #ffffff;
91 -
  font-size: 14px;
92 -
  line-height: 1.6;
93 -
}
90 +
## Shared Component Classes
94 91
95 -
html::-webkit-scrollbar {
96 -
  display: none;
97 -
}
98 -
```
99 -
100 -
## Layout
101 -
102 -
Single-column, centered, max 700px wide. No top body padding — top spacing comes from header `margin-top`:
103 -
104 -
```css
105 -
body {
106 -
  display: flex;
107 -
  flex-direction: column;
108 -
  justify-content: start;
109 -
  align-items: start;
110 -
  gap: 1.5rem;
111 -
  min-height: 100vh;
112 -
  max-width: 700px;
113 -
  margin: auto;
114 -
  padding: 0 1rem;
115 -
}
92 +
The stylesheet ships ready-to-use classes. Prefer these over writing new rules:
116 93
117 -
@media (max-width: 480px) {
118 -
  body {
119 -
    padding: 1rem;
120 -
    gap: 1rem;
121 -
  }
122 -
}
123 -
```
94 +
- Layout: `.header`, `.logo`, `.links`, `.footer`
95 +
- Forms: `.form`, `.form-row`, `.form-field`, `.form-actions`, `.checkbox-field`, `.switch`, `.switch-slider`
96 +
- Buttons: `button`, `.btn`, `.link-button`, `.link-button.danger`
97 +
- Lists: `.item-list` / `.item` / `.item-title` / `.item-meta`
98 +
- Admin lists: `.admin-list`, `.admin-list-item`, `.admin-toolbar`, `.admin-list-actions`
99 +
- Feedback: `.error`, `.success`, `.empty`
100 +
- Tags: `.tag`, `.status-badge`, `.status-published`, `.status-draft`
101 +
- Misc: `.spinner`, `.scroll-x`, `.hidden`, `.inline-form`
124 102
125 -
## Header
103 +
Visit `/darkmatter` on any app that mounts the crate to see live examples.
126 104
127 -
The header uses a border-bottom separator and `margin-top: 2rem` for top spacing. The site title/logo is **always uppercase**, 28px bold:
105 +
## Writing New Styles
128 106
129 -
```css
130 -
.header {
131 -
  display: flex;
132 -
  flex-direction: column;
133 -
  gap: 0.5rem;
134 -
  width: 100%;
135 -
  margin-top: 2rem;
136 -
  border-bottom: 1px solid #333;
137 -
  padding-bottom: 1rem;
138 -
}
107 +
Only add app-specific CSS when the shared sheet does not cover the pattern. When you do:
139 108
140 -
.logo {
141 -
  font-size: 28px;
142 -
  font-weight: 700;
143 -
  text-decoration: none;
144 -
  text-transform: uppercase;
145 -
}
146 -
```
147 -
148 -
## Navigation Links
149 -
150 -
Compact gap, small font:
151 -
152 -
```css
153 -
.links {
154 -
  display: flex;
155 -
  align-items: center;
156 -
  gap: 0.75rem;
157 -
  font-size: 12px;
158 -
}
159 -
```
160 -
161 -
## Interactive Elements
162 -
163 -
All inputs, textareas, and buttons match the background — they blend into the surface with only a white border. **No border-radius**, padding uses `0.4rem 0.75rem`:
164 -
165 -
```css
166 -
input, textarea {
167 -
  background: #121113;
168 -
  color: #ffffff;
169 -
  border: 1px solid white;
170 -
  padding: 0.4rem 0.75rem;
171 -
  font-size: 14px;
172 -
  width: 100%;
173 -
  border-radius: 0;
174 -
}
175 -
176 -
textarea {
177 -
  min-height: 400px;
178 -
  resize: vertical;
179 -
}
180 -
181 -
button {
182 -
  background: #121113;
183 -
  color: #ffffff;
184 -
  padding: 0.4rem 0.75rem;
185 -
  border: 1px solid white;
186 -
  cursor: pointer;
187 -
  width: fit-content;
188 -
  font-size: 14px;
189 -
  border-radius: 0;
190 -
}
191 -
192 -
button:hover, a:hover {
193 -
  opacity: 0.7;
194 -
}
195 -
196 -
a {
197 -
  color: #ffffff;
198 -
  text-decoration: none;
199 -
}
200 -
```
201 -
202 -
## Labels
203 -
204 -
```css
205 -
label {
206 -
  font-size: 12px;
207 -
  opacity: 0.7;
208 -
}
209 -
```
210 -
211 -
## Errors
212 -
213 -
Use a left border accent, not a full box border:
214 -
215 -
```css
216 -
.error {
217 -
  color: #ffffff;
218 -
  border-left: 2px solid #ffffff;
219 -
  padding-left: 0.5rem;
220 -
  font-size: 13px;
221 -
  opacity: 0.8;
222 -
}
223 -
```
224 -
225 -
## List Items
226 -
227 -
Vertical stacking with bottom borders as dividers, 16px title size:
228 -
229 -
```css
230 -
.item-list {
231 -
  display: flex;
232 -
  flex-direction: column;
233 -
  width: 100%;
234 -
}
235 -
236 -
.item {
237 -
  display: flex;
238 -
  flex-direction: column;
239 -
  gap: 0.25rem;
240 -
  padding: 0.75rem 0;
241 -
  border-bottom: 1px solid #333;
242 -
}
243 -
244 -
.item:hover {
245 -
  opacity: 0.7;
246 -
}
247 -
248 -
.item-title {
249 -
  font-size: 16px;
250 -
}
251 -
252 -
.item-meta {
253 -
  font-size: 12px;
254 -
  opacity: 0.5;
255 -
}
256 -
```
257 -
258 -
## Table Headers
259 -
260 -
Uppercase, dimmed, lightweight:
261 -
262 -
```css
263 -
th {
264 -
  opacity: 0.5;
265 -
  font-weight: 400;
266 -
  font-size: 12px;
267 -
  text-transform: uppercase;
268 -
}
269 -
```
270 -
271 -
## Meta Tags
272 -
273 -
Always include:
274 -
```html
275 -
<meta name="theme-color" content="#121113" />
276 -
```
109 +
- Match the palette and opacity scale above
110 +
- `border-radius: 0` everywhere
111 +
- Keep selectors shallow and class-based
112 +
- Prefer extending existing classes over inventing new ones
277 113
278 114
## What NOT to Do
279 115
280 -
- No `border-radius` — keep all corners sharp (explicitly set `border-radius: 0` on inputs/buttons)
116 +
- Do not copy Darkmatter CSS into an app's static assets — link the crate's `/assets/darkmatter.css` instead
117 +
- No `border-radius` — keep all corners sharp
281 118
- No box shadows or drop shadows
282 119
- No color other than `#121113`, `#ffffff`, and the gray tones (`#1e1c1f`, `#333`, `#555`)
283 120
- **No `color: #888`** — use `opacity` on white text for visual hierarchy instead
284 -
- No external font CDNs — fonts are self-hosted
121 +
- No external font CDNs — fonts come from the crate
285 122
- No utility frameworks (no Tailwind, no Bootstrap)
286 123
- No decorative elements, icons, or emojis