Skip to main content

max / makenotwork

Adopt .well, .raised and .segment; the server used none of the three Wave 2 tier B3. All three generated primitives had zero uses in the markup while the stylesheet hand-wrote what each of them says. .raised, 60 sites. The canonical panel — .content-section and its eight siblings (import form, import progress, library section, library downloads, downloads hero, receipt box, disclaimer box, project sections) — declared `background: var(--surface-overlay)` and no edge. They take .raised now, so the fill and the bevel are layout.css's and the local rule is spacing only. The fill moves --surface-overlay to --surface-raised, equal on the platform default and separable by a theme, the same move .card and .buy-card made. .well, 30 sites, and it is the one M1 added surface-well FOR. Every list container: .data-table, .results-table, .feed-results-table. GoingsOn's four list containers (G4, goingson@4f28357) and Balanced Breakfast's two took the class the same way, keeping their component class and adding .well beside it, so this follows the precedent rather than deciding fresh. Doing it turned up eight rules that never did anything. .data-table, .feed-page .table-row, .library-page .feed-table-row and .table-row each had a :nth-child(odd) and a :nth-child(even) rule setting THE SAME VALUE, --surface-overlay. So there was no zebra, and the effect was every row painted the colour of the panel behind it, which is the exact "bands on a panel" a well fixes. Deleted; the rows sit on the well unpainted now. makeover derives no row-stripe intent, so if striping is ever wanted it is a makeover-side question rather than a literal here. .segment, 12 sites. The task allowed that it might have no analogue here. It does: .time-selector, the 7d/30d/90d/All range control on the three analytics tabs, is a segmented control. Its selected state was a --primary-dark fill with a --primary-light label, a second thing meaning "chosen" beside the generated .chosen, which presses the segment IN (well fill, inset bevel). Taking the generated one. As with the tabs the NAME stays .is-selected, because that is one idiom across a dozen components here and the JS reads it. Charter updated: the panel and table rows, and the Shadow row, which still documented the --shadow-1/2/3 scale B5 deleted.
Author: Max Johnson <me@maxj.phd> · 2026-08-10 16:20 UTC
Signed with PGP, not checked
Commit: 2d79ea2293b0077bbba58acb8a25d1f01662cb09
Parent: e5ab32c
46 files changed, +129 insertions, -126 deletions
@@ -16,7 +16,7 @@
16 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) |
17 17 | Radius | `--radius-square` (0, containers: cards, panels, dropdowns), `--radius-fine` (2px, inline code, small badges), `--radius-control` (4px, buttons, inputs, selects), `--radius-panel` (8px, media covers, callout boxes), `--radius-round` (50%), named for what the corner belongs to | `geometry.css` (generated by makeover-build) |
18 18 | Stacking | `--z-raised` / `--z-nav` / `--z-header` / `--z-dropdown` / `--z-picker` / `--z-context` / `--z-overlay` / `--z-modal` / `--z-toast` / `--z-banner` / `--z-skip-link`, in that order, named for what floats over what | `style.css:213-228` |
19 - | 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` |
19 + | Shadow | Two kinds, and only two. A surface IN the page takes a bevel, an edge rather than a distance: `--shadow-raised` (buttons, tabs), `--shadow-card` (cards, panels), `--shadow-inset` (inputs, recessed), all aliasing the `--bevel-raised` / `--bevel-inset` pair from `layout.css`. A surface floating OVER the page takes `--elevation-overlay`, also generated: menus, toasts, popovers, dropdowns and pickers float; a card, a plate and a framed image do not, and are `.raised`. A consumer needing different blur geometry composes it from `var(--elevation)`, never from a literal. The old `--shadow-1/-2/-3` blurred scale was rgba-black literals picked against parchment and is gone (wave 2 tier B5). | `style.css` `:root`, `layout.css` |
20 20
21 21 Every colour outside `:root` is a `var()` or a `color-mix()` over one; there are no hex or `rgba()` literals in the stylesheets at all. Write the token, not a `var(--token, #fallback)`: nine of those named tokens that never existed and quietly rendered their hardcoded fallback on all 31 themes. Pure `#000` and `#fff` are forbidden outside the token table. Bootstrap-derived yellows (`#fff3cd`, `#ffc107`) are forbidden. Use `--warning-bg` / `--warning-border`.
22 22
@@ -91,7 +91,7 @@
91 91
92 92 | Primitive | Canonical class | Variants | States |
93 93 |---|---|---|---|
94 - | Page section box | `.content-section` | (none) | — |
94 + | Page section box | `.content-section` + `.raised` | (none) | — |
95 95 | Card | `.card` | `.card-muted` (surface-muted fill), `.card--bordered`, `.card--selectable` (+ `.is-text-heavy` for left-aligned content) | `:hover`, `:focus-within`, `.is-selected`, `.is-disabled` |
96 96 | Button | `.btn-primary` / `.btn-secondary` / `.btn-danger` | `.btn--large`, `.btn--icon`, `.btn--link`, `.small`, `.saved` | `:hover`, `:focus-visible`, `:disabled`, `.htmx-request` |
97 97 | Heading | `.brand-h1` (wordmark), `.page-title` (h1), `.subtitle-h2` (auth/wizard h2), `.subsection-title` (default h2), `.section-header` (h2 with bottom border) | — | — |
@@ -112,7 +112,7 @@
112 112 | Progress bar | `.progress-bar-container` + `.progress-bar` | `--slim` (6px), `--rounded`, `.progress-bar--highlight` (purple, default green) | — |
113 113 | Upload status block | `.upload-status` + `-row` | `-msg.is-success`, `-msg.is-error` | — |
114 114 | Status pill | `.field-status` / `.save-status` | `.success`, `.error`, `.saving` | — |
115 - | Table | `.data-table` (rich), `.compact-table` (small mono) | `.minw-300..800` for horizontal scroll min-width | `.sortable.ascending`, `.sortable.descending` |
115 + | Table | `.data-table` + `.well` (rich), `.compact-table` (small mono) | `.minw-300..800` for horizontal scroll min-width | `.sortable.ascending`, `.sortable.descending` |
116 116 | Tabs | `.tabs` + `.tab` | — | `.tab.is-selected` |
117 117 | Breadcrumb | `.breadcrumb` | — | — |
118 118 | Pagination | `_ui.html` macro `pagination` → `.pagination` | — | `.active` |
@@ -905,13 +905,12 @@
905 905 transition: background 0.1s ease;
906 906 }
907 907
908 - .data-table tbody tr:nth-child(odd) {
909 - background: var(--surface-overlay);
910 - }
911 -
912 - .data-table tbody tr:nth-child(even) {
913 - background: var(--surface-overlay);
914 - }
908 + /* No zebra. There were two rules here, :nth-child(odd) and (even), and both
909 + set --surface-overlay — the same value, so the stripe never existed and the
910 + effect was every row painted the panel's own colour. The table is a .well
911 + now and the rows sit on it unpainted, which is what the banding was
912 + reaching for. makeover derives no row-stripe intent, so if one is ever
913 + wanted it is a makeover-side question, not a literal here. */
915 914
916 915 .data-table tbody tr:hover {
917 916 background: var(--surface-sunken);
@@ -3403,8 +3402,6 @@
3403 3402 }
3404 3403
3405 3404 .feed-page .table-row:last-child { border-bottom: none; }
3406 - .feed-page .table-row:nth-child(odd) { background: var(--surface-overlay); }
3407 - .feed-page .table-row:nth-child(even) { background: var(--surface-overlay); }
3408 3405 .feed-page .table-row:hover { background: var(--surface-sunken); }
3409 3406
3410 3407 .feed-page .item-name-cell {
@@ -3871,8 +3868,6 @@
3871 3868 transition: background 0.1s ease;
3872 3869 }
3873 3870 .library-page .feed-table-row:last-child { border-bottom: none; }
3874 - .library-page .feed-table-row:nth-child(odd) { background: var(--surface-overlay); }
3875 - .library-page .feed-table-row:nth-child(even) { background: var(--surface-overlay); }
3876 3871 .library-page .feed-table-row:hover { background: var(--surface-sunken); }
3877 3872 .library-page .feed-item-name-cell {
3878 3873 display: flex;
@@ -4382,6 +4377,11 @@
4382 4377 space. One of these in the codebase. Aliased to the per-page class names
4383 4378 that were just relabels of this same shape. Templates can use the alias
4384 4379 name OR add `.content-section` as a co-class. */
4380 + /* The canonical panel. Every one of these carries `.raised` in the markup
4381 + now, so the fill and the bevel come from layout.css and this rule is the
4382 + spacing only. The background it used to declare was --surface-overlay,
4383 + which .raised spells --surface-raised; equal on the platform default and a
4384 + theme may set them apart, the same move .card and .buy-card made. */
4385 4385 .content-section,
4386 4386 .import-page .import-form,
4387 4387 .import-page .import-progress,
@@ -4391,7 +4391,6 @@
4391 4391 .receipt-page .receipt-box,
4392 4392 .stripe-disclaimer-page .disclaimer-box,
4393 4393 .project-page .project-sections {
4394 - background: var(--surface-overlay);
4395 4394 padding: var(--gap-page);
4396 4395 margin-bottom: var(--gap-page);
4397 4396 }
@@ -4796,20 +4795,26 @@
4796 4795 gap: var(--gap-peer);
4797 4796 }
4798 4797
4798 + /* The range buttons are makeover's `.segment`, which is what a segmented
4799 + control is called there, and B3's question about whether this codebase has
4800 + an analogue: it does, and this is it. Fill, bevel, hover, active and focus
4801 + are the generated ones; this rule is geometry and type.
4802 +
4803 + Selection was a --primary-dark fill with a --primary-light label, which is
4804 + a second thing meaning "chosen" beside the generated `.chosen` (the segment
4805 + presses IN — well fill, inset bevel). Taking the generated one; only the
4806 + name stays local, same as the tabs. */
4799 4807 .time-selector button {
4800 - background: var(--surface-overlay);
4801 4808 border: none;
4802 4809 padding: var(--gap-peer) var(--gap-section);
4803 4810 font-family: inherit;
4804 4811 font-size: var(--text-note);
4805 4812 cursor: pointer;
4806 - opacity: 0.6;
4807 4813 }
4808 4814
4809 4815 .time-selector button.is-selected {
4810 - opacity: 1;
4811 - background: var(--primary-dark);
4812 - color: var(--primary-light);
4816 + background: var(--surface-well, var(--surface-page));
4817 + box-shadow: var(--bevel-inset);
4813 4818 }
4814 4819
4815 4820 /* Analytics */
@@ -7874,8 +7879,6 @@
7874 7879 .table-row-item .row-save { display: flex; align-items: center; justify-content: center; }
7875 7880 .table-row.project-row { grid-template-columns: 1fr 100px 80px 70px; }
7876 7881 .table-row:last-child { border-bottom: none; }
7877 - .table-row:nth-child(odd) { background: var(--surface-overlay); }
7878 - .table-row:nth-child(even) { background: var(--surface-overlay); }
7879 7882 .table-row:hover { background: var(--surface-sunken); text-decoration: none; }
7880 7883 .row-type { font-size: var(--text-fine); background: var(--surface-sunken); padding: var(--gap-bound) var(--gap-peer); text-align: center; opacity: 0.7; }
7881 7884 .row-info { min-width: 0; display: flex; flex-direction: column; gap: var(--gap-bound); }
@@ -14,7 +14,7 @@
14 14 <p class="subtitle">Import subscribers, items, and transaction history from other platforms.</p>
15 15 </header>
16 16
17 - <div class="import-form">
17 + <div class="import-form raised">
18 18 <div class="form-group">
19 19 <label for="import-project">Project</label>
20 20 <select id="import-project">
@@ -69,8 +69,8 @@
69 69 </div>
70 70 </div>
71 71
72 - <div class="import-progress hidden" id="import-progress">
73 - <p class="import-progress-label">Importing...</p>
72 + <div class="import-progress hidden raised" id="import-progress">
73 + <p class="import-progress-label raised">Importing...</p>
74 74 <div class="progress-bar-container my-section">
75 75 <div class="progress-bar progress-bar--highlight" id="progress-bar"></div>
76 76 </div>
@@ -16,7 +16,7 @@
16 16 {% endif %}
17 17
18 18 {% if seller_groups.is_empty() %}
19 - <div class="content-section cart-empty">
19 + <div class="content-section cart-empty raised">
20 20 <p class="muted mb-section">Your cart is empty.</p>
21 21 <p class="cart-empty-hint">Add items from the Discover page or from your wishlist.</p>
22 22 <a href="/discover" class="btn-primary">Browse Discover</a>
@@ -47,14 +47,14 @@
47 47 {% endif %}
48 48
49 49 {% for group in seller_groups %}
50 - <div class="content-section cart-group">
50 + <div class="content-section cart-group raised">
51 51 <h2 class="cart-group-title">
52 52 <a href="/u/{{ group.seller_username }}">{{ group.seller_username }}</a>
53 53 </h2>
54 54 <p class="cart-group-count">{{ group.item_count }} item{% if group.item_count != 1 %}s{% endif %}</p>
55 55
56 56 <div class="scroll-x">
57 - <table class="data-table minw-400">
57 + <table class="data-table minw-400 well">
58 58 <thead>
59 59 <tr>
60 60 <th>Item</th>
@@ -168,11 +168,11 @@
168 168 {% endif %}
169 169
170 170 {% if !wishlist_suggestions.is_empty() %}
171 - <div class="content-section cart-wishlist">
171 + <div class="content-section cart-wishlist raised">
172 172 <h2 class="section-header">From your wishlist</h2>
173 173 <p class="section-lead text-sm dimmed">Add wishlisted items to your cart to buy them together.</p>
174 174 <div class="scroll-x">
175 - <table class="data-table minw-400">
175 + <table class="data-table minw-400 well">
176 176 <thead>
177 177 <tr>
178 178 <th>Item</th>
@@ -22,7 +22,7 @@
22 22 <span class="col-right">Price</span>
23 23 <span class="col-right">Date</span>
24 24 </div>
25 - <div class="results-table">
25 + <div class="results-table well">
26 26 {% for item in items %}
27 27 <a href="/i/{{ item.id }}" class="table-row">
28 28 <span class="badge">{{ item.item_type }}</span>
@@ -71,7 +71,7 @@
71 71 <div class="item-layout{% if item.cover_image_url.is_none() && item.item_type != "video" %} no-media{% endif %}">
72 72 {% match item.content %}
73 73 {% when ItemContent::Video with { video_s3_key, cover_url, .. } %}
74 - <div class="item-media content-section">
74 + <div class="item-media content-section raised">
75 75 <div id="video-container">
76 76 <video id="item-player" controls preload="metadata"
77 77 {% if let Some(url) = cover_url %}poster="{{ url }}"{% endif %}
@@ -82,7 +82,7 @@
82 82 </div>
83 83 {% when _ %}
84 84 {% if item.cover_image_url.is_some() %}
85 - <div class="item-media content-section">
85 + <div class="item-media content-section raised">
86 86 {% if let Some(img) = item.cover_image_url %}
87 87 <img src="{{ img }}" alt="{{ item.title }}" class="item-cover-img">
88 88 {% endif %}
@@ -90,7 +90,7 @@
90 90 {% endif %}
91 91 {% endmatch %}
92 92
93 - <div class="item-details content-section">
93 + <div class="item-details content-section raised">
94 94 <h1 class="item-title">{{ item.title }}</h1>
95 95 <div class="item-creator">
96 96 by <a href="/u/{{ creator_username }}">{{ creator_username }}</a>
@@ -213,12 +213,12 @@
213 213 </div>
214 214
215 215 {% if !gallery.is_empty() %}
216 - <section class="item-gallery content-section">
216 + <section class="item-gallery content-section raised">
217 217 {% call carousel::carousel("item-gallery", gallery) %}{% endcall %}
218 218 </section>
219 219 {% endif %}
220 220
221 - <section class="item-description content-section">
221 + <section class="item-description content-section raised">
222 222 <h2 class="section-header">Description</h2>
223 223 <div>
224 224 <p>{{ item.description }}</p>
@@ -226,7 +226,7 @@
226 226 </section>
227 227
228 228 {% if !sections.is_empty() %}
229 - <section class="item-sections content-section">
229 + <section class="item-sections content-section raised">
230 230 <div class="section-tabs">
231 231 {% for section in sections %}
232 232 <button class="section-tab{% if loop.first %} is-selected{% endif %}"
@@ -243,7 +243,7 @@
243 243 {% endif %}
244 244
245 245 {% if item.license_preset.is_some() %}
246 - <section class="item-description content-section">
246 + <section class="item-description content-section raised">
247 247 <h2 class="section-header">License</h2>
248 248 <p class="license-preset-name">
249 249 {% if item.license_preset.as_deref() == Some("personal_use") %}Personal Use Only
@@ -270,7 +270,7 @@
270 270 {% endif %}
271 271
272 272 {% if !bundle_items.is_empty() %}
273 - <section class="bundle-contents content-section">
273 + <section class="bundle-contents content-section raised">
274 274 <h2 class="section-header">What's Included ({{ bundle_items.len() }} items)</h2>
275 275 {% for child in bundle_items %}
276 276 <div class="bundle-child list-row">
@@ -115,7 +115,7 @@
115 115 {% endif %}
116 116
117 117 {% if !versions.is_empty() %}
118 - <section class="library-downloads">
118 + <section class="library-downloads raised">
119 119 <h3>Source files</h3>
120 120 {% for version in versions %}
121 121 {% if version.has_file %}
@@ -36,7 +36,7 @@
36 36 </div>
37 37
38 38 {% if !versions.is_empty() %}
39 - <section class="downloads-hero">
39 + <section class="downloads-hero raised">
40 40 <h2 class="section-header">Downloads</h2>
41 41 {% for version in versions %}
42 42 {% if version.has_file %}
@@ -67,7 +67,7 @@
67 67 {% endif %}
68 68
69 69 {% if !bundle_items.is_empty() %}
70 - <section class="library-section">
70 + <section class="library-section raised">
71 71 <h2 class="section-header">Included in this bundle ({{ bundle_items.len() }})</h2>
72 72 {% for child in bundle_items %}
73 73 <div class="bundle-child">
@@ -81,7 +81,7 @@
81 81 {% endif %}
82 82
83 83 {% if !item.description.is_empty() %}
84 - <section class="library-section">
84 + <section class="library-section raised">
85 85 <details>
86 86 <summary class="lib-summary">Description</summary>
87 87 <div class="lib-summary-body">
@@ -92,7 +92,7 @@
92 92 {% endif %}
93 93
94 94 {% if !sections.is_empty() %}
95 - <section class="library-section">
95 + <section class="library-section raised">
96 96 <div class="section-tabs">
97 97 {% for section in sections %}
98 98 <button class="section-tab{% if loop.first %} is-selected{% endif %}"
@@ -109,7 +109,7 @@
109 109 {% endif %}
110 110
111 111 {% if item.license_preset.is_some() %}
112 - <section class="library-section">
112 + <section class="library-section raised">
113 113 <h2 class="section-header">License</h2>
114 114 <p class="lib-license-name">
115 115 {% if item.license_preset.as_deref() == Some("personal_use") %}Personal Use Only
@@ -109,7 +109,7 @@
109 109 {% endif %}
110 110
111 111 {% if !versions.is_empty() %}
112 - <section class="library-downloads">
112 + <section class="library-downloads raised">
113 113 <h3>Source files</h3>
114 114 {% for version in versions %}
115 115 {% if version.has_file %}
@@ -98,7 +98,7 @@
98 98 {% endif %}
99 99
100 100 {% if !sections.is_empty() %}
101 - <section class="project-sections">
101 + <section class="project-sections raised">
102 102 <div class="section-tabs">
103 103 {% for section in sections %}
104 104 <button class="section-tab{% if loop.first %} is-selected{% endif %}"
@@ -8,7 +8,7 @@
8 8 <h1 class="brand-h1">Makenot<span class="dot">.</span>work</h1>
9 9 <p class="tagline">Fair distribution for creatives of all kinds<span class="dot">.</span></p>
10 10
11 - <div class="checkout-box content-section">
11 + <div class="checkout-box content-section raised">
12 12 <div class="step-indicator">Step 2 of 2</div>
13 13 <h2 class="section-header">Confirm Purchase</h2>
14 14
@@ -9,7 +9,7 @@
9 9 <div class="container">
10 10 <a href="/library" class="back-link">&larr; Back to Library</a>
11 11
12 - <div class="receipt-box">
12 + <div class="receipt-box raised">
13 13 <div class="receipt-header">
14 14 <div>
15 15 <h1 class="page-title">Receipt</h1>
@@ -8,7 +8,7 @@
8 8 <h1 class="stripe-disclaimer-title">Makenot<span class="dot">.</span>work</h1>
9 9 <p class="tagline">Fair distribution for creatives of all kinds<span class="dot">.</span></p>
10 10
11 - <div class="disclaimer-box">
11 + <div class="disclaimer-box raised">
12 12 <h2 class="section-header">Before You Connect with Stripe</h2>
13 13 <p class="stripe-disclaimer-lead">
14 14 Please review the following information about payment processing and your responsibilities as a creator.