max / makenotwork
1 file changed,
+43 insertions,
-7 deletions
| @@ -11,16 +11,20 @@ | |||
| 11 | 11 | | Tier | Token group | Where defined | | |
| 12 | 12 | |---|---|---| | |
| 13 | 13 | | Color | `--background`, `--detail`, `--highlight`, `--light-background`, surface family, `--text-muted`, `--border`, semantic (`--success/-bg`, `--warning/-bg/-border`, `--danger/-bg`, `--error/-bg`), `--stripe`, health (`--health-ok/-warn/-error/-unknown`), diff (`--diff-add/-bg`, `--diff-del/-bg`), `--focus-ring`, `--highlight-faint`, `--overlay` | `style.css:40-95` | | |
| 14 | - | | Type | `--font-heading` (Young Serif), `--font-mono` (IBM Plex Mono), `--font-body` (Lato) | `style.css:42-44` | | |
| 14 | + | | Typeface | `--font-heading` (Young Serif), `--font-mono` (IBM Plex Mono), `--font-body` (Lato) | `style.css:42-44` | | |
| 15 | + | | Type size | `--text-fine` / `--text-note` / `--text-body` / `--text-lead` / `--text-subhead` / `--text-head` / `--text-title` / `--text-display` / `--text-hero`, named for what the text is, not the size | `geometry.css` (generated by makeover-build) | | |
| 15 | 16 | | Spacing | `--gap-bound` / `--gap-peer` / `--gap-group` / `--gap-section` / `--gap-pane` / `--gap-page`, named for the relationship they express, not the size | `geometry.css` (generated by makeover-build) | | |
| 16 | 17 | | Radius | `--radius-sm` (4px, controls: buttons, inputs, chips, badges), `--radius-md` (0, containers: cards, panels, dropdowns), `--radius-round` (50%) | `style.css:216-222` | | |
| 17 | 18 | | Shadow | Everyday depth: `--shadow-raised` (buttons, tabs), `--shadow-card` (cards, panels), `--shadow-inset` (inputs, recessed). All three alias the bevel pair `--bevel-raised` / `--bevel-inset` from `layout.css`, which makeover derives from each theme's own raised surface. Blurred (true elevation, floats over page): `--shadow-1` (subtle), `--shadow-2` (raised), `--shadow-3` (modal/overlay). | `style.css:224-243` | | |
| 18 | 19 | ||
| 19 | 20 | Pure `#000` and `#fff` are forbidden outside the token table. Bootstrap-derived yellows (`#fff3cd`, `#ffc107`) are forbidden. Use `--warning-bg` / `--warning-border`. | |
| 20 | 21 | ||
| 21 | - | ## Type tiers (from `brand.md`) | |
| 22 | + | ## Type | |
| 22 | 23 | ||
| 23 | - | Every text element maps to exactly one tier: | |
| 24 | + | Two independent choices, and every text element makes both: which typeface, and | |
| 25 | + | which size. | |
| 26 | + | ||
| 27 | + | ### Typeface tiers (from `brand.md`) | |
| 24 | 28 | ||
| 25 | 29 | - **H1 / wordmark / section heads**: `--font-heading` (Young Serif), `normal` weight, color `--detail`. | |
| 26 | 30 | - **H2 / H3 / meta / taglines / footer**: `--font-mono` (IBM Plex Mono), `normal` weight. | |
| @@ -28,6 +32,37 @@ | |||
| 28 | 32 | ||
| 29 | 33 | No fourth typeface. No `font-family` declarations in templates. | |
| 30 | 34 | ||
| 35 | + | ### Size tiers | |
| 36 | + | ||
| 37 | + | Nine, generated from makeover-geometry as ratios of `--geometry-base`, so every | |
| 38 | + | size tracks the reader's own root font size. Named for what the text is, on the | |
| 39 | + | same argument as `--gap-*`: whether a caption should be 13px or 14px cannot be | |
| 40 | + | reviewed, whether a piece of text is a caption can. | |
| 41 | + | ||
| 42 | + | | Token | What it is | At the default base | | |
| 43 | + | |---|---|---| | |
| 44 | + | | `--text-fine` | timestamps, badges, legal lines | 12px | | |
| 45 | + | | `--text-note` | metadata, table cells, captions, form help | 14px | | |
| 46 | + | | `--text-body` | running copy | 16px | | |
| 47 | + | | `--text-lead` | emphasised copy, card titles | 18px | | |
| 48 | + | | `--text-subhead` | h3 | 20px | | |
| 49 | + | | `--text-head` | h2, section heads | 24px | | |
| 50 | + | | `--text-title` | h1, page titles | 32px | | |
| 51 | + | | `--text-display` | display copy | 40px | | |
| 52 | + | | `--text-hero` | a landing hero, at most one per page | 48px | | |
| 53 | + | ||
| 54 | + | Nothing below `--text-fine`. A size under 12px is a legibility problem rather | |
| 55 | + | than a tier; text that should recede does it with colour or weight. | |
| 56 | + | ||
| 57 | + | Sizes do not shift under a coarse pointer, unlike spacing. Density is a claim | |
| 58 | + | about the contact patch and text is not a tap target, so a phone gets the same | |
| 59 | + | tiers a desktop does and the reader's root size is the knob. | |
| 60 | + | ||
| 61 | + | The `em` unit is banned for font sizes: it compounds against whatever the parent | |
| 62 | + | happens to be, so the same rule renders at different sizes depending on where it | |
| 63 | + | is used. Where text needs to sit one rung below its container (inline `code` | |
| 64 | + | inside long-form copy), name the rung. | |
| 65 | + | ||
| 31 | 66 | ## Components: canonical primitive table | |
| 32 | 67 | ||
| 33 | 68 | For each primitive, exactly one canonical class **or** one canonical partial. Variants are class modifiers; nothing else. | |
| @@ -141,10 +176,11 @@ | |||
| 141 | 176 | 6. **Empty / error / loading states use the shared partial.** Never assemble these inline. | |
| 142 | 177 | 7. **Destructive actions** use `.danger` button class plus the `confirm_dialog` macro. No bare destructive buttons. | |
| 143 | 178 | 8. **Spacing values come from `--gap-*` tokens.** Pick the one that names what the rule separates: `bound` inside a thing, `peer` between siblings, `group` between related controls, `section` between parts of a pane, `pane` between panes, `page` at page level. Raw values and off-scale values are bugs. The tokens are generated from makeover-geometry and shift under a coarse pointer, so a hardcoded value silently opts that rule out of touch density. | |
| 144 | - | 9. **Page-scoped CSS is a last resort.** Default to composing layout + component primitives. Page-scoped sections exist for genuinely page-specific layout (grids, long-form typography, marketing heroes), not for shapes that are cards or list rows in disguise. | |
| 145 | - | 10. **No bare `<h1>` / `<h2>` in templates.** Pick a heading class: `.brand-h1` (wordmark), `.page-title` (page h1), `.subtitle-h2` (page subtitle on auth/wizards), `.subsection-title` (default h2 inside dashboards/tabs/partials), or `.section-header` (prose sub-section with bottom border). Bare tags inside server-rendered markdown / user content (e.g. `partials/item_text_editor.html` JS preview) are the only exception. | |
| 146 | - | 11. **Button class is `.btn-primary` / `.btn-secondary` / `.btn-danger`.** Works on both `<button>` and `<a>` (the `<a><button>` antipattern is banned. Use `<a class="btn-primary">…</a>`). The bare `button.primary` shorthand has been retired. | |
| 147 | - | 12. **Class names use kebab-case only.** No BEM `__` separator (retired 2026-05-20, was 112 sites across 20 prefixes, now flattened to single-dash). Modifier `--` (e.g. `.card--bordered`) is still allowed. | |
| 179 | + | 9. **Font sizes come from `--text-*` tokens.** Pick the one that names what the text is: `fine` for timestamps and badges, `note` for metadata and table cells, `body` for running copy, `lead` for emphasised copy and card titles, `subhead` / `head` / `title` for the three heading levels, `display` and `hero` above the hierarchy. Raw values and off-scale values are bugs, including a value that differs from a tier by a fraction of a pixel. Nothing sits below `fine`: text that should recede does it with colour or weight. | |
| 180 | + | 10. **Page-scoped CSS is a last resort.** Default to composing layout + component primitives. Page-scoped sections exist for genuinely page-specific layout (grids, long-form typography, marketing heroes), not for shapes that are cards or list rows in disguise. | |
| 181 | + | 11. **No bare `<h1>` / `<h2>` in templates.** Pick a heading class: `.brand-h1` (wordmark), `.page-title` (page h1), `.subtitle-h2` (page subtitle on auth/wizards), `.subsection-title` (default h2 inside dashboards/tabs/partials), or `.section-header` (prose sub-section with bottom border). Bare tags inside server-rendered markdown / user content (e.g. `partials/item_text_editor.html` JS preview) are the only exception. | |
| 182 | + | 12. **Button class is `.btn-primary` / `.btn-secondary` / `.btn-danger`.** Works on both `<button>` and `<a>` (the `<a><button>` antipattern is banned. Use `<a class="btn-primary">…</a>`). The bare `button.primary` shorthand has been retired. | |
| 183 | + | 13. **Class names use kebab-case only.** No BEM `__` separator (retired 2026-05-20, was 112 sites across 20 prefixes, now flattened to single-dash). Modifier `--` (e.g. `.card--bordered`) is still allowed. | |
| 148 | 184 | ||
| 149 | 185 | ## How to extend | |
| 150 | 186 |