EHS-Studio Claude Sonnet 5.5 commited on
Commit
a2dd7a5
·
1 Parent(s): 2c6de14

v0.16.1: DSSL.lint css-loses compares values

Browse files

A page that ships dssl build output and also runs the engine says every rule twice; that is not a conflict.
Found on this site's docs page (4,314 false findings).

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

GUIDE.md CHANGED
@@ -950,7 +950,7 @@ and listed, so the file you get always compiles.
950
  ```js
951
  import { DSSL } from '/dssl/index.js' // or just use window.DSSL after boot
952
 
953
- DSSL.version // "0.16.0": a string, not a function
954
  DSSL.compile(source) // { ok, errors, warnings, stats, doc }: parse and resolve, no DOM
955
  DSSL.apply(source, { name, scope, replace })
956
  await DSSL.load(['a.dssl', 'b.dssl'])
@@ -985,7 +985,7 @@ Three ways to get it:
985
 
986
  1. VSCodium: open the Extensions tab, search "DSSL" and install. It is on Open VSX:
987
  https://open-vsx.org/extension/ehs-studio/dssl-vscode
988
- 2. VS Code: download `dssl-vscode/dssl-vscode-0.16.0.vsix` from the repo files, then
989
  Extensions panel, `...`, Install from VSIX. (The Microsoft Marketplace listing is not published yet.)
990
  3. Build it yourself: `cd dssl-vscode && npx @vscode/vsce package --no-dependencies`.
991
 
 
950
  ```js
951
  import { DSSL } from '/dssl/index.js' // or just use window.DSSL after boot
952
 
953
+ DSSL.version // "0.16.1": a string, not a function
954
  DSSL.compile(source) // { ok, errors, warnings, stats, doc }: parse and resolve, no DOM
955
  DSSL.apply(source, { name, scope, replace })
956
  await DSSL.load(['a.dssl', 'b.dssl'])
 
985
 
986
  1. VSCodium: open the Extensions tab, search "DSSL" and install. It is on Open VSX:
987
  https://open-vsx.org/extension/ehs-studio/dssl-vscode
988
+ 2. VS Code: download `dssl-vscode/dssl-vscode-0.16.1.vsix` from the repo files, then
989
  Extensions panel, `...`, Install from VSIX. (The Microsoft Marketplace listing is not published yet.)
990
  3. Build it yourself: `cd dssl-vscode && npx @vscode/vsce package --no-dependencies`.
991
 
PARITY.md CHANGED
@@ -62,6 +62,10 @@ so the boundary is explicit, not folklore.
62
  - loud errors with did-you-mean, and a warnings channel for cascade-order footguns
63
  - `freeze()` / `unfreeze()`: a live engine that can be parked at zero cost
64
 
 
 
 
 
65
  ## v0.16.0: round three
66
 
67
  | Item from the game builder | Status |
 
62
  - loud errors with did-you-mean, and a warnings channel for cascade-order footguns
63
  - `freeze()` / `unfreeze()`: a live engine that can be parked at zero cost
64
 
65
+ ## v0.16.1
66
+
67
+ `DSSL.lint`'s `css-loses` ignores a CSS rule whose value is the same as the inline value DSSL wrote (found on this site, which ships compiled CSS and runs the engine: 4,314 false findings on the docs page).
68
+
69
  ## v0.16.0: round three
70
 
71
  | Item from the game builder | Status |
README.md CHANGED
@@ -68,7 +68,7 @@ Both drop a `dssl-engine/` folder next to you: the engine, a starter token set,
68
 
69
  Prefer to click: [dssl-engine.zip](https://dssl-sable.vercel.app/dssl-engine.zip) or [dssl-engine.tar.gz](https://dssl-sable.vercel.app/dssl-engine.tar.gz). Same package, straight from the browser.
70
 
71
- Writing your own .dssl? The official editor extension (`ehs-studio.dssl-vscode`) puts the real compiler in your editor: the squiggles are the same errors the browser console prints, completions come from your own token registry, and hovers explain the semantic vocabulary. One package for VS Code and VSCodium (same extension API). In VSCodium, search "DSSL" in the Extensions tab (it is on Open VSX: https://open-vsx.org/extension/ehs-studio/dssl-vscode). In VS Code, download `dssl-vscode/dssl-vscode-0.16.0.vsix` from the repo files, then Extensions panel -> ... -> Install from VSIX. See `dssl-vscode/PUBLISHING.md` for publishing.
72
 
73
  AI agents and machine reviewers: this repo ships `llms.txt` (dense, structured facts), `AGENTS.md` (how to work on the codebase) and `PARITY.md` (the honest feature matrix against CSS). The site serves the same `llms.txt` at https://dssl-sable.vercel.app/llms.txt
74
 
@@ -470,7 +470,7 @@ await DSSL.lint(root) // contrast against the real background,
470
  DSSL.play(el, 'boing', opts) // a one-shot motion from JS, as a promise
471
  DSSL.motion('full') // run every motion whatever the system asks for
472
  DSSL.auraZ(20) // where the aura canvas sits in the stack
473
- DSSL.version // "0.16.0", a string
474
  ```
475
 
476
  Auto-boot picks up every `link[rel="stylesheet/dssl"]` and `style[type="text/dssl"]`, applies them, and fires `dssl-ready` on `window`. `<html data-dssl-reset>` enables the small built-in reset.
@@ -546,7 +546,7 @@ const rep = DSSL.explain(document.querySelector('.doc-card'))
546
 
547
  The matcher also pre-filters every rule through a cheap class/tag/id gate extracted from the selector's rightmost compound, so a recompute skips obvious non-matches instead of asking the browser rule by rule. The gate only ever says no; anything it does not fully understand falls back to native matching.
548
 
549
- ## What works today (v0.16.0)
550
 
551
  - the full selector surface, including `:nth-child`, `:not`, `:is`, `:where`, `:has`
552
  - flexbox and grid with `row:` / `column:` / `grid:` / `stack:` / `center:` sugar, place words now own an axis (`between` is main-axis, `stretch` is cross-axis) and conflicts warn instead of silently overwriting
@@ -586,7 +586,7 @@ The matcher also pre-filters every rule through a cheap class/tag/id gate extrac
586
 
587
  ## Status
588
 
589
- v0.16.0, experimental, moving fast. The language grows whenever the site needs something it cannot express yet, so the site doubles as the test suite, and the docs examples are rendered and asserted in a real browser, so the guide cannot lie. Honest ledger: great for creative sites, prototypes, docs, playgrounds and internal tools; when a page must work without JavaScript, build the static subset with `dssl build` or pick another tool for that page. Freeze makes big static pages viable; live interaction is what the engine is for.
590
 
591
  ## License
592
 
 
68
 
69
  Prefer to click: [dssl-engine.zip](https://dssl-sable.vercel.app/dssl-engine.zip) or [dssl-engine.tar.gz](https://dssl-sable.vercel.app/dssl-engine.tar.gz). Same package, straight from the browser.
70
 
71
+ Writing your own .dssl? The official editor extension (`ehs-studio.dssl-vscode`) puts the real compiler in your editor: the squiggles are the same errors the browser console prints, completions come from your own token registry, and hovers explain the semantic vocabulary. One package for VS Code and VSCodium (same extension API). In VSCodium, search "DSSL" in the Extensions tab (it is on Open VSX: https://open-vsx.org/extension/ehs-studio/dssl-vscode). In VS Code, download `dssl-vscode/dssl-vscode-0.16.1.vsix` from the repo files, then Extensions panel -> ... -> Install from VSIX. See `dssl-vscode/PUBLISHING.md` for publishing.
72
 
73
  AI agents and machine reviewers: this repo ships `llms.txt` (dense, structured facts), `AGENTS.md` (how to work on the codebase) and `PARITY.md` (the honest feature matrix against CSS). The site serves the same `llms.txt` at https://dssl-sable.vercel.app/llms.txt
74
 
 
470
  DSSL.play(el, 'boing', opts) // a one-shot motion from JS, as a promise
471
  DSSL.motion('full') // run every motion whatever the system asks for
472
  DSSL.auraZ(20) // where the aura canvas sits in the stack
473
+ DSSL.version // "0.16.1", a string
474
  ```
475
 
476
  Auto-boot picks up every `link[rel="stylesheet/dssl"]` and `style[type="text/dssl"]`, applies them, and fires `dssl-ready` on `window`. `<html data-dssl-reset>` enables the small built-in reset.
 
546
 
547
  The matcher also pre-filters every rule through a cheap class/tag/id gate extracted from the selector's rightmost compound, so a recompute skips obvious non-matches instead of asking the browser rule by rule. The gate only ever says no; anything it does not fully understand falls back to native matching.
548
 
549
+ ## What works today (v0.16.1)
550
 
551
  - the full selector surface, including `:nth-child`, `:not`, `:is`, `:where`, `:has`
552
  - flexbox and grid with `row:` / `column:` / `grid:` / `stack:` / `center:` sugar, place words now own an axis (`between` is main-axis, `stretch` is cross-axis) and conflicts warn instead of silently overwriting
 
586
 
587
  ## Status
588
 
589
+ v0.16.1, experimental, moving fast. The language grows whenever the site needs something it cannot express yet, so the site doubles as the test suite, and the docs examples are rendered and asserted in a real browser, so the guide cannot lie. Honest ledger: great for creative sites, prototypes, docs, playgrounds and internal tools; when a page must work without JavaScript, build the static subset with `dssl build` or pick another tool for that page. Freeze makes big static pages viable; live interaction is what the engine is for.
590
 
591
  ## License
592
 
dssl-vscode/CHANGELOG.md CHANGED
@@ -1,5 +1,9 @@
1
  # Changelog
2
 
 
 
 
 
3
  ## 0.16.0
4
 
5
  - Bundled engine updated to 0.16.0. The editor now accepts the whole of CSS (`env()`, `tabular-nums`, `touch-action`, vendor properties)
 
1
  # Changelog
2
 
3
+ ## 0.16.1
4
+
5
+ - Bundled engine 0.16.1: `DSSL.lint` no longer reports `css-loses` for a stylesheet that says the same thing as DSSL (a page that ships the compiled CSS and also runs the engine).
6
+
7
  ## 0.16.0
8
 
9
  - Bundled engine updated to 0.16.0. The editor now accepts the whole of CSS (`env()`, `tabular-nums`, `touch-action`, vendor properties)
dssl-vscode/package.json CHANGED
@@ -2,7 +2,7 @@
2
  "name": "dssl-vscode",
3
  "displayName": "DSSL Language Support",
4
  "description": "The DSSL style language in your editor: syntax highlighting, real-compiler diagnostics (the same errors the browser console shows), completions from the live token registry and for textures, auras and sliders, hover docs, an interactive designer with sliders and live previews for aura, texture and range sliders, and a CSS to DSSL converter. Works in VS Code and VSCodium.",
5
- "version": "0.16.0",
6
  "publisher": "ehs-studio",
7
  "icon": "icon.png",
8
  "license": "MIT",
 
2
  "name": "dssl-vscode",
3
  "displayName": "DSSL Language Support",
4
  "description": "The DSSL style language in your editor: syntax highlighting, real-compiler diagnostics (the same errors the browser console shows), completions from the live token registry and for textures, auras and sliders, hover docs, an interactive designer with sliders and live previews for aura, texture and range sliders, and a CSS to DSSL converter. Works in VS Code and VSCodium.",
5
+ "version": "0.16.1",
6
  "publisher": "ehs-studio",
7
  "icon": "icon.png",
8
  "license": "MIT",
llms.txt CHANGED
@@ -5,7 +5,7 @@
5
  - Site (docs, playground, changelog, bench): https://dssl-sable.vercel.app
6
  - Repo + full docs in the README: https://huggingface.co/EHS-Studio/dssl
7
  - Install: `curl -fsSL https://dssl-sable.vercel.app/install.sh | sh` (or the zip: https://dssl-sable.vercel.app/dssl-engine.zip)
8
- - Version: 0.16.0 (engine), MIT license
9
  - Feature matrix vs CSS: see PARITY.md in the repo
10
  - For agents working ON the codebase: see AGENTS.md in the repo
11
 
@@ -64,6 +64,9 @@ DSSL.replay(sel) / DSSL.refresh([el]) / DSSL.errors() (a function) / DSSL.versio
64
  - Alpha on a named colour works: `white/12`, `currentColor/20`. It used to compile to `white/12px`.
65
  - The playground has a canvas.html tab, `?example=` links, lint warnings and an "as CSS" tab. The canvas keeps a short allow-list of tags and drops scripts, handlers, styles and ids.
66
 
 
 
 
67
  ## 0.16.0: round three
68
  - `yield: padding-top padding-bottom` hands properties back to plain CSS (the engine writes inline styles, which beat a stylesheet): the CSS wins with no `!important`. `yield: padding` covers the family, `yield: none` clears it. `DSSL.lint` reports `css-loses` when your CSS rule loses to DSSL, naming the fix. `dssl build` ignores `yield`.
69
  - Valid CSS is accepted: `env(safe-area-inset-top)`, `font-variant-numeric: tabular-nums`, `touch-action`, `scroll-snap-type`, `-webkit-user-select`, `direction` and the rest. The known words and properties are generated from the MDN data (`node scripts/gen-css-keywords.mjs`). A typo still errors with did-you-mean.
@@ -129,4 +132,4 @@ Wait for the `dssl-ready` event on `window` before measuring layout: the engine
129
 
130
  ## Editor support
131
 
132
- The official extension (VS Code and VSCodium, same .vsix) bundles the real parser and resolver: diagnostics identical to the browser console, completions from the workspace token registry, hover docs for the semantic vocabulary. In VSCodium, search "DSSL" in the Extensions tab (it is on Open VSX: https://open-vsx.org/extension/ehs-studio/dssl-vscode). In VS Code, download `dssl-vscode/dssl-vscode-0.16.0.vsix` from the repo files, then Extensions panel -> ... -> Install from VSIX. Source lives in `dssl-vscode/` in the repo.
 
5
  - Site (docs, playground, changelog, bench): https://dssl-sable.vercel.app
6
  - Repo + full docs in the README: https://huggingface.co/EHS-Studio/dssl
7
  - Install: `curl -fsSL https://dssl-sable.vercel.app/install.sh | sh` (or the zip: https://dssl-sable.vercel.app/dssl-engine.zip)
8
+ - Version: 0.16.1 (engine), MIT license
9
  - Feature matrix vs CSS: see PARITY.md in the repo
10
  - For agents working ON the codebase: see AGENTS.md in the repo
11
 
 
64
  - Alpha on a named colour works: `white/12`, `currentColor/20`. It used to compile to `white/12px`.
65
  - The playground has a canvas.html tab, `?example=` links, lint warnings and an "as CSS" tab. The canvas keeps a short allow-list of tags and drops scripts, handlers, styles and ids.
66
 
67
+ ## 0.16.1
68
+ - `DSSL.lint`'s `css-loses` no longer reports a rule whose value is the same as what DSSL wrote inline (a page that ships `dssl build` output and also runs the engine says every rule twice).
69
+
70
  ## 0.16.0: round three
71
  - `yield: padding-top padding-bottom` hands properties back to plain CSS (the engine writes inline styles, which beat a stylesheet): the CSS wins with no `!important`. `yield: padding` covers the family, `yield: none` clears it. `DSSL.lint` reports `css-loses` when your CSS rule loses to DSSL, naming the fix. `dssl build` ignores `yield`.
72
  - Valid CSS is accepted: `env(safe-area-inset-top)`, `font-variant-numeric: tabular-nums`, `touch-action`, `scroll-snap-type`, `-webkit-user-select`, `direction` and the rest. The known words and properties are generated from the MDN data (`node scripts/gen-css-keywords.mjs`). A typo still errors with did-you-mean.
 
132
 
133
  ## Editor support
134
 
135
+ The official extension (VS Code and VSCodium, same .vsix) bundles the real parser and resolver: diagnostics identical to the browser console, completions from the workspace token registry, hover docs for the semantic vocabulary. In VSCodium, search "DSSL" in the Extensions tab (it is on Open VSX: https://open-vsx.org/extension/ehs-studio/dssl-vscode). In VS Code, download `dssl-vscode/dssl-vscode-0.16.1.vsix` from the repo files, then Extensions panel -> ... -> Install from VSIX. Source lives in `dssl-vscode/` in the repo.
package.json CHANGED
@@ -1,6 +1,6 @@
1
  {
2
  "name": "dssl",
3
- "version": "0.16.0",
4
  "private": true,
5
  "description": "The DSSL style language and the website that is written in it.",
6
  "scripts": {
 
1
  {
2
  "name": "dssl",
3
+ "version": "0.16.1",
4
  "private": true,
5
  "description": "The DSSL style language and the website that is written in it.",
6
  "scripts": {
public/dssl/dev.js CHANGED
@@ -212,6 +212,9 @@ function cssThatLoses(eng, scope) {
212
  for (const [p, v] of owned) {
213
  if (v.imp) continue;
214
  if (p === q || q.startsWith(p + '-') || p.startsWith(q + '-')) {
 
 
 
215
  const key = `${r.selectorText}|${p}|${q}|${describe(el)}`;
216
  if (seen.has(key)) continue;
217
  seen.add(key);
 
212
  for (const [p, v] of owned) {
213
  if (v.imp) continue;
214
  if (p === q || q.startsWith(p + '-') || p.startsWith(q + '-')) {
215
+ // the same value on both sides is no conflict (a page that ships the compiled CSS AND runs the engine says everything twice)
216
+ const iv = el.style.getPropertyValue(q), rv = r.style.getPropertyValue(q);
217
+ if (!iv || iv === rv) continue;
218
  const key = `${r.selectorText}|${p}|${q}|${describe(el)}`;
219
  if (seen.has(key)) continue;
220
  seen.add(key);
public/dssl/index.js CHANGED
@@ -19,7 +19,7 @@ import { resolve, DEFAULT_TOKENS, EASINGS } from './resolver.js';
19
  import { toCSS as docToCSS } from './static.js';
20
  import { DsslEngine } from './engine.js';
21
 
22
- export const VERSION = '0.16.0';
23
 
24
  let counter = 0;
25
  const loadedUrls = new Set(); // every .dssl file fetched by load(), so DSSL.watch() knows what to follow
 
19
  import { toCSS as docToCSS } from './static.js';
20
  import { DsslEngine } from './engine.js';
21
 
22
+ export const VERSION = '0.16.1';
23
 
24
  let counter = 0;
25
  const loadedUrls = new Set(); // every .dssl file fetched by load(), so DSSL.watch() knows what to follow
public/llms.txt CHANGED
@@ -5,7 +5,7 @@
5
  - Site (docs, playground, changelog, bench): https://dssl-sable.vercel.app
6
  - Repo + full docs in the README: https://huggingface.co/EHS-Studio/dssl
7
  - Install: `curl -fsSL https://dssl-sable.vercel.app/install.sh | sh` (or the zip: https://dssl-sable.vercel.app/dssl-engine.zip)
8
- - Version: 0.16.0 (engine), MIT license
9
  - Feature matrix vs CSS: see PARITY.md in the repo
10
  - For agents working ON the codebase: see AGENTS.md in the repo
11
 
@@ -64,6 +64,9 @@ DSSL.replay(sel) / DSSL.refresh([el]) / DSSL.errors() (a function) / DSSL.versio
64
  - Alpha on a named colour works: `white/12`, `currentColor/20`. It used to compile to `white/12px`.
65
  - The playground has a canvas.html tab, `?example=` links, lint warnings and an "as CSS" tab. The canvas keeps a short allow-list of tags and drops scripts, handlers, styles and ids.
66
 
 
 
 
67
  ## 0.16.0: round three
68
  - `yield: padding-top padding-bottom` hands properties back to plain CSS (the engine writes inline styles, which beat a stylesheet): the CSS wins with no `!important`. `yield: padding` covers the family, `yield: none` clears it. `DSSL.lint` reports `css-loses` when your CSS rule loses to DSSL, naming the fix. `dssl build` ignores `yield`.
69
  - Valid CSS is accepted: `env(safe-area-inset-top)`, `font-variant-numeric: tabular-nums`, `touch-action`, `scroll-snap-type`, `-webkit-user-select`, `direction` and the rest. The known words and properties are generated from the MDN data (`node scripts/gen-css-keywords.mjs`). A typo still errors with did-you-mean.
@@ -129,4 +132,4 @@ Wait for the `dssl-ready` event on `window` before measuring layout: the engine
129
 
130
  ## Editor support
131
 
132
- The official extension (VS Code and VSCodium, same .vsix) bundles the real parser and resolver: diagnostics identical to the browser console, completions from the workspace token registry, hover docs for the semantic vocabulary. In VSCodium, search "DSSL" in the Extensions tab (it is on Open VSX: https://open-vsx.org/extension/ehs-studio/dssl-vscode). In VS Code, download `dssl-vscode/dssl-vscode-0.16.0.vsix` from the repo files, then Extensions panel -> ... -> Install from VSIX. Source lives in `dssl-vscode/` in the repo.
 
5
  - Site (docs, playground, changelog, bench): https://dssl-sable.vercel.app
6
  - Repo + full docs in the README: https://huggingface.co/EHS-Studio/dssl
7
  - Install: `curl -fsSL https://dssl-sable.vercel.app/install.sh | sh` (or the zip: https://dssl-sable.vercel.app/dssl-engine.zip)
8
+ - Version: 0.16.1 (engine), MIT license
9
  - Feature matrix vs CSS: see PARITY.md in the repo
10
  - For agents working ON the codebase: see AGENTS.md in the repo
11
 
 
64
  - Alpha on a named colour works: `white/12`, `currentColor/20`. It used to compile to `white/12px`.
65
  - The playground has a canvas.html tab, `?example=` links, lint warnings and an "as CSS" tab. The canvas keeps a short allow-list of tags and drops scripts, handlers, styles and ids.
66
 
67
+ ## 0.16.1
68
+ - `DSSL.lint`'s `css-loses` no longer reports a rule whose value is the same as what DSSL wrote inline (a page that ships `dssl build` output and also runs the engine says every rule twice).
69
+
70
  ## 0.16.0: round three
71
  - `yield: padding-top padding-bottom` hands properties back to plain CSS (the engine writes inline styles, which beat a stylesheet): the CSS wins with no `!important`. `yield: padding` covers the family, `yield: none` clears it. `DSSL.lint` reports `css-loses` when your CSS rule loses to DSSL, naming the fix. `dssl build` ignores `yield`.
72
  - Valid CSS is accepted: `env(safe-area-inset-top)`, `font-variant-numeric: tabular-nums`, `touch-action`, `scroll-snap-type`, `-webkit-user-select`, `direction` and the rest. The known words and properties are generated from the MDN data (`node scripts/gen-css-keywords.mjs`). A typo still errors with did-you-mean.
 
132
 
133
  ## Editor support
134
 
135
+ The official extension (VS Code and VSCodium, same .vsix) bundles the real parser and resolver: diagnostics identical to the browser console, completions from the workspace token registry, hover docs for the semantic vocabulary. In VSCodium, search "DSSL" in the Extensions tab (it is on Open VSX: https://open-vsx.org/extension/ehs-studio/dssl-vscode). In VS Code, download `dssl-vscode/dssl-vscode-0.16.1.vsix` from the repo files, then Extensions panel -> ... -> Install from VSIX. Source lives in `dssl-vscode/` in the repo.
public/showcase/wood/wood.css CHANGED
@@ -1,4 +1,4 @@
1
- /* generated by dssl build from tokens.dssl + static.dssl - the static subset of DSSL v0.16.0.
2
  @signal rules and engine-native properties (animate, aura, tilt, ...) stay in the runtime.
3
  Textures are baked in as background images when their colours are known at build time. */
4
  @import url("https://fonts.googleapis.com/css2?family=Fraunces:wght@500;700;800&family=Hanken+Grotesk:wght@400;500;700&display=swap");
 
1
+ /* generated by dssl build from tokens.dssl + static.dssl - the static subset of DSSL v0.16.1.
2
  @signal rules and engine-native properties (animate, aura, tilt, ...) stay in the runtime.
3
  Textures are baked in as background images when their colours are known at build time. */
4
  @import url("https://fonts.googleapis.com/css2?family=Fraunces:wght@500;700;800&family=Hanken+Grotesk:wght@400;500;700&display=swap");
scripts/test-v0150.mjs CHANGED
@@ -312,7 +312,7 @@ section('12. docs and version');
312
  const read = (f) => readFileSync(path.join(ROOT, f), 'utf8');
313
  const API = await import('../public/dssl/index.js');
314
  ok('the engine says 0.15.0 or later', /^0\.(15|16)\./.test(API.VERSION));
315
- for (const f of ['GUIDE.md', 'README.md', 'llms.txt', 'PARITY.md', 'src/components/dssl/views/ChangelogView.tsx', 'dssl-vscode/CHANGELOG.md']) ok(`${f} has a 0.15.0 (or later) section`, /0\.1[5-9]\.0/.test(read(f)));
316
  const guide = read('GUIDE.md');
317
  for (const w of ['outline-shape', 'DSSL.settled', 'DSSL.signal(\'hp\'', 'pauseMotion', '--engine', 'z 5']) ok(`the guide covers ${w}`, guide.includes(w));
318
  ok('llms.txt and public/llms.txt are the same file', read('llms.txt') === read('public/llms.txt'));
 
312
  const read = (f) => readFileSync(path.join(ROOT, f), 'utf8');
313
  const API = await import('../public/dssl/index.js');
314
  ok('the engine says 0.15.0 or later', /^0\.(15|16)\./.test(API.VERSION));
315
+ for (const f of ['GUIDE.md', 'README.md', 'llms.txt', 'PARITY.md', 'src/components/dssl/views/ChangelogView.tsx', 'dssl-vscode/CHANGELOG.md']) ok(`${f} has a 0.15.0 (or later) section`, /0\.1[5-9]\.\d/.test(read(f)));
316
  const guide = read('GUIDE.md');
317
  for (const w of ['outline-shape', 'DSSL.settled', 'DSSL.signal(\'hp\'', 'pauseMotion', '--engine', 'z 5']) ok(`the guide covers ${w}`, guide.includes(w));
318
  ok('llms.txt and public/llms.txt are the same file', read('llms.txt') === read('public/llms.txt'));
scripts/test-v0160.mjs CHANGED
@@ -92,6 +92,16 @@ await withBrowser(async ({ open, errors }) => {
92
  ok('dssl build writes the padding and does not count or print yield (a stylesheet has nothing to hand back)', r.status === 0 && /padding: 10px/.test(css) && !/yield/.test(css) && !/engine-native/.test(r.stdout), r.stdout + r.stderr);
93
  }
94
 
 
 
 
 
 
 
 
 
 
 
95
  section('4. aura follows the real shape');
96
  {
97
  const around = (w) => { const out = parseAura('aura-glow', `#f00 30 around ${w}`, { error() { }, color: (c) => c, suggest: () => null }); return out && out.glow && out.glow[0] && out.glow[0].around; };
@@ -230,8 +240,8 @@ section('7. docs and version');
230
  {
231
  const read = (f) => readFileSync(path.join(ROOT, f), 'utf8');
232
  const API = await import('../public/dssl/index.js');
233
- ok('the engine says 0.16.0', API.VERSION === '0.16.0');
234
- for (const f of ['GUIDE.md', 'README.md', 'llms.txt', 'PARITY.md', 'src/components/dssl/views/ChangelogView.tsx', 'dssl-vscode/CHANGELOG.md']) ok(`${f} has a 0.16.0 section`, /0\.16\.0/.test(read(f)));
235
  const guide = read('GUIDE.md');
236
  for (const w of ['yield:', 'around diamond', 'from outline', 'palette', 'orbit', 'herringbone', 'tartan', 'css-loses', 'env(safe-area-inset-top']) ok(`the guide covers ${w}`, guide.includes(w));
237
  ok('no em dashes in the new guide chapter', !/—/.test(guide.slice(guide.indexOf('### Round three (0.16.0)'), guide.indexOf('### Fonts'))));
 
92
  ok('dssl build writes the padding and does not count or print yield (a stylesheet has nothing to hand back)', r.status === 0 && /padding: 10px/.test(css) && !/yield/.test(css) && !/engine-native/.test(r.stdout), r.stdout + r.stderr);
93
  }
94
 
95
+ {
96
+ // a page that ships `dssl build` output AND runs the engine says every rule twice: that is not a conflict
97
+ const built = (await import('../public/dssl/index.js')).toCSS('.dup { padding: 10; color: #123456 }', { file: 'a.dssl' }).css;
98
+ await withBrowser(async ({ open }) => {
99
+ const p = await open('/b'); await ready(p); await p.waitForTimeout(250);
100
+ const n = await p.evaluate(async () => (await DSSL.lint(document.body, { log: false })).filter((f) => f.kind === 'css-loses').length);
101
+ ok('compiled CSS and the engine saying the same thing is not reported as css-loses', n === 0, String(n));
102
+ }, { pages: { '/b': page('.dup { padding: 10; color: #123456 }', '<div class=dup></div>', '', built) } });
103
+ }
104
+
105
  section('4. aura follows the real shape');
106
  {
107
  const around = (w) => { const out = parseAura('aura-glow', `#f00 30 around ${w}`, { error() { }, color: (c) => c, suggest: () => null }); return out && out.glow && out.glow[0] && out.glow[0].around; };
 
240
  {
241
  const read = (f) => readFileSync(path.join(ROOT, f), 'utf8');
242
  const API = await import('../public/dssl/index.js');
243
+ ok('the engine says 0.16', /^0\.16\./.test(API.VERSION));
244
+ for (const f of ['GUIDE.md', 'README.md', 'llms.txt', 'PARITY.md', 'src/components/dssl/views/ChangelogView.tsx', 'dssl-vscode/CHANGELOG.md']) ok(`${f} has a 0.16 section`, /0\.16\.\d/.test(read(f)));
245
  const guide = read('GUIDE.md');
246
  for (const w of ['yield:', 'around diamond', 'from outline', 'palette', 'orbit', 'herringbone', 'tartan', 'css-loses', 'env(safe-area-inset-top']) ok(`the guide covers ${w}`, guide.includes(w));
247
  ok('no em dashes in the new guide chapter', !/—/.test(guide.slice(guide.indexOf('### Round three (0.16.0)'), guide.indexOf('### Fonts'))));
src/components/dssl/views/ChangelogView.tsx CHANGED
@@ -11,6 +11,14 @@ const ENTRIES: {
11
  code?: string;
12
  kind?: "spec" | "vote" | "add";
13
  }[] = [
 
 
 
 
 
 
 
 
14
  {
15
  version: "v0.16.0",
16
  date: "growth phase \u00b7 round three",
 
11
  code?: string;
12
  kind?: "spec" | "vote" | "add";
13
  }[] = [
14
+ {
15
+ version: "v0.16.1",
16
+ date: "growth phase \u00b7 a small fix",
17
+ title: "DSSL.lint stops crying wolf on pages that ship compiled CSS and run the engine.",
18
+ why: "the new css-loses check, run on this very site, reported 4,314 conflicts: the compiled stylesheet and the engine say the same thing, which is not a conflict.",
19
+ kind: "add",
20
+ body: "css-loses now compares values. A rule is reported only when its value differs from what DSSL wrote inline, so a page that links the output of dssl build and also runs the engine is quiet, and a real conflict (your padding-top: 40px against DSSL's padding: 10) is still named, with the fix.",
21
+ },
22
  {
23
  version: "v0.16.0",
24
  date: "growth phase \u00b7 round three",