From 633a6de1114ee067a84f171b1cfe18840e07f165 Mon Sep 17 00:00:00 2001 From: Claude Date: Wed, 22 Jul 2026 12:25:27 +0000 Subject: [PATCH 1/2] feat(create-bestax): add controlled-Burger Navbar to the landing archetype MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The landing archetype of bestax-layout-scaffold had no Navbar, so agents scaffolding marketing pages never saw the controlled Burger pattern and shipped mobile menus that could never open (bare with no active state — a silent failure), plus inline padding offsets instead of has-navbar-fixed-top. - examples/landing.tsx: fixed-top Navbar with useState-wired Navbar.Burger/Navbar.Menu and has-navbar-fixed-top on , mirroring app-shell.tsx - references/archetypes.md §2: same pattern in the skeleton, plus a Required note on controlled burger wiring and the fixed-top class - SKILL.md: controlled-burger rule in Approach and Checklist; updated landing example description - constants.ts CLAUDE_MD House style: one always-in-context line on controlled Burger/Menu wiring and has-navbar-fixed-top Closes #348 Co-Authored-By: Claude Fable 5 Claude-Session: https://claude.ai/code/session_01JDRUvpEgaMAV2UBPokA7hR --- create-bestax/src/constants.ts | 3 ++ skills/bestax-layout-scaffold/SKILL.md | 9 ++-- .../examples/landing.tsx | 42 ++++++++++++++++++- .../references/archetypes.md | 28 ++++++++++++- 4 files changed, 76 insertions(+), 6 deletions(-) diff --git a/create-bestax/src/constants.ts b/create-bestax/src/constants.ts index 4312ae4b4..3f060d63d 100644 --- a/create-bestax/src/constants.ts +++ b/create-bestax/src/constants.ts @@ -139,6 +139,9 @@ ${setupLines.join('\n')} take a \`gap\` prop, so prefer that there). - Compose existing components before writing custom CSS; theme via \`Theme\` and \`--bulma-*\` variables, never hardcoded colors. +- \`Navbar.Burger\`/\`Navbar.Menu\` are controlled — wire \`active\` via state on both, and pair + \`Navbar fixed="top"\` with the \`has-navbar-fixed-top\` class on \`\` (never an inline + padding offset). - There is no test runner or Storybook in this app — don't assume one. ## AI skills diff --git a/skills/bestax-layout-scaffold/SKILL.md b/skills/bestax-layout-scaffold/SKILL.md index e66843603..185e4d9f4 100644 --- a/skills/bestax-layout-scaffold/SKILL.md +++ b/skills/bestax-layout-scaffold/SKILL.md @@ -45,8 +45,10 @@ Centered; a collection of items → Card grid. For mixed requests, pick the domi `height: 100%` on the card doesn't help — the column's height is auto). - Rely on Bulma's responsive defaults: `Columns` sit side by side on tablet and up and stack on mobile. Add responsive `size*` props only to tune the breakpoints. -- For a `fixed="top"` `Navbar`, add the `has-navbar-fixed-top` class to `` so content is not - hidden behind it — the library does not do this automatically. +- `Navbar.Burger`/`Navbar.Menu` are **controlled** — wire `active` via state on both, or the + mobile menu can never open (no error, silent failure). For a `fixed="top"` `Navbar`, add the + `has-navbar-fixed-top` class to `` so content is not hidden behind it — the library does + not do this automatically, and an inline padding offset is not a substitute. - **Style with helper props, not inline `style`.** Use `m`/`p` spacing (`mt="4"` = 1rem), `textAlign="centered"`, and `textColor`/`bgColor` instead of `style={{ marginTop, textAlign, color }}`. Set the app-wide icon library once with `` at the root @@ -69,7 +71,7 @@ color }}`. Set the app-wide icon library once with ``. - [ ] Do not use `Tile` — it is not shipped. - [ ] Style with helper props (`mt`/`p`, `textAlign`, `textColor`), not inline `style`. diff --git a/skills/bestax-layout-scaffold/examples/landing.tsx b/skills/bestax-layout-scaffold/examples/landing.tsx index 9066e701b..56d9a23d7 100644 --- a/skills/bestax-layout-scaffold/examples/landing.tsx +++ b/skills/bestax-layout-scaffold/examples/landing.tsx @@ -1,8 +1,16 @@ -// Marketing / landing page — Hero + stacked Sections + Footer. +// Marketing / landing page — fixed top Navbar + Hero + stacked Sections + Footer. // Each Section stacks vertically; the feature Columns collapse to one per row on // mobile (Bulma columns stack below the tablet breakpoint). -import React from 'react'; +// +// The Navbar's burger/menu is CONTROLLED: without `active` state wired to both +// `Navbar.Burger` and `Navbar.Menu`, the mobile menu can never open — desktop +// looks fine and nothing errors, so the failure is silent. A fixed-top navbar +// also needs the `has-navbar-fixed-top` class on so the page is padded +// below it (never an inline padding offset) — Bulma requires this and the +// library does NOT add it for you. +import React, { useEffect, useState } from 'react'; import { + Navbar, Hero, Section, Container, @@ -24,8 +32,38 @@ const FEATURES = [ ]; export default function LandingPage() { + const [menuOpen, setMenuOpen] = useState(false); + + useEffect(() => { + document.documentElement.classList.add('has-navbar-fixed-top'); + return () => { + document.documentElement.classList.remove('has-navbar-fixed-top'); + }; + }, []); + return ( <> + + + Acme + setMenuOpen(open => !open)} + aria-label="menu" + aria-expanded={menuOpen} + /> + + + + Features + Pricing + + + Sign in + + + + diff --git a/skills/bestax-layout-scaffold/references/archetypes.md b/skills/bestax-layout-scaffold/references/archetypes.md index 7ab7ab2c3..af28ffce3 100644 --- a/skills/bestax-layout-scaffold/references/archetypes.md +++ b/skills/bestax-layout-scaffold/references/archetypes.md @@ -75,6 +75,26 @@ pricing page. The default for "build me a site/page". ```tsx <> + + + Brand + setOpen(o => !o)} + aria-label="menu" + /> + + + + Features + Pricing + + + Sign in + + + + @@ -113,7 +133,13 @@ pricing page. The default for "build me a site/page". ``` -**Responsive:** `Section`s already stack vertically. The feature `Columns` collapse to one feature +**Required:** `Navbar.Burger`/`Navbar.Menu` are **controlled** — wire `active` via state on both +(a bare `` renders a burger that can never open, with no error). And add +`has-navbar-fixed-top` to `` (see `examples/landing.tsx`) so content is not hidden behind +the fixed navbar — never an inline padding offset. + +**Responsive:** the navbar collapses to a burger on mobile (`Navbar.Burger` + `Navbar.Menu active`). +`Section`s already stack vertically. The feature `Columns` collapse to one feature per row on mobile. Use `Hero size="large"` / `"fullheight"` for a taller hero. **Hero CTAs:** on a colored hero use **filled** buttons only — `color="light"` for the primary From f3387de3c5d0da5f67c97eb0a4ff90052bba6aa3 Mon Sep 17 00:00:00 2001 From: Claude Date: Wed, 22 Jul 2026 23:03:02 +0000 Subject: [PATCH 2/2] fix(create-bestax): precise burger/menu semantics and state prelude in skeletons MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Addresses CodeRabbit review on #355: - SKILL.md + landing.tsx header: replace the 'menu can never open' overclaim with the precise contract — active on Navbar.Menu controls visibility, active + onClick on Navbar.Burger make the burger toggle and animate; wiring both is still required - archetypes.md: define the open/setOpen state in the §1 and §2 skeletons instead of using it undeclared, and align the §2 Required note with the precise wording Co-Authored-By: Claude Fable 5 Claude-Session: https://claude.ai/code/session_01JDRUvpEgaMAV2UBPokA7hR --- skills/bestax-layout-scaffold/SKILL.md | 10 ++++++---- skills/bestax-layout-scaffold/examples/landing.tsx | 8 +++++--- .../references/archetypes.md | 14 ++++++++++---- 3 files changed, 21 insertions(+), 11 deletions(-) diff --git a/skills/bestax-layout-scaffold/SKILL.md b/skills/bestax-layout-scaffold/SKILL.md index 185e4d9f4..e078b8ad9 100644 --- a/skills/bestax-layout-scaffold/SKILL.md +++ b/skills/bestax-layout-scaffold/SKILL.md @@ -45,10 +45,12 @@ Centered; a collection of items → Card grid. For mixed requests, pick the domi `height: 100%` on the card doesn't help — the column's height is auto). - Rely on Bulma's responsive defaults: `Columns` sit side by side on tablet and up and stack on mobile. Add responsive `size*` props only to tune the breakpoints. -- `Navbar.Burger`/`Navbar.Menu` are **controlled** — wire `active` via state on both, or the - mobile menu can never open (no error, silent failure). For a `fixed="top"` `Navbar`, add the - `has-navbar-fixed-top` class to `` so content is not hidden behind it — the library does - not do this automatically, and an inline padding offset is not a substitute. +- `Navbar.Burger`/`Navbar.Menu` are **controlled** — wire the same `active` state to both: + `active` on `Navbar.Menu` shows/hides the mobile menu, while `active` + `onClick` on + `Navbar.Burger` make the burger toggle it and animate. Left unwired, clicking the burger + does nothing (no error, silent failure). For a `fixed="top"` `Navbar`, add the + `has-navbar-fixed-top` class to `` so content is not hidden behind it — the library + does not do this automatically, and an inline padding offset is not a substitute. - **Style with helper props, not inline `style`.** Use `m`/`p` spacing (`mt="4"` = 1rem), `textAlign="centered"`, and `textColor`/`bgColor` instead of `style={{ marginTop, textAlign, color }}`. Set the app-wide icon library once with `` at the root diff --git a/skills/bestax-layout-scaffold/examples/landing.tsx b/skills/bestax-layout-scaffold/examples/landing.tsx index 56d9a23d7..731789d2e 100644 --- a/skills/bestax-layout-scaffold/examples/landing.tsx +++ b/skills/bestax-layout-scaffold/examples/landing.tsx @@ -2,9 +2,11 @@ // Each Section stacks vertically; the feature Columns collapse to one per row on // mobile (Bulma columns stack below the tablet breakpoint). // -// The Navbar's burger/menu is CONTROLLED: without `active` state wired to both -// `Navbar.Burger` and `Navbar.Menu`, the mobile menu can never open — desktop -// looks fine and nothing errors, so the failure is silent. A fixed-top navbar +// The Navbar's burger/menu is CONTROLLED: `active` on Navbar.Menu shows/hides +// the mobile menu, while `active` + `onClick` on Navbar.Burger make the burger +// toggle it and animate. Wire the same state to both — left unwired, clicking +// the burger does nothing; desktop looks fine and nothing errors, so the +// failure is silent. A fixed-top navbar // also needs the `has-navbar-fixed-top` class on so the page is padded // below it (never an inline padding offset) — Bulma requires this and the // library does NOT add it for you. diff --git a/skills/bestax-layout-scaffold/references/archetypes.md b/skills/bestax-layout-scaffold/references/archetypes.md index af28ffce3..c5d6dc9c5 100644 --- a/skills/bestax-layout-scaffold/references/archetypes.md +++ b/skills/bestax-layout-scaffold/references/archetypes.md @@ -19,6 +19,8 @@ app". **Skeleton:** ```tsx +const [open, setOpen] = useState(false); // controls the burger + mobile menu + <> @@ -54,7 +56,7 @@ app". - +; ``` **Required:** add `has-navbar-fixed-top` to `` (see `examples/app-shell.tsx`) so content is @@ -74,6 +76,8 @@ pricing page. The default for "build me a site/page". **Skeleton:** ```tsx +const [open, setOpen] = useState(false); // controls the burger + mobile menu + <> @@ -130,11 +134,13 @@ pricing page. The default for "build me a site/page". {/* footer */} - +; ``` -**Required:** `Navbar.Burger`/`Navbar.Menu` are **controlled** — wire `active` via state on both -(a bare `` renders a burger that can never open, with no error). And add +**Required:** `Navbar.Burger`/`Navbar.Menu` are **controlled** — wire the same `active` state to +both: `active` on `Navbar.Menu` shows/hides the mobile menu, and `active` + `onClick` on +`Navbar.Burger` make the burger toggle it and animate (a bare `` does nothing +when clicked, with no error). And add `has-navbar-fixed-top` to `` (see `examples/landing.tsx`) so content is not hidden behind the fixed navbar — never an inline padding offset.