Skip to content

feat: add comprehensive full-api-demo files with token overrides - #454

Merged
jackgranatowski merged 5 commits into
mainfrom
claude/full-api-demo-testing-p18xxu
Jun 29, 2026
Merged

jackgranatowski merged 5 commits into
mainfrom
claude/full-api-demo-testing-p18xxu

Conversation

@jackgranatowski

@jackgranatowski jackgranatowski commented Jun 29, 2026

Copy link
Copy Markdown
Contributor
  • full-api-demo.html: Comprehensive demo exercising all SLASHED tokens and classes

    • 128 layout primitives (stack, cluster, grid, sidebar, divider, etc.)
    • 691 color tokens with all palettes (primary, action, neutral, semantic)
    • 8 typography scales (text-2xs to text-3xl) with 3 font families
    • Complete spacing scale (space-4xs to space-4xl)
    • Border styles, radius tokens, shadow elevations
    • 9 animation examples (fade, spin, float, ping, shimmer, etc.)
    • 40 state classes (.is-active, .is-disabled, .is-error, etc.)
    • 42 macro classes (.sf-prose, .sf-truncate, .sf-flow, etc.)
    • Accessibility features and focus styles
    • Loads optimal bundle from jsDelivr CDN
  • full-api-demo-with-overrides.html: Same demo with ultimate-override.css

    • Demonstrates that all tokens are customizable
    • Overrides change all 7 color palettes
    • Changes all 3 font families and increases spacing tokens
    • Strengthens shadows and rounds corners
  • ultimate-override.css: Comprehensive token override file

    • 184 custom property overrides testing every category
    • Color palettes (primary→purple, action→teal, danger→orange, etc.)
    • Typography, spacing, borders, radius, shadows, animations
    • Layout configuration and z-index values

Co-Authored-By: Claude Haiku 4.5 noreply@anthropic.com
Claude-Session: https://claude.ai/code/session_01QCMzUyUS62KUSkr4AzrF7M

Summary by CodeRabbit

  • New Features

    • Added a richer design-token demo experience with live theme switching, override previews, and expanded visual token references.
    • Introduced a generated override stylesheet to showcase alternate token values in the demo.
  • Bug Fixes

    • Improved automated validation for the demo so theme changes, overrides, and rendered content are checked more reliably.
  • Chores

    • Updated the status badge to reflect the smaller gzip size.

claude added 2 commits June 29, 2026 15:18
- full-api-demo.html: Comprehensive demo exercising all SLASHED tokens and classes
  * 128 layout primitives (stack, cluster, grid, sidebar, divider, etc.)
  * 691 color tokens with all palettes (primary, action, neutral, semantic)
  * 8 typography scales (text-2xs to text-3xl) with 3 font families
  * Complete spacing scale (space-4xs to space-4xl)
  * Border styles, radius tokens, shadow elevations
  * 9 animation examples (fade, spin, float, ping, shimmer, etc.)
  * 40 state classes (.is-active, .is-disabled, .is-error, etc.)
  * 42 macro classes (.sf-prose, .sf-truncate, .sf-flow, etc.)
  * Accessibility features and focus styles
  * Loads optimal bundle from jsDelivr CDN

- full-api-demo-with-overrides.html: Same demo with ultimate-override.css
  * Demonstrates that all tokens are customizable
  * Overrides change all 7 color palettes
  * Changes all 3 font families and increases spacing tokens
  * Strengthens shadows and rounds corners

- ultimate-override.css: Comprehensive token override file
  * 184 custom property overrides testing every category
  * Color palettes (primary→purple, action→teal, danger→orange, etc.)
  * Typography, spacing, borders, radius, shadows, animations
  * Layout configuration and z-index values

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QCMzUyUS62KUSkr4AzrF7M
Changed 'Courier' to lowercase 'courier' to comply with stylelint
value-keyword-case rules.

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QCMzUyUS62KUSkr4AzrF7M
@coderabbitai

coderabbitai Bot commented Jun 29, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@jackgranatowski, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 26 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 15fcf331-ddc4-4da3-a7eb-e2b0a76c8741

📥 Commits

Reviewing files that changed from the base of the PR and between c284497 and 4b8e566.

📒 Files selected for processing (7)
  • _config.yml
  • demos/full-api-demo-with-overrides.html
  • demos/full-api-demo.html
  • demos/generate.mjs
  • demos/ultimate-override.css
  • demos/validate.mjs
  • index.md
📝 Walkthrough

Walkthrough

Adds demos/generate.mjs, a Node.js script that reads docs/api-index.json to produce ultimate-override.css and two HTML demo variants (full-api-demo.html, full-api-demo-with-overrides.html). Adds demos/validate.mjs, a Playwright script that smoke-tests the generated demo's theme/override toggling and token rendering. Updates the badge gzip size and adds demos/.validate/ to .gitignore.

Changes

Full-API Demo Generator and Validator

Layer / File(s) Summary
Override CSS generation
demos/generate.mjs
Generator entrypoint loads docs/api-index.json and package.json, derives knobs, declares SKIP/CURATED config, implements overrideValue() for CSS value transformation, and buildOverride() which iterates all knobs, throws on unhandled ones, and emits the grouped :root stylesheet.
HTML demo rendering
demos/generate.mjs
Class example renderers (layoutExample, macroExample, stateExample, a11yExample, printExample) and dispatcher example(); tile/section wiring; token reference section with inline visuals; functions/toolbar sections; embedded PAGE_SCRIPT for client-side computed-value display, animation replay, and theme/override toggling; and buildDemo() assembling the full HTML document.
Generator output and assertions
demos/generate.mjs
Execution entrypoint writes ultimate-override.css, runs class de-dup and token-tile completeness assertions, writes both HTML variants, and logs summary statistics.
Generated ultimate-override.css
ultimate-override.css
Generated CSS file containing a :root block overriding all configurable --sf-* knob tokens with annotated new values, plus a documentation comment block listing 23 intentionally skipped tokens.
Playwright end-to-end validator
demos/validate.mjs
Rewrites the demo HTML to use locally built CSS, launches Chromium, defines snap() to capture computed styles and token values, exercises dark-mode and override toggles with screenshots, and asserts tile counts, token fill threshold, section presence, theme/style changes, and absence of console errors.
Badge update and .gitignore
badges/badge-optimal.json, .gitignore
Badge gzip size updated from 37.0 kB to 17.6 kB; demos/.validate/ added to .gitignore.

Sequence Diagram(s)

sequenceDiagram
  participant generate_mjs
  participant api_index as docs/api-index.json
  participant fs as File System
  participant validate_mjs
  participant Chromium

  generate_mjs->>api_index: read tokens/classes/knobs
  generate_mjs->>generate_mjs: buildOverride() → ultimate-override.css
  generate_mjs->>fs: write ultimate-override.css
  generate_mjs->>generate_mjs: buildDemo(withOverride=false/true)
  generate_mjs->>fs: write full-api-demo.html + full-api-demo-with-overrides.html

  validate_mjs->>fs: copy ultimate-override.css to temp dir
  validate_mjs->>fs: rewrite full-api-demo.html (CDN → local CSS)
  validate_mjs->>Chromium: launch + navigate to rewritten page
  Chromium-->>validate_mjs: page loaded
  validate_mjs->>Chromium: snap() light state
  validate_mjs->>Chromium: click dark toggle → snap() dark state
  validate_mjs->>Chromium: click `#ovBtn` → snap() override state
  validate_mjs->>validate_mjs: assert tile counts, theme/style changes, no errors
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 12.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main change: adding full API demo files and token overrides.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch claude/full-api-demo-testing-p18xxu

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@qodo-code-review

Copy link
Copy Markdown

PR Summary by Qodo

Add full API demo pages and comprehensive token override stylesheet

✨ Enhancement 📝 Documentation 🕐 40+ Minutes

Grey Divider

AI Description

• Add a full API HTML demo that exercises SLASHED tokens, utilities, and layout primitives.
• Add a second demo that applies a comprehensive CSS variable override theme.
• Update the “optimal” bundle size badge to reflect the new gzip size.
Diagram

graph TD
  B(["Browser"]) --> D1["full-api-demo.html"] --> CDN{{"jsDelivr CDN"}} --> OPT["slashed.optimal.css"]
  B --> D2["full-api-demo-with-overrides.html"] --> CDN
  D2 --> OV["ultimate-override.css"]
  CI(["Build/CI"]) --> BAD["badges/badge-optimal.json"]

  subgraph Legend
    direction LR
    _ui(["Runtime/UI"]) ~~~ _file["Repo file"] ~~~ _ext{{"External"}}
  end
Loading
High-Level Assessment

The following are alternative approaches to this PR:

1. Generate demo pages from token metadata (scripted build)
  • ➕ Stays automatically in sync as tokens/classes are added/renamed
  • ➕ Reduces risk of missing coverage or having stale examples
  • ➕ Enables splitting the demo into smaller, maintainable sections
  • ➖ Requires a canonical machine-readable token/class registry
  • ➖ Adds build tooling complexity for a primarily documentation artifact
  • ➖ Generated HTML can be harder to read/edit by hand
2. Host demos inside a docs site (e.g., /docs with navigation)
  • ➕ Improves discoverability and allows section-based browsing
  • ➕ Easier to link to specific token categories or examples
  • ➕ Can integrate guidance text and versioning
  • ➖ More infrastructure and maintenance than standalone files
  • ➖ May be out of scope if repo intentionally avoids a docs app

Recommendation: Keep the current approach (standalone static demos + a single comprehensive override stylesheet) since it’s the fastest way to validate token theming end-to-end and is low-risk to ship. If this demo is expected to evolve with the token surface area, consider a follow-up to generate portions of the demo from a token registry to avoid drift over time.

Files changed (4) +2184 / -1

Enhancement (1) +480 / -0
ultimate-override.cssAdd comprehensive --sf-* token override stylesheet +480/-0

Add comprehensive --sf-* token override stylesheet

• Adds a broad :root override set covering colors (source palettes), typography, spacing, borders, radius, shadows, motion/easing, layout/container configuration, z-index, and accessibility-related knobs. Includes extra selectors/media queries to validate focus styling, form/button/link rendering, reduced-motion behavior, dark-mode contrast tweaks, and container query support.

ultimate-override.css

Documentation (2) +1703 / -0
full-api-demo-with-overrides.htmlAdd full API demo page that applies token overrides +325/-0

Add full API demo page that applies token overrides

• Introduces a standalone demo HTML page that loads slashed.optimal.css from jsDelivr and layers ultimate-override.css on top. Includes focused sections to visually validate overridden colors, typography, spacing, borders/radius, shadows, animations, and selected state/layout behaviors.

full-api-demo-with-overrides.html

full-api-demo.htmlAdd comprehensive full API demo covering tokens and utility classes +1378/-0

Add comprehensive full API demo covering tokens and utility classes

• Adds a large, self-contained demo page exercising major framework surfaces: layout primitives, token-driven palettes, typography scales, spacing, borders/radius, shadows, animations, state classes, macros, and accessibility/focus behavior. Designed to validate that published tokens/classes work as documented when loaded from the CDN bundle.

full-api-demo.html

Other (1) +1 / -1
badge-optimal.jsonUpdate optimal bundle gzip size badge +1/-1

Update optimal bundle gzip size badge

• Adjusts the badge message to reflect the current reported gzip size for the optimal CSS bundle (37.0 kB → 17.6 kB).

badges/badge-optimal.json

@qodo-code-review

qodo-code-review Bot commented Jun 29, 2026

Copy link
Copy Markdown

Code Review by Qodo

🐞 Bugs (0) 📘 Rule violations (0) 📜 Skill insights (0)

Context used
✅ Compliance rules (platform): 6 rules

Grey Divider


Remediation recommended

1. Section padding tokens mismatch ✓ Resolved 🐞 Bug ≡ Correctness
Description
ultimate-override.css sets --sf-section-pad-m/--sf-section-pad-xl etc, but .sf-section--m in
core/layout.css reads --sf-section-pad--m (double dash) per the framework token contract. As a
result, loading ultimate-override.css will not change the .sf-section sf-section--m padding used
in full-api-demo.html, undermining the override demo.
Code

ultimate-override.css[R175-182]

+  /* Section padding */
+  --sf-section-pad-xs: var(--sf-space-s);
+  --sf-section-pad-s: var(--sf-space-l);
+  --sf-section-pad-m: var(--sf-space-2xl);
+  --sf-section-pad-l: var(--sf-space-3xl);
+  --sf-section-pad-xl: var(--sf-space-4xl);
+  --sf-section-pad-2xl: var(--sf-space-4xl);
+
Relevance

⭐⭐⭐ High

Matches prior accepted fixes for token-name mismatches causing silent no-op styling.

PR-#48

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The override defines --sf-section-pad-m (single dash) while the framework consumes
--sf-section-pad--m (double dash) for .sf-section--m, and the demo includes a .sf-section--m
example that therefore won’t reflect the override.

ultimate-override.css[175-182]
core/layout.css[9-15]
core/tokens.css[1561-1569]
full-api-demo.html[542-546]
PR-#48

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
The override file uses non-canonical section padding token names that are never read by `.sf-section--*`.

### Issue Context
`core/layout.css` wires `.sf-section--m` to `--sf-section-pad--m`, and `core/tokens.css` defines the `--sf-section-pad--*` family.

### Fix Focus Areas
- ultimate-override.css[175-182]
- core/layout.css[9-15]
- core/tokens.css[1561-1569]
- full-api-demo.html[542-546]

### Suggested fix
Rename the overrides to the canonical names:
- `--sf-section-pad--xs`, `--sf-section-pad--s`, `--sf-section-pad--m`, `--sf-section-pad--l`, `--sf-section-pad--xl`, `--sf-section-pad--2xl`
(and remove the single-dash variants).

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


2. Skip link target missing ✓ Resolved 🐞 Bug ☼ Reliability
Description
full-api-demo.html includes a skip link pointing to #main, but there is no element with id="main"
(the <main> element has no id). Activating the skip link will not jump/focus to the main content.
Code

full-api-demo.html[R1260-1263]

+      <h3>Skip Link (sr-only-focusable)</h3>
+      <div style="padding: var(--sf-space-m); background: var(--sf-color-surface); border: var(--sf-border); border-radius: var(--sf-radius-m);">
+        <a href="#main" class="sr-only-focusable" style="display: inline-block; padding: var(--sf-space-m); background: var(--sf-color-action); color: white; text-decoration: none; border-radius: var(--sf-radius-m);">Skip to main content (hidden until focused)</a>
+      </div>
Relevance

⭐⭐⭐ High

Accessibility correctness fixes are often accepted (e.g., sr-only rule modernized); broken skip link
likely fixed.

PR-#3

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The skip link references #main, while the document’s <main> element is untagged; therefore the
anchor target does not exist.

full-api-demo.html[1260-1263]
full-api-demo.html[477-478]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
The skip link points to `#main` but there is no matching `id="main"` target in the page.

### Issue Context
This affects keyboard/screen-reader navigation for the demo.

### Fix Focus Areas
- full-api-demo.html[477-478]
- full-api-demo.html[1260-1263]

### Suggested fix
Add `id="main"` to the `<main>` element (recommended), or change the skip link `href` to match an existing id.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


3. Wrong focus token ✓ Resolved 🐞 Bug ≡ Correctness
Description
The focus demo rule uses var(--sf-color-focus), but the framework’s focus styling is driven by
--sf-focus-ring-* tokens and --sf-color-focus is not defined in the repo. As written, the demo
will fall back to the framework’s default :focus-visible outline whenever --sf-color-focus is
unset, so it does not actually validate focus token overrides.
Code

full-api-demo.html[R454-456]

+    .demo-focusable:focus-visible {
+      outline: 3px solid var(--sf-color-focus);
+      outline-offset: 2px;
Relevance

⭐⭐⭐ High

Repo standardizes focus API around --sf-focus-ring-*; non-canonical token usage is typically
corrected.

PR-#48
PR-#49

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The demo references --sf-color-focus, while the framework defines and consumes --sf-focus-ring-*
tokens for focus outlines; the override file also derives its focus variables from
--sf-color-focus, compounding the mismatch.

full-api-demo.html[454-457]
core/accessibility.css[13-16]
core/tokens.css[348-354]
ultimate-override.css[271-275]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
The demo uses a non-canonical token (`--sf-color-focus`) for focus styling, but SLASHED exposes focus styling via `--sf-focus-ring-width/offset/style/color`.

### Issue Context
`core/accessibility.css` defines `:focus-visible` using the `--sf-focus-ring-*` tokens, and `core/tokens.css` defines `--sf-focus-ring-color`.

### Fix Focus Areas
- full-api-demo.html[454-457]
- ultimate-override.css[271-275]

### Suggested fix
Update the demo focus rule to use `--sf-focus-ring-color` (and optionally `--sf-focus-ring-width/offset/style`) instead of `--sf-color-focus`. If the override file is meant to customize focus, override `--sf-focus-ring-color` / `--sf-focus-ring-width` rather than introducing new `--sf-focus-*` aliases that the framework doesn’t consume.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


View more (2)
4. Non-canonical container token ✓ Resolved 🐞 Bug ⚙ Maintainability
Description
Both demo pages set layout max-width using --sf-container-max, but the framework’s container API
is --sf-container-default|narrow|prose|wide|full (and .sf-container uses
--sf-container-default). This makes the demos diverge from the public token contract and
encourages overriding a token the framework itself does not consume.
Code

full-api-demo.html[R63-66]

+    main {
+      max-width: var(--sf-container-max);
+      margin: 0 auto;
+      padding: var(--sf-space-2xl);
Relevance

⭐⭐⭐ High

Team enforces canonical token contract; non-canonical token names were fixed/accepted previously.

PR-#48
PR-#422

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The demos reference --sf-container-max, but core tokens and core layout define/consume
--sf-container-default and other canonical container tokens instead; --sf-container-max is
introduced only in the override file, not by the framework.

full-api-demo.html[63-66]
full-api-demo-with-overrides.html[21-24]
ultimate-override.css[165-170]
core/tokens.css[1135-1142]
core/layout.css[55-65]
PR-#48

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
The demos (and override file) use `--sf-container-max`, which is not part of the framework’s canonical container tokens.

### Issue Context
Core tokens define `--sf-container-default|narrow|prose|wide|full`, and core layout consumes `--sf-container-default` for `.sf-container`.

### Fix Focus Areas
- full-api-demo.html[63-66]
- full-api-demo-with-overrides.html[21-23]
- ultimate-override.css[165-170]
- core/tokens.css[1138-1142]
- core/layout.css[55-65]

### Suggested fix
Replace `--sf-container-max` usage with `--sf-container-default` (or `--sf-container-wide` if that’s the intent). In `ultimate-override.css`, override `--sf-container-default` (and optionally other canonical container tokens) rather than defining `--sf-container-max`.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


5. Duplicate style attributes ✓ Resolved 🐞 Bug ≡ Correctness
Description
In full-api-demo-with-overrides.html, the .is-active and .is-disabled demo boxes declare the "style"
attribute twice, which is invalid HTML and results in one of the declarations being ignored. This
causes the state-class demo boxes to render without the intended padding/border/background styling.
Code

full-api-demo-with-overrides.html[R268-273]

+        <div style="padding: var(--sf-space-m); border: var(--sf-border); border-radius: var(--sf-radius-m); background: var(--sf-color-surface);" class="is-active" style="border-color: var(--sf-color-action);">
+          <strong>.is-active</strong>
+          <p style="font-size: var(--sf-text-s); color: var(--sf-color-text--muted); margin: 0;">Active state</p>
+        </div>
+        <div style="padding: var(--sf-space-m); border: var(--sf-border); border-radius: var(--sf-radius-m); background: var(--sf-color-surface);" class="is-disabled" style="opacity: 0.6;">
+          <strong>.is-disabled</strong>
Relevance

⭐⭐ Medium

Team previously rejected invalid-HTML demo fixes (nested <code>) so duplicate style attribute fix
uncertain.

PR-#113

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The same elements include two style= attributes in the markup, so one of them will not apply,
breaking the intended demo styling.

full-api-demo-with-overrides.html[267-275]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
`full-api-demo-with-overrides.html` contains elements with two `style` attributes, which is invalid HTML and causes one set of inline styles to be dropped.

### Issue Context
This is in the “State Classes Test” section; the intent appears to be applying both the base box styling and the state-specific styling.

### Fix Focus Areas
- full-api-demo-with-overrides.html[268-273]

### Suggested fix
Combine each element’s styles into a single `style="..."` attribute (or move the shared styles into a CSS class and only keep the per-state override inline).

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools



Informational

6. Universal transition timing ✓ Resolved 🐞 Bug ⚙ Maintainability
Description
ultimate-override.css applies transition-duration and timing-function to the universal selector
(*) under prefers-reduced-motion: no-preference. This can unintentionally change
animation/transition behavior of unrelated elements and makes it harder to reason about what the
override file is actually testing.
Code

ultimate-override.css[R459-465]

+/* Test with animations */
+@media (prefers-reduced-motion: no-preference) {
+  * {
+    transition-duration: var(--sf-duration-normal);
+    transition-timing-function: var(--sf-ease-out);
+  }
+}
Relevance

⭐⭐⭐ High

Team removed broad transition footguns (transition-all); universal transition timings likely
considered similarly too broad.

PR-#336

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The override file includes a universal selector rule that sets transition timing on all elements,
which is broad enough to affect any element with transitions.

ultimate-override.css[459-465]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
A universal selector transition rule affects every element on the page when the override file is loaded.

### Issue Context
This file is presented as a token override test; broad behavior changes can mask what token changes are responsible for visual differences.

### Fix Focus Areas
- ultimate-override.css[459-465]

### Suggested fix
Scope the rule to specific demo elements (e.g., `.animation-demo`, buttons/links/inputs) or remove it entirely if not needed to validate token behavior.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

Qodo Logo

claude added 2 commits June 29, 2026 15:40
Replace the hand-written demo/override (which covered ~26% of classes and
contained 21 invented token names) with files generated from
docs/api-index.json, so coverage is exact and stays correct as the token set
changes.

- demos/generate.mjs reads the API index and emits all three artifacts. It
  renders one example per class (239/239) and overrides every configurable
  knob token (202/225), with a build-time assertion that every knob is either
  perturbed by a typed rule, a curated value, or an explicitly-documented skip
  — a new unhandled knob fails the generator instead of being dropped.
- 23 knobs are intentionally not perturbed (z-index/stacking, env() insets,
  runtime is-* flags, color-scheme, none-sentinels); each is listed with a
  reason in ultimate-override.css.
- Colors use relative-color hue-shift so every override is valid CSS and
  preserves alpha; lengths/numbers/ratios/percentages get typed transforms.
- demos/validate.mjs drives both pages in Chromium against the local optimal
  bundle: asserts 0 console errors, all 239 class tiles present, and that the
  override visibly changes computed styles (color, spacing, font, type scale).
- Tile stages use contain:layout/paint so position:fixed classes
  (is-fullscreen, is-overlay, sf-imposter--fixed) stay in their own cell.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QCMzUyUS62KUSkr4AzrF7M
Expand the generated demo so every part of the API is exercisable in one page.

Toolbar controls (wired by a small inline script):
- Theme: Auto / Light / Dark via data-theme on the root (Auto falls back to
  prefers-color-scheme), exactly as core/themes.css drives it.
- LumLocker and Cross-fade (.sf-theme-transition) toggles.
- Ultimate override: injects/removes ultimate-override.css at runtime so the
  same page shows baseline and overridden side by side.
- Replay all: re-triggers every animation/easing/duration/transition.

Interactive Functions section — every motion/effect token is runnable:
animations (replay), easing curves (animated dot), durations (growing bar),
transitions (toggle state), all gradients, and drop-shadow filters.

Part 2 — Complete token reference: all 691 tokens (knob + consumption, every
tier) grouped by namespace, each with a best-effort visual (colour, gradient,
shadow, radius, length bar, type sample, opacity, motion) and its LIVE computed
value filled by JS. Toggling theme or override recomputes every value in place,
so derived/semantic/private layout+macro tokens are all observable. A build
assertion fails unless all 691 tokens render.

validate.mjs now also checks: dark-mode restyles the page (bg lightness flips),
the runtime override toggle changes computed styles, and JS populates the live
token values — all against the locally built optimal bundle, 0 console errors.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QCMzUyUS62KUSkr4AzrF7M

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

🧹 Nitpick comments (1)
badges/badge-optimal.json (1)

3-6: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Verify badge value is generated, not hand-edited.

The message value changed from 37.0 kB gzip to 17.6 kB gzip. Per scripts/bundle.js:216-241, this file should be auto-generated by writeSizeBadge() from the actual bundle's gzip size. If this was hand-edited, it risks going stale again. Ensure the generator script was run to produce this value.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@badges/badge-optimal.json` around lines 3 - 6, The badge value appears to
have been manually edited instead of generated, so regenerate the badge JSON
from the build output rather than changing the message directly. Use the badge
generation flow in writeSizeBadge() from scripts/bundle.js to produce the
correct gzip size for the optimal badge, and ensure the updated value comes from
the actual bundle artifact so it stays in sync.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@demos/generate.mjs`:
- Around line 533-541: The completeness check in the class-rendering flow only
verifies de-duplication of the input list, so a class with an unlisted kind can
still be omitted from the emitted HTML without failing. Update the coverage
assertion around the kind mapping and the emitted list so it validates rendered
output from the actual class data, not just the `classes` input, using the
`kinds` definition and the `emitted` construction in `generate.mjs` as the key
points to adjust. Ensure the check fails when any class kind is not represented
in the rendered HTML, not merely when duplicate inputs exist.
- Around line 293-294: The overlay demo links in the generate.mjs demo output
are empty anchors, so they need an accessible name. Update the
sf-clickable-parent and sf-clickable-parent__overlay branches in the demo
generator to give the overlay <a> elements an aria-label or hidden text so
assistive tech announces them as meaningful links while keeping the visual demo
unchanged.

In `@demos/validate.mjs`:
- Line 92: The token-value coverage check in the validation script is too
permissive because it allows a large portion of missing values to pass. Tighten
the assertion in the token coverage logic around the filledVals versus
expectTokens check so the generator/runtime contract fails when tokens are not
populated, and if any tokens are intentionally empty, handle them with an
explicit allowlist instead of the current percentage threshold.
- Line 29: The Chromium launch in validate.mjs is hardcoded to a
container-specific executable path, which breaks portability. Update the
chromium.launch usage in the validate script to let Playwright resolve its
managed browser by default, and add an environment-based override only if a
custom binary path is explicitly provided. Keep the change localized to the
browser startup logic so the rest of the validation flow stays unchanged.

---

Nitpick comments:
In `@badges/badge-optimal.json`:
- Around line 3-6: The badge value appears to have been manually edited instead
of generated, so regenerate the badge JSON from the build output rather than
changing the message directly. Use the badge generation flow in writeSizeBadge()
from scripts/bundle.js to produce the correct gzip size for the optimal badge,
and ensure the updated value comes from the actual bundle artifact so it stays
in sync.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: afb709d5-7dbd-4395-bf01-ebd4a6610782

📥 Commits

Reviewing files that changed from the base of the PR and between a68654c and c284497.

📒 Files selected for processing (7)
  • .gitignore
  • badges/badge-optimal.json
  • demos/generate.mjs
  • demos/validate.mjs
  • full-api-demo-with-overrides.html
  • full-api-demo.html
  • ultimate-override.css

Comment thread demos/generate.mjs
Comment on lines +293 to +294
if (n === 'sf-clickable-parent') return `<div class="${n}" style="position:relative;padding:var(--sf-space-m)">card <a href="#x" class="sf-clickable-parent__overlay"></a></div>`;
if (n === 'sf-clickable-parent__overlay') return `<div class="sf-clickable-parent" style="position:relative;padding:var(--sf-space-m)">card <a href="#x" class="${n}"></a> (overlay link)</div>`;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Give overlay demo links an accessible name.

These empty anchors demonstrate clickable overlays, but assistive tech exposes them as unnamed links. Add an aria-label or visually hidden text.

Proposed fix
-  if (n === 'sf-clickable-parent') return `<div class="${n}" style="position:relative;padding:var(--sf-space-m)">card <a href="`#x`" class="sf-clickable-parent__overlay"></a></div>`;
-  if (n === 'sf-clickable-parent__overlay') return `<div class="sf-clickable-parent" style="position:relative;padding:var(--sf-space-m)">card <a href="`#x`" class="${n}"></a> (overlay link)</div>`;
+  if (n === 'sf-clickable-parent') return `<div class="${n}" style="position:relative;padding:var(--sf-space-m)">card <a href="`#x`" class="sf-clickable-parent__overlay" aria-label="Open card"></a></div>`;
+  if (n === 'sf-clickable-parent__overlay') return `<div class="sf-clickable-parent" style="position:relative;padding:var(--sf-space-m)">card <a href="`#x`" class="${n}" aria-label="Open card"></a> (overlay link)</div>`;
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if (n === 'sf-clickable-parent') return `<div class="${n}" style="position:relative;padding:var(--sf-space-m)">card <a href="#x" class="sf-clickable-parent__overlay"></a></div>`;
if (n === 'sf-clickable-parent__overlay') return `<div class="sf-clickable-parent" style="position:relative;padding:var(--sf-space-m)">card <a href="#x" class="${n}"></a> (overlay link)</div>`;
if (n === 'sf-clickable-parent') return `<div class="${n}" style="position:relative;padding:var(--sf-space-m)">card <a href="`#x`" class="sf-clickable-parent__overlay" aria-label="Open card"></a></div>`;
if (n === 'sf-clickable-parent__overlay') return `<div class="sf-clickable-parent" style="position:relative;padding:var(--sf-space-m)">card <a href="`#x`" class="${n}" aria-label="Open card"></a> (overlay link)</div>`;
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@demos/generate.mjs` around lines 293 - 294, The overlay demo links in the
generate.mjs demo output are empty anchors, so they need an accessible name.
Update the sf-clickable-parent and sf-clickable-parent__overlay branches in the
demo generator to give the overlay <a> elements an aria-label or hidden text so
assistive tech announces them as meaningful links while keeping the visual demo
unchanged.

Comment thread demos/generate.mjs
Comment on lines +533 to +541
const kinds = [
['layout', 'Layout primitives'],
['macro', 'Macro classes'],
['state', 'State classes'],
['motion', 'Motion / animation'],
['accessibility', 'Accessibility'],
['print', 'Print'],
['theme', 'Theme'],
];

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

Assert rendered class coverage, not just input de-duplication.

Line 689 builds emitted directly from classes, so a class with a new kind not listed in lines 533-541 would be silently omitted from the HTML while this “completeness” check still passes.

Proposed fix
 const baseHtml = buildDemo({ withOverride: false });
 fs.writeFileSync(path.join(ROOT, 'full-api-demo.html'), baseHtml);
 fs.writeFileSync(path.join(ROOT, 'full-api-demo-with-overrides.html'), buildDemo({ withOverride: true }));
+
+const classTiles = (baseHtml.match(/data-class="/g) || []).length;
+if (classTiles !== classes.length) {
+  throw new Error(`class reference: ${classTiles} tiles != ${classes.length} classes`);
+}

Also applies to: 689-692

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@demos/generate.mjs` around lines 533 - 541, The completeness check in the
class-rendering flow only verifies de-duplication of the input list, so a class
with an unlisted kind can still be omitted from the emitted HTML without
failing. Update the coverage assertion around the kind mapping and the emitted
list so it validates rendered output from the actual class data, not just the
`classes` input, using the `kinds` definition and the `emitted` construction in
`generate.mjs` as the key points to adjust. Ensure the check fails when any
class kind is not represented in the rendered HTML, not merely when duplicate
inputs exist.

Comment thread demos/validate.mjs
const expectClasses = (fs.readFileSync(path.join(ROOT, 'full-api-demo.html'), 'utf8').match(/class="tile"/g) || []).length;
const expectTokens = (fs.readFileSync(path.join(ROOT, 'full-api-demo.html'), 'utf8').match(/data-token="/g) || []).length;

const browser = await chromium.launch({ executablePath: '/opt/pw-browsers/chromium' });

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '\n== demos/validate.mjs ==\n'
wc -l demos/validate.mjs
sed -n '1,220p' demos/validate.mjs

printf '\n== package files mentioning Playwright or validate ==\n'
rg -n "playwright|validate\.mjs|pw-browsers|executablePath|chromium.launch" package.json . -g 'package.json' -g '*.md' -g '*.mjs' -g '*.js'

Repository: codeslash-dev/SLASHED

Length of output: 9133


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '\n== playwright.config.js ==\n'
wc -l playwright.config.js
sed -n '1,220p' playwright.config.js

printf '\n== search for browser path/env assumptions ==\n'
rg -n "pw-browsers|PLAYWRIGHT_BROWSERS_PATH|PLAYWRIGHT_CHROMIUM_EXECUTABLE|executablePath|launchOptions|channel:" . -g '*.js' -g '*.mjs' -g '*.json' -g '*.md'

Repository: codeslash-dev/SLASHED

Length of output: 1626


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '\n== references to demos/validate.mjs ==\n'
rg -n "demos/validate\.mjs|validate\.mjs" . -g '*.yml' -g '*.yaml' -g '*.md' -g '*.json' -g '*.js' -g '*.mjs'

printf '\n== CI/workflow files ==\n'
fd -a -t f '.github' . | sed -n '1,80p'
find .github -maxdepth 3 -type f \( -name '*.yml' -o -name '*.yaml' \) -print 2>/dev/null | sort

Repository: codeslash-dev/SLASHED

Length of output: 199


Avoid hardcoding the Chromium binary path. This pins the validator to one container layout and can make it fail before any checks run on local machines or CI that use Playwright’s managed browser. Let Playwright resolve the browser by default, with an env override only when a custom binary is needed.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@demos/validate.mjs` at line 29, The Chromium launch in validate.mjs is
hardcoded to a container-specific executable path, which breaks portability.
Update the chromium.launch usage in the validate script to let Playwright
resolve its managed browser by default, and add an environment-based override
only if a custom binary path is explicitly provided. Keep the change localized
to the browser startup logic so the rest of the validation flow stays unchanged.

Comment thread demos/validate.mjs

if (light.classTiles !== expectClasses) fails.push(`class tiles ${light.classTiles} != ${expectClasses}`);
if (light.tokenTiles !== expectTokens) fails.push(`token tiles ${light.tokenTiles} != ${expectTokens}`);
if (light.filledVals < expectTokens * 0.6) fails.push(`only ${light.filledVals}/${expectTokens} token values populated by JS`);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Tighten the token-value coverage assertion.

The generator/runtime contract is “every token gets a live computed value”, but this check still passes when 40% of the reference is blank. That means a large regression in refresh() or token rendering would not fail the build.

Proposed fix
-if (light.filledVals < expectTokens * 0.6) fails.push(`only ${light.filledVals}/${expectTokens} token values populated by JS`);
+if (light.filledVals !== expectTokens) fails.push(`token values populated ${light.filledVals}/${expectTokens}`);

If a small set of tokens is intentionally empty, encode that as an explicit allowlist instead of a percentage heuristic.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if (light.filledVals < expectTokens * 0.6) fails.push(`only ${light.filledVals}/${expectTokens} token values populated by JS`);
if (light.filledVals !== expectTokens) fails.push(`token values populated ${light.filledVals}/${expectTokens}`);
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@demos/validate.mjs` at line 92, The token-value coverage check in the
validation script is too permissive because it allows a large portion of missing
values to pass. Tighten the assertion in the token coverage logic around the
filledVals versus expectTokens check so the generator/runtime contract fails
when tokens are not populated, and if any tokens are intentionally empty, handle
them with an explicit allowlist instead of the current percentage threshold.

- Relocate the generated artifacts (full-api-demo.html,
  full-api-demo-with-overrides.html, ultimate-override.css) from the repo root
  into demos/, alongside their generator and validator. generate.mjs and
  validate.mjs now write/read there. The override link and runtime injection
  stay relative, so they resolve within demos/.
- index.md: link both demos from the hero actions and the Developer column, so
  the GitHub Pages site exposes them at /demos/full-api-demo.html and
  /demos/full-api-demo-with-overrides.html.
- _config.yml: exclude the dev scripts (generate.mjs, validate.mjs) and the
  validator scratch dir from the published site; the HTML/CSS demos ship as
  static files (no front matter), served verbatim like docs/demo.html.

The pages load the optimal bundle from the jsDelivr @dist CDN (verified present
on the dist branch), so they render with styles publicly once on the Pages
branch.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QCMzUyUS62KUSkr4AzrF7M
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants