| 4 |
4 |
|
Build new UI by COMPOSING the existing vocabulary, in this order of preference:
|
| 5 |
5 |
|
|
| 6 |
6 |
|
1. Use a UTILITY class for one-off adjustments (.hidden, .sr-only,
|
| 7 |
|
- |
.mb-1, .flex-1 — most
|
| 8 |
|
- |
still to be added)
|
| 9 |
|
- |
2. Use a LAYOUT PRIMITIVE to position content (.row-flex, .row,
|
| 10 |
|
- |
.stack-{2,3,4} —
|
| 11 |
|
- |
to be added in F1/F2)
|
|
7 |
+ |
.mb-1, .mb-2, .flex-1,
|
|
8 |
+ |
.text-sm,
|
|
9 |
+ |
.text-sm-secondary)
|
|
10 |
+ |
2. Use a LAYOUT PRIMITIVE to position content (.row-flex +
|
|
11 |
+ |
.row-flex-{2,3,4},
|
|
12 |
+ |
.stack + .stack-{2,3,4})
|
| 12 |
13 |
|
3. Use a COMPONENT PRIMITIVE for a UI element (.btn, .card, .modal,
|
| 13 |
14 |
|
.form-input,
|
| 14 |
15 |
|
.form-select, .badge,
|
| 48 |
49 |
|
BAND: FOUNDATIONS
|
| 49 |
50 |
|
1. Design System Variables — tokens (:root)
|
| 50 |
51 |
|
2. CSS Reset & Base
|
|
52 |
+ |
2b. Utility Classes — layout primitives,
|
|
53 |
+ |
margin, text
|
| 51 |
54 |
|
3. Keyframes & Animation
|
| 52 |
55 |
|
|
| 53 |
56 |
|
BAND: APP SHELL & CHROME
|
| 157 |
160 |
|
--accent-yellow-light: color-mix(in oklch, var(--category-four) 82%, white);
|
| 158 |
161 |
|
--shadow-color: color-mix(in oklch, var(--content-muted) 88%, black);
|
| 159 |
162 |
|
--border-width: 2px; /* invariant */
|
|
163 |
+ |
--radius-xs: 3px; /* invariant — scrollbars, tiny elements */
|
| 160 |
164 |
|
--radius-sm: 5px; /* invariant */
|
| 161 |
165 |
|
--radius-lg: 10px; /* invariant */
|
| 162 |
166 |
|
--radius-xl: 20px; /* invariant */
|
|
167 |
+ |
--radius-full: 50%; /* invariant — circles */
|
| 163 |
168 |
|
--shadow-offset: 3px; /* invariant — BB neobrute signature */
|
| 164 |
169 |
|
--shadow-brutal: var(--shadow-offset) var(--shadow-offset) 0 var(--shadow-color); /* invariant composition */
|
|
170 |
+ |
|
|
171 |
+ |
/* Invariant scales (values shared with GO for cross-app portability;
|
|
172 |
+ |
never themed). Per-line `invariant` markers satisfy the lint
|
|
173 |
+ |
theme-token-coverage rule. radius-md intentionally absent (dropped as
|
|
174 |
+ |
a dup of radius-sm). */
|
|
175 |
+ |
--space-1: 0.25rem; /* invariant */
|
|
176 |
+ |
--space-2: 0.5rem; /* invariant */
|
|
177 |
+ |
--space-3: 0.75rem; /* invariant */
|
|
178 |
+ |
--space-4: 1rem; /* invariant */
|
|
179 |
+ |
--space-5: 1.25rem; /* invariant */
|
|
180 |
+ |
--space-6: 1.5rem; /* invariant */
|
|
181 |
+ |
--font-size-xxs: 0.65rem; /* invariant — tiny badges, indicators */
|
|
182 |
+ |
--font-size-xs: 0.7rem; /* invariant — small badges, counts */
|
|
183 |
+ |
--font-size-sm: 0.75rem; /* invariant — meta text, timestamps */
|
|
184 |
+ |
--font-size-md: 0.8rem; /* invariant — table headers, compact UI */
|
|
185 |
+ |
--font-size-base: 0.875rem; /* invariant — body text default */
|
|
186 |
+ |
--font-size-lg: 1rem; /* invariant — emphasized body text */
|
|
187 |
+ |
--font-size-xl: 1.1rem; /* invariant — subheadings */
|
|
188 |
+ |
--font-size-2xl: 1.25rem; /* invariant — section titles */
|
|
189 |
+ |
--font-size-3xl: 1.5rem; /* invariant — page titles */
|
|
190 |
+ |
--font-size-4xl: 1.75rem; /* invariant — main headings */
|
|
191 |
+ |
--line-height-tight: 1.25; /* invariant */
|
|
192 |
+ |
--line-height-normal: 1.5; /* invariant */
|
|
193 |
+ |
--line-height-relaxed: 1.75; /* invariant */
|
|
194 |
+ |
--transition-fast: 0.1s; /* invariant */
|
|
195 |
+ |
--transition-normal: 0.15s; /* invariant */
|
|
196 |
+ |
--transition-slow: 0.3s; /* invariant */
|
| 165 |
197 |
|
}
|
| 166 |
198 |
|
/* F5 cleanup (2026-06-02): dropped --bg-surface (themed but never consumed),
|
| 167 |
199 |
|
--radius-md (duplicate of --radius-sm), --shadow / --shadow-hover (derived
|
| 171 |
203 |
|
/* === 2. CSS Reset & Base ================================================ */
|
| 172 |
204 |
|
* { margin: 0; padding: 0; box-sizing: border-box; }
|
| 173 |
205 |
|
|
|
206 |
+ |
/* === 2b. Utility Classes ================================================
|
|
207 |
+ |
Compose-first layer (see header). Ported from GO's utility set; all consume
|
|
208 |
+ |
the shared --space-* / intent tokens. NOTE: `.row` is NOT a utility here —
|
|
209 |
+ |
BB uses `.row` as the renderRow COMPONENT base (see § Component Primitives).
|
|
210 |
+ |
For a raw centered flex row use `.row-flex`; for a column use `.stack`.
|
|
211 |
+ |
========================================================================== */
|
|
212 |
+ |
/* Layout primitives */
|
|
213 |
+ |
.flex-1 { flex: 1; }
|
|
214 |
+ |
.stack { display: flex; flex-direction: column; }
|
|
215 |
+ |
.stack-2 { gap: var(--space-2); }
|
|
216 |
+ |
.stack-3 { gap: var(--space-3); }
|
|
217 |
+ |
.stack-4 { gap: var(--space-4); }
|
|
218 |
+ |
.row-flex { display: flex; align-items: center; }
|
|
219 |
+ |
.row-flex-2 { gap: var(--space-2); }
|
|
220 |
+ |
.row-flex-3 { gap: var(--space-3); }
|
|
221 |
+ |
.row-flex-4 { gap: var(--space-4); }
|
|
222 |
+ |
|
|
223 |
+ |
/* Margin (values mirror GO exactly for drop-in ports) */
|
|
224 |
+ |
.mb-1 { margin-bottom: var(--space-4); }
|
|
225 |
+ |
.mb-2 { margin-bottom: var(--space-2); }
|
|
226 |
+ |
|
|
227 |
+ |
/* Text */
|
|
228 |
+ |
.text-sm { font-size: var(--font-size-sm); }
|
|
229 |
+ |
.text-sm-secondary { font-size: var(--font-size-sm); color: var(--content-secondary); }
|
|
230 |
+ |
|
| 174 |
231 |
|
/* === 4. Layout shell — body & #app ==================================== */
|
| 175 |
232 |
|
body {
|
| 176 |
233 |
|
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, sans-serif;
|