Retheme on Linear's neutral palette and restore light mode The palette was tinted -- chroma ~.03-.07 around hue 263-266 -- so every surface, border and muted text read blue. Replaced with Linear's ramp, taken from a saved copy of their docs: #08090a page, #0f1011 canvas, #141516 raised, #f7f8f8 ink, #23252a/#34343a borders. Neutral to faintly cool, never blue. Light mode returns. Linear publishes no light palette, so it is derived in the same language rather than copied: same neutral discipline, same surface-ladder direction (raised stays lighter than void, which inverts to white cards on a grey page), ink flipped to their darkest value. Only the primitives and four literal exceptions are restated for light. The icon tiers, washes, hover surface and inverse control are all color-mix(... var(--text-ink) N% ...) and invert on their own -- the ladder was built for this even though nothing had used it yet. The inverse control becomes a dark fill with light glyph in light mode without being told. Theme selection is a three-rung segmented control in both command bars. The active rung cannot be rendered server-side because the choice lives in localStorage, so the head script records it as data-theme-choice and the CSS expresses the selection. That script is deliberately not deferred: resolving the theme after the stylesheet paints produces a flash of the wrong theme. "System" stores nothing and clears data-theme so the prefers-color-scheme fallback governs; an explicit choice always wins. Built on basecoat's button-group, whose inline-flex/w-fit shrink-wrap is what the previous toggle lacked when it stretched across its container. Two fixes found on the way: - .audio-player hardcoded color-scheme: dark, which would have put a dark native scrubber on a white card in light mode. Now inherits. - Documented a real name collision: basecoat's base.css also defines --accent, but as shadcn does -- a subtle hover background, not a brand color. Ours wins on cascade order, and only combobox/dropdown-menu/select consume basecoat's meaning, none of which are imported. Importing one would give it an indigo hover surface. The CSS contract test asserted the cascade contained no data-theme or prefers-color-scheme at all. That was the right guard for proving DaisyUI's theme plugin was gone, but it forbade all theming including ours. Replaced the prohibition with a positive contract: both themes must compile, the no-JS fallback must compile, and no third theme may appear.
Retheme on Linear's neutral palette and restore light mode
Deploy story
What this commit did to the running system — joined from the forge receipt chain, the part a commit page elsewhere cannot show.
Not deployed through the forge lane
No push, promotion, build, or deploy receipt references this commit (receipts are scanned over a bounded recent window). Changes shipped by full node replacement carry their proof in the release gate receipt instead.
Changed files
-
modified
assets/css/app.css -
modified
assets/css/openagents.css -
modified
assets/test/css_contract_test.mjs -
modified
lib/openagents_web/components/layouts.ex -
modified
lib/openagents_web/components/layouts/root.html.heex
Diff
5 files changed, +195 -28
assets/css/app.css modified +120 -26
@@ -26,6 +26,7 @@
| 26 | 26 |
|
| 27 | 27 |
|
| 28 | 28 |
|
| 29 |
|
|
| 29 | 30 |
|
| 30 | 31 |
|
| 31 | 32 |
|
@@ -69,31 +70,50 @@
| 69 | 70 |
|
| 70 | 71 |
|
| 71 | 72 |
|
| 72 |
|
|
| 73 |
|
|
| 73 |
|
|
| 74 |
|
|
| 75 |
|
|
| 76 |
|
|
| 77 |
|
|
| 78 |
|
|
| 79 |
|
|
| 80 |
|
|
| 81 |
|
|
| 74 | 82 |
|
| 75 | 83 |
|
| 76 | 84 |
|
| 77 | 85 |
|
| 78 |
|
|
| 79 |
|
|
| 80 |
|
|
| 81 |
|
|
| 82 |
|
|
| 83 |
|
|
| 84 |
|
|
| 85 |
|
|
| 86 |
|
|
| 87 |
|
|
| 88 |
|
|
| 89 |
|
|
| 90 |
|
|
| 91 |
|
|
| 92 |
|
|
| 86 |
|
|
| 87 |
|
|
| 88 |
|
|
| 89 |
|
|
| 90 |
|
|
| 91 |
|
|
| 92 |
|
|
| 93 |
|
|
| 94 |
|
|
| 95 |
|
|
| 96 |
|
|
| 97 |
|
|
| 98 |
|
|
| 99 |
|
|
| 100 |
|
|
| 101 |
|
|
| 102 |
|
|
| 103 |
|
|
| 104 |
|
|
| 105 |
|
|
| 106 |
|
|
| 107 |
|
|
| 108 |
|
|
| 109 |
|
|
| 110 |
|
|
| 111 |
|
|
| 112 |
|
|
| 93 | 113 |
|
| 94 |
|
|
| 95 |
|
|
| 96 |
|
|
| 114 |
|
|
| 115 |
|
|
| 116 |
|
|
| 97 | 117 |
|
| 98 | 118 |
|
| 99 | 119 |
|
@@ -114,19 +134,72 @@
| 114 | 134 |
|
| 115 | 135 |
|
| 116 | 136 |
|
| 117 |
|
|
| 137 |
|
|
| 118 | 138 |
|
| 119 | 139 |
|
| 120 | 140 |
|
| 121 |
|
|
| 122 |
|
|
| 123 |
|
|
| 124 |
|
|
| 141 |
|
|
| 142 |
|
|
| 125 | 143 |
|
| 126 | 144 |
|
| 127 |
|
|
| 145 |
|
|
| 146 |
|
|
| 147 |
|
|
| 148 |
|
|
| 149 |
|
|
| 150 |
|
|
| 151 |
|
|
| 152 |
|
|
| 153 |
|
|
| 154 |
|
|
| 155 |
|
|
| 156 |
|
|
| 157 |
|
|
| 158 |
|
|
| 159 |
|
|
| 160 |
|
|
| 161 |
|
|
| 162 |
|
|
| 163 |
|
|
| 164 |
|
|
| 165 |
|
|
| 166 |
|
|
| 167 |
|
|
| 168 |
|
|
| 169 |
|
|
| 170 |
|
|
| 171 |
|
|
| 172 |
|
|
| 173 |
|
|
| 174 |
|
|
| 175 |
|
|
| 176 |
|
|
| 177 |
|
|
| 178 |
|
|
| 179 |
|
|
| 180 |
|
|
| 181 |
|
|
| 182 |
|
|
| 183 |
|
|
| 184 |
|
|
| 185 |
|
|
| 186 |
|
|
| 187 |
|
|
| 188 |
|
|
| 189 |
|
|
| 190 |
|
|
| 191 |
|
|
| 192 |
|
|
| 193 |
|
|
| 194 |
|
|
| 195 |
|
|
| 196 |
|
|
| 197 |
|
|
| 198 |
|
|
| 199 |
|
|
| 128 | 200 |
|
| 129 | 201 |
|
| 202 |
|
|
| 130 | 203 |
|
| 131 | 204 |
|
| 132 | 205 |
|
@@ -511,3 +584,24 @@
| 511 | 584 |
|
| 512 | 585 |
|
| 513 | 586 |
|
| 587 |
|
|
| 588 |
|
|
| 589 |
|
|
| 590 |
|
|
| 591 |
|
|
| 592 |
|
|
| 593 |
|
|
| 594 |
|
|
| 595 |
|
|
| 596 |
|
|
| 597 |
|
|
| 598 |
|
|
| 599 |
|
|
| 600 |
|
|
| 601 |
|
|
| 602 |
|
|
| 603 |
|
|
| 604 |
|
|
| 605 |
|
|
| 606 |
|
|
| 607 |
|
assets/css/openagents.css modified +4 -1
@@ -1603,7 +1603,10 @@
| 1603 | 1603 |
|
| 1604 | 1604 |
|
| 1605 | 1605 |
|
| 1606 |
|
|
| 1606 |
|
|
| 1607 |
|
|
| 1608 |
|
|
| 1609 |
|
|
| 1607 | 1610 |
|
| 1608 | 1611 |
|
| 1609 | 1612 |
|
assets/test/css_contract_test.mjs modified +11 -1
@@ -43,7 +43,17 @@ test("the compiled cascade preserves every governed button variant", () => {
| 43 | 43 |
|
| 44 | 44 |
|
| 45 | 45 |
|
| 46 |
|
|
| 46 |
|
|
| 47 |
|
|
| 48 |
|
|
| 49 |
|
|
| 50 |
|
|
| 51 |
|
|
| 52 |
|
|
| 53 |
|
|
| 54 |
|
|
| 55 |
|
|
| 56 |
|
|
| 47 | 57 |
|
| 48 | 58 |
|
| 49 | 59 |
|
lib/openagents_web/components/layouts.ex modified +38
@@ -96,6 +96,7 @@ defmodule OpenAgentsWeb.Layouts do
| 96 | 96 |
|
| 97 | 97 |
|
| 98 | 98 |
|
| 99 |
|
|
| 99 | 100 |
|
| 100 | 101 |
|
| 101 | 102 |
|
@@ -127,12 +128,49 @@ defmodule OpenAgentsWeb.Layouts do
| 127 | 128 |
|
| 128 | 129 |
|
| 129 | 130 |
|
| 131 |
|
|
| 130 | 132 |
|
| 131 | 133 |
|
| 132 | 134 |
|
| 133 | 135 |
|
| 134 | 136 |
|
| 135 | 137 |
|
| 138 |
|
|
| 139 |
|
|
| 140 |
|
|
| 141 |
|
|
| 142 |
|
|
| 143 |
|
|
| 144 |
|
|
| 145 |
|
|
| 146 |
|
|
| 147 |
|
|
| 148 |
|
|
| 149 |
|
|
| 150 |
|
|
| 151 |
|
|
| 152 |
|
|
| 153 |
|
|
| 154 |
|
|
| 155 |
|
|
| 156 |
|
|
| 157 |
|
|
| 158 |
|
|
| 159 |
|
|
| 160 |
|
|
| 161 |
|
|
| 162 |
|
|
| 163 |
|
|
| 164 |
|
|
| 165 |
|
|
| 166 |
|
|
| 167 |
|
|
| 168 |
|
|
| 169 |
|
|
| 170 |
|
|
| 171 |
|
|
| 172 |
|
|
| 173 |
|
|
| 136 | 174 |
|
| 137 | 175 |
|
| 138 | 176 |
|
lib/openagents_web/components/layouts/root.html.heex modified +22
@@ -10,6 +10,28 @@
| 10 | 10 |
|
| 11 | 11 |
|
| 12 | 12 |
|
| 13 |
|
|
| 14 |
|
|
| 15 |
|
|
| 16 |
|
|
| 17 |
|
|
| 18 |
|
|
| 19 |
|
|
| 20 |
|
|
| 21 |
|
|
| 22 |
|
|
| 23 |
|
|
| 24 |
|
|
| 25 |
|
|
| 26 |
|
|
| 27 |
|
|
| 28 |
|
|
| 29 |
|
|
| 30 |
|
|
| 31 |
|
|
| 32 |
|
|
| 33 |
|
|
| 34 |
|
|
| 13 | 35 |
|
| 14 | 36 |
|
| 15 | 37 |
|