Skip to content

fix(landing): bento tile, mobile nav, hero acronym, visual polish - #499

Merged
jackgranatowski merged 11 commits into
mainfrom
claude/bento-ui-plugin-docs-865tpu
Jul 3, 2026
Merged

fix(landing): bento tile, mobile nav, hero acronym, visual polish#499
jackgranatowski merged 11 commits into
mainfrom
claude/bento-ui-plugin-docs-865tpu

Conversation

@jackgranatowski

@jackgranatowski jackgranatowski commented Jul 2, 2026

Copy link
Copy Markdown
Contributor

Summary

Follow-up fixes to the landing page draft, addressing review feedback:

  • Bento featured tile looked odd: the color-ramp demo was anchored to the bottom of the 2×2-span card via margin-block-start: auto, leaving a large empty gap between the paragraph and the ramp. Added an alpha-ramp row + labels and centered the card's content as a group instead, so it fills the space.
  • Header nav ugly / broken on mobile: text links wrapped into three cramped rows with oversized buttons on real mobile (confirmed with proper touch-device emulation, not just window-resizing). Split the text-link cluster from the CTA/theme-toggle cluster and drop the links below 48em instead of wrapping.
  • Animated acronym shrunk on mobile: the any-hover-gated vw-based size cap could shrink the headline below the tagline on narrow hover-capable viewports, and touch devices got an unreachable hover-reveal interaction that wrapped into an ugly orphaned line ("/D" alone). Rethought for mobile: since there's no working hover affordance on touch, show the full manifesto words directly instead of hiding them behind a dead interaction. Desktop keeps the collapsed-letters hover-reveal, now sized off container-query units with a readable floor instead of raw viewport width.
  • Zero oomph: subtle gradient wash behind the hero, a gradient top-edge on every card, dividers in the stats strip, a tinted band for the Philosophy section for visual rhythm — all composed from existing framework tokens (gradients, alpha colors), no raw values. Also dropped the emoji feature-card icons.

Type

  • fix
  • feat
  • docs
  • chore / tooling

Test plan

  • Verified mobile layout with real device emulation (iPhone 13, any-hover: none), not just a resized desktop window
  • Verified desktop hover-unfold interaction still works and fits on one line
  • Verified dark mode
  • Verified tablet breakpoint (~800px)

https://claude.ai/code/session_012kga5ydHSnFupfqph6vU73

claude added 11 commits July 2, 2026 12:19
Correct stale facts on both surfaces: token count (685, was 840),
cascade layer count (fifteen, was sixteen), hardcoded landing-page
version, and the npm link (the 'slashed' npm package is an unrelated
project). Label the staged component/utility layers honestly, point
the WordPress plugin link at SLASHED-Plugins, and restructure both
pages around a quick-start-first flow.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019y4H17xqMWoEgvxv3BRM98
Restore the live README.md and index.md to their previous state and
park the rewritten versions in copy-wip/ pending review.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019y4H17xqMWoEgvxv3BRM98
The draft landing page in copy-wip/ carries Jekyll front matter and the
site uses jekyll-optional-front-matter, so without the exclusion both
drafts would be rendered and served publicly under /copy-wip/.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019y4H17xqMWoEgvxv3BRM98
Replace the hand-styled copy-wip landing draft with a standalone page
styled entirely by slashed.optimal.css: layout via sf-section /
sf-container / sf-stack / sf-cluster / sf-grid, macros (sf-prose,
sf-surface, sf-text-gradient, sf-divider), scroll-driven sf-entrance
animations, and base element styling for code blocks and tables. The
only page-specific rules live in the reserved slashed.overrides layer
and compose framework tokens exclusively — no raw colors, sizes, or
fonts. Dark mode, fluid type, and pre overflow all come from the
framework; a small nav toggle demos data-theme. Now .html with
layout:null front matter since the page carries its own document
shell (the default layout's hardcoded styles would fight it).

Verified with Playwright against a local build of badges/: light,
dark, and 390px mobile all render clean with no console errors.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019y4H17xqMWoEgvxv3BRM98
Add a 'name is the philosophy' section to the README draft and a
matching manifesto band to the landing-page draft: one verifiable
commitment per letter (Standalone, Lean, Agnostic, Structured, Hybrid,
Explicit, Deterministic), each grounded in a documented framework
behaviour rather than slogan-ware.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019y4H17xqMWoEgvxv3BRM98
Make the philosophy the hero: the wordmark renders as S/L/A/S/H/E/D
with gradient initials, and each letter unfolds into its manifesto
word on hover (pure CSS — max-width/opacity transitions on framework
motion tokens). Add a giant gradient slash watermark, a stats strip
(685 tokens / 15 layers / 0 JS / 0 build steps), and rebuild the
features section on the framework's own sf-bento grid with live token
demos: the real --sf-color-primary 50–950 ramp, hover/active/status
chips, side-by-side data-theme panels, the fluid type scale, and a
layer-stack visual. The install band is forced dark via
data-theme="dark" as a section-theming demo; its code blocks pin to
surface/text tokens because code tokens don't yet follow scoped
data-theme. Entrances stagger via the framework's scroll-timeline
range knobs. Still token-only styling in the slashed.overrides layer.

Verified with Playwright: light, dark, hero hover state, and 390px
mobile (no horizontal overflow, no console errors).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019y4H17xqMWoEgvxv3BRM98
Storage-restricted browsers can throw on localStorage reads/writes;
fall back to in-memory state so the toggle still initializes and
cycles without persistence.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019y4H17xqMWoEgvxv3BRM98
Switch the stylesheet href from the site-local /badges/ build artifact
to the dist-branch jsDelivr URL, matching the install instructions the
page itself gives. Verified with Playwright that the page requests the
exact CDN URL and renders correctly against the minified bundle.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019y4H17xqMWoEgvxv3BRM98
The unfold interaction could hand the hover to a neighbouring letter:
the centered row re-centers as a word expands, sliding letters under
the stationary cursor and re-firing the effect in a cascade. Fix by
expanding each word to an exact measured width (--w, in the row's own
ch context, weight-inherited so the units agree) and counter-shifting
the row by exactly --w/2 with the same duration/easing/delay, so the
hovered letter never moves. Gate the interaction to any-hover devices,
forbid wrapping mid-interaction with a viewport-capped font size, add
a 120ms sweep-guard delay, and honour prefers-reduced-motion.
Verified with Playwright: hovering each of the 7 letters keeps the
cursor on the same letter through the full animation.

In the forced-dark install band, wrap code lines (pre-wrap +
overflow-wrap) instead of horizontal scrolling and extend the
theme-safe token pinning to inline code chips, which rendered
light-on-dark on real devices (same root cause as #496).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019y4H17xqMWoEgvxv3BRM98
…nl9lx4' into claude/bento-ui-plugin-docs-865tpu
- Bento featured tile: the color-ramp demo was anchored to the bottom of
  the 2x2-span card via margin-block-start:auto, leaving a huge empty gap.
  Add an alpha ramp + labels and center the content as a group instead.
- Header nav: text links wrapped into three cramped rows with oversized
  buttons on real mobile. Split link cluster from the CTA/theme-toggle
  cluster and drop the links below 48em instead of wrapping.
- Hero acronym: the any-hover-gated vw-based size cap could shrink the
  headline below the tagline on narrow hover-capable viewports, and touch
  devices got an unreachable hover-reveal with an ugly wrapped orphan line.
  Show the full manifesto words directly on no-hover devices (nothing to
  hide, since hover can't be triggered), and switch the desktop cap to
  container query units with a readable floor.
- Add a subtle gradient wash to the hero, a gradient top-edge on cards, a
  tinted band + dividers for rhythm, and drop the emoji card icons.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012kga5ydHSnFupfqph6vU73
@coderabbitai

coderabbitai Bot commented Jul 2, 2026

Copy link
Copy Markdown

Warning

Review limit reached

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

Next review available in: 50 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: f80d3264-c684-4df1-9d9c-a3a2012702f7

📥 Commits

Reviewing files that changed from the base of the PR and between 5f34a8a and 09026ce.

📒 Files selected for processing (3)
  • _config.yml
  • copy-wip/github-pages-index.html
  • copy-wip/github-readme.md
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch claude/bento-ui-plugin-docs-865tpu

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

Stage rewritten README + landing-page drafts in copy-wip and exclude from Pages

📝 Documentation ⚙️ Configuration changes 🕐 40+ Minutes

Grey Divider

AI Description

• Add rewritten README and landing-page draft copy under copy-wip/ for review.
• Fix stale project facts/links in the staged copy (tokens/layers, CDN/npm/plugin URLs).
• Prevent copy-wip drafts from being published by excluding copy-wip/ from the Jekyll build.
Diagram

graph TD
  A["Docs author"] --> B["copy-wip/ drafts"]
  A --> C["_config.yml"] --> D["GitHub Pages (Jekyll)"] --> E["Published site"]
  C -. "exclude copy-wip" .-> B
Loading
High-Level Assessment

The following are alternative approaches to this PR:

1. Use Jekyll’s _drafts/ (or a non-rendered collection) instead of copy-wip/
  • ➕ Conventional Jekyll workflow; drafts are naturally non-published
  • ➕ Reduces need for explicit exclude rules and avoids accidental publication
  • ➖ Requires reorganizing draft files and potentially adjusting site structure
  • ➖ Drafts may be less discoverable for reviewers who browse repo folders
2. Keep drafts on a dedicated docs branch (no in-repo drafts)
  • ➕ Zero risk of accidental publication on main branch
  • ➕ Keeps repository tree cleaner for end users
  • ➖ Harder to review alongside code changes in a single PR
  • ➖ Less convenient to iterate on copy with code-adjacent context
3. Remove Jekyll front matter from drafts to prevent rendering
  • ➕ No config change required; drafts won’t be treated as Jekyll pages
  • ➖ Easier to accidentally reintroduce publishing later
  • ➖ Loses the ability to preview drafts locally via Jekyll when desired

Recommendation: Current approach (stage in copy-wip/ and explicitly exclude it in _config.yml) is a pragmatic middle ground: reviewers can see the proposed copy in-repo while GitHub Pages is protected from publishing it. If drafts become long-lived, consider migrating to _drafts/ or a dedicated non-published collection to align with standard Jekyll conventions and reduce reliance on manual excludes.

Files changed (3) +870 / -0

Documentation (2) +869 / -0
github-pages-index.htmlAdd landing page draft rebuilt on SLASHED’s own CSS +678/-0

Add landing page draft rebuilt on SLASHED’s own CSS

• Introduces a full draft landing page (with Jekyll front matter) styled via the framework’s CDN bundle and minimal token-only overrides. Updates/embeds corrected product facts (685 tokens, 15 layers) and adds quick-start-first structure with install snippets and doc links.

copy-wip/github-pages-index.html

github-readme.mdAdd rewritten README draft emphasizing quick start and corrected facts +191/-0

Add rewritten README draft emphasizing quick start and corrected facts

• Adds a draft README with updated first-contact copy, corrected project metrics/links, and reorganized sections (quick install, philosophy, bundles, browser support, docs index). Clarifies staged layers/utilities status and updates the WordPress plugin repository link.

copy-wip/github-readme.md

Other (1) +1 / -0
_config.ymlExclude copy-wip/ from the GitHub Pages build +1/-0

Exclude copy-wip/ from the GitHub Pages build

• Adds copy-wip/ to Jekyll’s exclude list so draft pages aren’t rendered or published under the site root. This prevents accidental exposure caused by optional front matter rendering.

_config.yml

@jackgranatowski jackgranatowski changed the title docs: rewrite README and landing page as first-contact copy fix(landing): bento tile, mobile nav, hero acronym, visual polish Jul 2, 2026
@qodo-code-review

Copy link
Copy Markdown

Code Review by Qodo

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

Context used
✅ Compliance rules (platform): 11 rules

Grey Divider


Action required

1. Docs rewrite not published 🐞 Bug ≡ Correctness
Description
This PR adds the rewritten landing page/README under copy-wip/ but also excludes copy-wip from
the Jekyll build, so the deployed Pages site will not include the new content. The published
homepage (index.md) therefore continues to ship stale facts (v0.6.19, 840 tokens, sixteen layers)
and the wrong npm package link.
Code

_config.yml[R8-13]

exclude:
  - node_modules
+  - copy-wip
  - configurator
  - configurator-archive
  - core
Relevance

⭐⭐⭐ High

Team fixes published Pages docs issues; Jekyll/landing updates in PR296 and broken-doc link fix
accepted in PR415.

PR-#296
PR-#415
PR-#420

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
copy-wip/ is explicitly excluded from Jekyll, and the Pages workflow builds the site via Jekyll
from the repo root; therefore the newly added copy-wip landing/README files will not appear in the
deployed _site. The existing index.md still contains the stale counts/version and the incorrect
npm link, so those remain user-visible after deployment.

_config.yml[8-18]
.github/workflows/deploy-configurator.yml[67-93]
copy-wip/github-pages-index.html[1-16]
copy-wip/github-readme.md[1-25]
index.md[123-193]

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 PR adds updated “first-contact” copy as `copy-wip/github-pages-index.html` and `copy-wip/github-readme.md`, but `_config.yml` excludes `copy-wip` from the Jekyll build. The Pages deployment workflow builds the site via Jekyll using this config, so `copy-wip/` content will not be present in `_site/`.

As a result, `index.md` remains the deployed homepage and continues to contain stale/incorrect facts (token count, layer count, hardcoded release version, and the npm link).

## Issue Context
- GitHub Pages is built by `.github/workflows/deploy-configurator.yml` using `actions/jekyll-build-pages@v1`, which honors `_config.yml` exclusions.
- The new copy is currently only present under `copy-wip/`.

## Fix Focus Areas
- _config.yml[8-18]
- .github/workflows/deploy-configurator.yml[67-93]
- index.md[123-244]
- copy-wip/github-pages-index.html[1-40]
- copy-wip/github-readme.md[1-40]

## Suggested fix
- Move/port the rewritten landing page content into the actual published homepage (`index.md`), or otherwise update the Pages build so the new landing page is generated at `/`.
- Apply the rewritten README content to the repository’s actual `README.md` (or add an explicit build step that replaces it), instead of leaving it only in `copy-wip/`.
- If `copy-wip/` is intended to be published for review, remove it from `_config.yml` `exclude:` (or add an `include:`/copy step) and ensure the desired route is linked/served.

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



Remediation recommended

2. Unvalidated theme state 🐞 Bug ☼ Reliability
Description
github-pages-index.html loads slashed-home-theme from localStorage and, for any non-auto
value, writes it directly into <html data-theme>. If the stored value is anything other than
light/dark, the page stops matching the framework’s theme selectors (and stops following OS
scheme) until the user clicks to cycle back to a valid state.
Code

copy-wip/github-pages-index.html[R659-674]

+    (function () {
+      var btn = document.getElementById('theme-toggle');
+      var states = ['auto', 'dark', 'light'];
+      var current = 'auto';
+      try { current = localStorage.getItem('slashed-home-theme') || 'auto'; } catch (e) {}
+      function apply(state) {
+        if (state === 'auto') document.documentElement.removeAttribute('data-theme');
+        else document.documentElement.setAttribute('data-theme', state);
+        btn.textContent = state[0].toUpperCase() + state.slice(1);
+      }
+      apply(current);
+      btn.addEventListener('click', function () {
+        current = states[(states.indexOf(current) + 1) % states.length];
+        try { localStorage.setItem('slashed-home-theme', current); } catch (e) {}
+        apply(current);
+      });
Relevance

⭐⭐⭐ High

Repo repeatedly hardens/validates localStorage-persisted theme/state; accepted in PR323 (uiTheme
validation) and PR460.

PR-#323
PR-#460

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The script sets data-theme to arbitrary stored values, but the framework only defines theme
behavior for data-theme="light" and data-theme="dark" (and OS-following only when the attribute
is absent), so an unexpected value prevents correct theme activation.

copy-wip/github-pages-index.html[656-675]
core/themes.css[8-18]

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 theme toggle reads a persisted string from `localStorage` and passes it into `apply()` without validating it against the supported state set. Any unexpected value causes the script to set an unsupported `data-theme` attribute value on `<html>`, preventing the framework’s `[data-theme="light"]` / `[data-theme="dark"]` selectors from applying.

## Issue Context
Framework theme switching is implemented via selectors for only `light` and `dark` values, and OS-following mode depends on the *absence* of the `data-theme` attribute.

## Fix Focus Areas
- copy-wip/github-pages-index.html[656-675]

## Suggested fix
- After reading `current` from `localStorage`, normalize it:
 - if `current` is not in `['auto','dark','light']`, set it to `'auto'`.
- Optionally guard against `btn` being null before dereferencing (`btn.textContent`, `btn.addEventListener`).

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


Grey Divider

Qodo Logo

Comment thread _config.yml
Comment on lines 8 to 13
exclude:
- node_modules
- copy-wip
- configurator
- configurator-archive
- core

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Action required

1. Docs rewrite not published 🐞 Bug ≡ Correctness

This PR adds the rewritten landing page/README under copy-wip/ but also excludes copy-wip from
the Jekyll build, so the deployed Pages site will not include the new content. The published
homepage (index.md) therefore continues to ship stale facts (v0.6.19, 840 tokens, sixteen layers)
and the wrong npm package link.
Agent Prompt
## Issue description
The PR adds updated “first-contact” copy as `copy-wip/github-pages-index.html` and `copy-wip/github-readme.md`, but `_config.yml` excludes `copy-wip` from the Jekyll build. The Pages deployment workflow builds the site via Jekyll using this config, so `copy-wip/` content will not be present in `_site/`.

As a result, `index.md` remains the deployed homepage and continues to contain stale/incorrect facts (token count, layer count, hardcoded release version, and the npm link).

## Issue Context
- GitHub Pages is built by `.github/workflows/deploy-configurator.yml` using `actions/jekyll-build-pages@v1`, which honors `_config.yml` exclusions.
- The new copy is currently only present under `copy-wip/`.

## Fix Focus Areas
- _config.yml[8-18]
- .github/workflows/deploy-configurator.yml[67-93]
- index.md[123-244]
- copy-wip/github-pages-index.html[1-40]
- copy-wip/github-readme.md[1-40]

## Suggested fix
- Move/port the rewritten landing page content into the actual published homepage (`index.md`), or otherwise update the Pages build so the new landing page is generated at `/`.
- Apply the rewritten README content to the repository’s actual `README.md` (or add an explicit build step that replaces it), instead of leaving it only in `copy-wip/`.
- If `copy-wip/` is intended to be published for review, remove it from `_config.yml` `exclude:` (or add an `include:`/copy step) and ensure the desired route is linked/served.

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

Comment on lines +659 to +674
(function () {
var btn = document.getElementById('theme-toggle');
var states = ['auto', 'dark', 'light'];
var current = 'auto';
try { current = localStorage.getItem('slashed-home-theme') || 'auto'; } catch (e) {}
function apply(state) {
if (state === 'auto') document.documentElement.removeAttribute('data-theme');
else document.documentElement.setAttribute('data-theme', state);
btn.textContent = state[0].toUpperCase() + state.slice(1);
}
apply(current);
btn.addEventListener('click', function () {
current = states[(states.indexOf(current) + 1) % states.length];
try { localStorage.setItem('slashed-home-theme', current); } catch (e) {}
apply(current);
});

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Remediation recommended

2. Unvalidated theme state 🐞 Bug ☼ Reliability

github-pages-index.html loads slashed-home-theme from localStorage and, for any non-auto
value, writes it directly into <html data-theme>. If the stored value is anything other than
light/dark, the page stops matching the framework’s theme selectors (and stops following OS
scheme) until the user clicks to cycle back to a valid state.
Agent Prompt
## Issue description
The theme toggle reads a persisted string from `localStorage` and passes it into `apply()` without validating it against the supported state set. Any unexpected value causes the script to set an unsupported `data-theme` attribute value on `<html>`, preventing the framework’s `[data-theme="light"]` / `[data-theme="dark"]` selectors from applying.

## Issue Context
Framework theme switching is implemented via selectors for only `light` and `dark` values, and OS-following mode depends on the *absence* of the `data-theme` attribute.

## Fix Focus Areas
- copy-wip/github-pages-index.html[656-675]

## Suggested fix
- After reading `current` from `localStorage`, normalize it:
  - if `current` is not in `['auto','dark','light']`, set it to `'auto'`.
- Optionally guard against `btn` being null before dereferencing (`btn.textContent`, `btn.addEventListener`).

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

@jackgranatowski
jackgranatowski merged commit 2ca0872 into main Jul 3, 2026
13 checks passed
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