🔍 fix: apply the code review — two visible regressions, and the gates behind them
Nine review angles, fourteen verified findings, all but the byte-table generator applied. The two that mattered most were regressions of mine: - a:hover repainted button-styled anchors, and in dark theme --accent-text equals --accent-solid — hovering the hero CTA drew its label in its own background colour. Verified invisible before (computed color == computed background) and distinct after: 10.39:1 dark, 6.90:1 light. The buttons and the skip link now re-assert their label colours on hover. - Footer links had lost every non-hover affordance: the text-decoration:none carve-out plus body-coloured links left a 2.37:1 shade difference as the only cue. The carve-out is deleted — .nav-links a and .brand already declare none themselves — and the accent rule is back on the footer. Also on the page: #ref-filter, the one text input, moves to --border-ui (it still had the 1.68:1 border the token's own comment calls decorative); focusable code surfaces get the --accent-on-code ring at -2px offset, inside the .code overflow clip; #output .out-err drops #ff8095, the last surviving colour of the deleted indigo palette; the two rgba(255,106,126) washes become color-mix over --err-line so a grep for the token finds them. The theme machinery loses a whole block: the dark media query is guarded with :not([data-theme="light"]), so an explicit light toggle falls through to the bare :root palette and the 21-token hand-copy in [data-theme="light"] is gone. Verified in all four system/toggle combinations. The page stops contradicting the repo: it claimed cereale/min "cannot tree-shake — nothing left to shake" while src/treeshake.test.ts proves the opposite on every run. Corrected here and in FRAMEWORKS.md, with the measured figures (1,837 vs 1,996 bytes for one decorator). The release facts the page was hand-bumping — both tgz names, "0.4.0 lives in the repository", the sixty-eight — now fill from meta.js/the bundle like the version badge always has. The workflows close three holes: - The docs sync gate was blind to NEW untracked build outputs (git diff does not report them; demonstrated). Both workflows now run check:docs-sync, one shared script that fails on anything porcelain reports — which also ends the copy-paste divergence between them. - pages.yml deploys on CI succeeding on main (workflow_run) instead of on the push itself, so a deploy implies green tests, not just in-sync docs. The deploy job refuses refs other than main, closing the workflow_dispatch any-branch deploy, and the build job drops pages/id-token — npm postinstall scripts no longer run alongside an OIDC grant. - The Junie action is pinned to the commit behind v1.7.4 rather than the tag, which is the immutability the previous comment promised but a mutable ref cannot deliver. Verified: every fix confirmed in a rendered browser in both themes; 72 contrast pairs still pass; no overflow at 20 widths; 268 tests, build, check:types, check:docs, actionlint all green. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SAcqrz3FcadkYr3xG32CjK
This commit is contained in:
+27
-26
@@ -27,9 +27,10 @@
|
||||
which already owns amber. Two amber families would make "our brand" and "needs
|
||||
your attention" the same colour.
|
||||
|
||||
Every token below that differs between themes must be written in ALL FOUR places:
|
||||
this block, the prefers-color-scheme block, [data-theme="light"] and
|
||||
[data-theme="dark"]. Miss one and the toggle silently serves the light value. */
|
||||
Every token below that differs between themes must be written in THREE places: this
|
||||
block (the light palette), the prefers-color-scheme block, and [data-theme="dark"].
|
||||
The dark media block is guarded with :not([data-theme="light"]), so an explicit light
|
||||
toggle falls straight through to these values — there is no light copy to keep in sync. */
|
||||
:root {
|
||||
--bg: #faf7f0;
|
||||
--bg-raised: #fffdf7;
|
||||
@@ -95,7 +96,7 @@
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
:root {
|
||||
:root:not([data-theme="light"]) {
|
||||
--bg: #12100b;
|
||||
--bg-raised: #1a1710;
|
||||
--bg-sunken: #16130d;
|
||||
@@ -120,16 +121,9 @@
|
||||
}
|
||||
}
|
||||
|
||||
/* The toggle wins over the media query in both directions. */
|
||||
/* An explicit light choice: the guarded media block above no longer matches, so the
|
||||
bare :root palette wins on its own. Only the UA hint needs stating. */
|
||||
:root[data-theme="light"] {
|
||||
--bg: #faf7f0; --bg-raised: #fffdf7; --bg-sunken: #f2ede1;
|
||||
--text: #1a1712; --text-muted: #5c5346; --text-faint: #6e6353;
|
||||
--border: #e6dfd1; --border-strong: #cfc5b2; --border-ui: #8e8269;
|
||||
--accent: #8a6238; --accent-text: #7a5530; --accent-soft: #f1e9dc;
|
||||
--accent-solid: #6b4a28; --on-accent: #fffdf7;
|
||||
--bad: #a82820; --bad-soft: #faebe7; --ok: #256b3d; --ok-soft: #e8f2e9;
|
||||
--warn: #8a5a05; --warn-soft: #fbf1dc;
|
||||
--shadow: 0 1px 2px rgba(40, 30, 14, .05), 0 8px 24px -12px rgba(40, 30, 14, .20);
|
||||
color-scheme: light;
|
||||
}
|
||||
:root[data-theme="dark"] {
|
||||
@@ -173,7 +167,6 @@ p { margin: 0 0 1rem; }
|
||||
--accent-text and --text-muted sit 1.14:1 apart — colour alone would lose them. */
|
||||
a { color: var(--text); text-decoration-color: var(--accent); text-decoration-thickness: 2px; text-underline-offset: .16em; }
|
||||
a:hover { color: var(--accent-text); text-decoration-color: currentColor; }
|
||||
.nav-links a, .foot-grid a, .brand { text-decoration: none; }
|
||||
code, kbd, pre { font-family: var(--mono); }
|
||||
:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; border-radius: 4px; }
|
||||
|
||||
@@ -200,6 +193,7 @@ section { padding-block: clamp(3rem, 6vw, 5.5rem); }
|
||||
background: var(--accent-solid); color: var(--on-accent); padding: .6rem 1rem; border-radius: 0 0 var(--radius) 0;
|
||||
}
|
||||
.skip:focus { left: 0; }
|
||||
.skip:hover { color: var(--on-accent); }
|
||||
.sr-only {
|
||||
position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
|
||||
overflow: hidden; clip-path: inset(50%); white-space: nowrap; border: 0;
|
||||
@@ -249,9 +243,12 @@ header.nav {
|
||||
padding: .75rem 1.15rem; border-radius: var(--radius); text-decoration: none; cursor: pointer; border: 1px solid transparent;
|
||||
}
|
||||
.btn-primary { background: var(--accent-solid); color: var(--on-accent); box-shadow: var(--shadow); }
|
||||
.btn-primary:hover { filter: brightness(1.08); }
|
||||
/* Re-assert label colours on hover: the base a:hover (0,1,1) outranks these classes
|
||||
(0,1,0), and in dark theme --accent-text equals --accent-solid — a hovered label
|
||||
painted in its own background. */
|
||||
.btn-primary:hover { filter: brightness(1.08); color: var(--on-accent); }
|
||||
.btn-secondary { background: var(--bg-raised); color: var(--text); border-color: var(--border-ui); }
|
||||
.btn-secondary:hover { border-color: var(--text-faint); }
|
||||
.btn-secondary:hover { border-color: var(--text-faint); color: var(--text); }
|
||||
.fact-row {
|
||||
display: flex; flex-wrap: wrap; gap: .4rem .5rem; margin-top: 1.5rem;
|
||||
font-size: .8125rem; color: var(--text-muted);
|
||||
@@ -290,7 +287,7 @@ header.nav {
|
||||
|
||||
/* The page's one visual device: the line the compiler refuses. */
|
||||
.ln--error {
|
||||
background: rgba(255, 106, 126, .09);
|
||||
background: color-mix(in srgb, var(--err-line) 9%, transparent);
|
||||
text-decoration: underline wavy var(--err-line);
|
||||
text-decoration-skip-ink: none;
|
||||
text-underline-offset: .32em;
|
||||
@@ -298,7 +295,7 @@ header.nav {
|
||||
.tsc-error {
|
||||
display: flex; gap: .6rem; align-items: flex-start;
|
||||
margin: 0; padding: .7rem .9rem; border-top: 1px solid var(--code-border);
|
||||
background: rgba(255, 106, 126, .08); color: var(--err-text);
|
||||
background: color-mix(in srgb, var(--err-line) 8%, transparent); color: var(--err-text);
|
||||
font: 500 .78125rem/1.5 var(--mono);
|
||||
}
|
||||
.tsc-error .mark { color: var(--err-line); flex-shrink: 0; }
|
||||
@@ -348,13 +345,16 @@ header.nav {
|
||||
overflow: auto;
|
||||
}
|
||||
#editor:focus { outline: 2px solid var(--accent-on-code); outline-offset: -2px; }
|
||||
/* Scrollable code samples are keyboard-focusable in Chromium; the page-level ring is
|
||||
unreadable on the dark slab and its +2px offset would be clipped by .code overflow. */
|
||||
.code :focus-visible, #output:focus-visible { outline: 2px solid var(--accent-on-code); outline-offset: -2px; }
|
||||
#output {
|
||||
flex: 1; min-height: 400px; margin: 0; overflow: auto;
|
||||
background: var(--code-bg); color: var(--code-text); border: 1px solid var(--code-border);
|
||||
border-top: none; border-radius: 0 0 var(--radius-lg) var(--radius-lg);
|
||||
padding: 1.1rem 1.15rem; font: .84375rem/1.75 var(--mono); white-space: pre-wrap; word-break: break-word;
|
||||
}
|
||||
#output .out-err { color: #ff8095; }
|
||||
#output .out-err { color: var(--err-text); }
|
||||
#output .out-dim { color: var(--code-faint); }
|
||||
.pg-note { font-size: .8125rem; color: var(--text-muted); margin: .9rem 0 0; }
|
||||
|
||||
@@ -370,7 +370,7 @@ td.note { white-space: normal; color: var(--text-muted); font-size: .875rem; }
|
||||
.ref-bar { display: flex; flex-wrap: wrap; gap: .75rem; align-items: center; margin-bottom: 1.5rem; }
|
||||
#ref-filter {
|
||||
flex: 1; min-width: 210px; font: .9375rem var(--sans); padding: .6rem .85rem;
|
||||
border: 1px solid var(--border-strong); border-radius: var(--radius);
|
||||
border: 1px solid var(--border-ui); border-radius: var(--radius);
|
||||
background: var(--bg-raised); color: var(--text);
|
||||
}
|
||||
#ref-count { font-size: .875rem; color: var(--text-muted); font-variant-numeric: tabular-nums; }
|
||||
@@ -817,7 +817,7 @@ export default defineConfig({
|
||||
<p class="compare-label"><span class="pill pill-bad">not on npm yet</span> installing it today</p>
|
||||
<div class="code">
|
||||
<div class="code-head"><span class="name">shell</span></div>
|
||||
<pre><code data-lang="text">git clone https://github.com/avalon-vanguard/cereale
|
||||
<pre><code data-lang="text" id="install-shell">git clone https://github.com/avalon-vanguard/cereale
|
||||
cd cereale
|
||||
npm install && npm run build
|
||||
npm pack # → cereale-0.4.0.tgz
|
||||
@@ -851,9 +851,10 @@ npm install ../cereale/cereale-0.4.0.tgz</code></pre>
|
||||
</script></code></pre>
|
||||
</div>
|
||||
<p class="pg-note">
|
||||
<strong>If you are using a bundler, do not use it.</strong> It is the whole library in one
|
||||
file, so nothing can be dropped from it. The default entry point tree-shakes; this one
|
||||
cannot, because there is nothing left to shake.
|
||||
<strong>If you are using a bundler, prefer the default entry.</strong> The flat file keeps
|
||||
its purity annotations, so a bundler can still drop the rules you did not import — that
|
||||
is pinned by a test — but the per-module build shakes slightly leaner (1,837 bytes
|
||||
against 1,996 for one decorator) and is the canonical route.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
@@ -866,7 +867,7 @@ npm install ../cereale/cereale-0.4.0.tgz</code></pre>
|
||||
<p class="eyebrow">Bundle size</p>
|
||||
<h2>You pay for the decorators you name</h2>
|
||||
<p class="lede">
|
||||
Sixty-eight decorators is a lot to ship to a browser, so none of the ones you did not
|
||||
<b class="js-dec-count">68</b> decorators is a lot to ship to a browser, so none of the ones you did not
|
||||
import are shipped. Minified bytes, measured through all three bundlers.
|
||||
</p>
|
||||
</div>
|
||||
@@ -998,7 +999,7 @@ npm install ../cereale/cereale-0.4.0.tgz</code></pre>
|
||||
</div>
|
||||
<div class="note-item">
|
||||
<h3>It is not on npm yet</h3>
|
||||
<p>0.4.0 lives in the repository. <code class="inline-code">npm install cereale</code> does not
|
||||
<p><span class="js-version">0.4.0</span> lives in the repository. <code class="inline-code">npm install cereale</code> does not
|
||||
resolve to this library — build it from source until it is published.</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -39,6 +39,22 @@
|
||||
if (versionEl && meta.version) versionEl.textContent = 'v' + meta.version;
|
||||
var nodeEl = document.getElementById('node-req');
|
||||
if (nodeEl && meta.node) nodeEl.textContent = meta.node.replace('>=', '≥').replace('.0.0', '');
|
||||
if (meta.version) {
|
||||
Array.prototype.forEach.call(document.querySelectorAll('.js-version'), function (el) {
|
||||
el.textContent = meta.version;
|
||||
});
|
||||
// The install snippet names the tarball npm pack produces; keep it tied to the
|
||||
// same package.json fact the badge uses instead of hand-bumping it each release.
|
||||
var shell = document.getElementById('install-shell');
|
||||
if (shell) {
|
||||
shell.textContent = shell.textContent.replace(/cereale-[\d.]+\.tgz/g, 'cereale-' + meta.version + '.tgz');
|
||||
}
|
||||
}
|
||||
if (decoratorCount) {
|
||||
Array.prototype.forEach.call(document.querySelectorAll('.js-dec-count'), function (el) {
|
||||
el.textContent = String(decoratorCount);
|
||||
});
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------- highlighting */
|
||||
var TOKENS = [
|
||||
|
||||
Reference in New Issue
Block a user