create-bestax 3.3.3 β†’ 3.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -22,8 +22,9 @@ export declare const MESSAGES: {
22
22
  readonly PROJECT_CREATED: "βœ” Done! Project created successfully.";
23
23
  readonly NEXT_STEPS: "Next steps:";
24
24
  readonly HAPPY_CODING: "Happy coding! πŸŽ‰";
25
- readonly SKILLS_ADDED: "βœ” Installed bestax AI skills into .claude/skills/ (+ CLAUDE.md)";
25
+ readonly SKILLS_ADDED: "βœ” Installed bestax AI skills into .claude/skills/ (+ CLAUDE.md, .claude/launch.json)";
26
26
  };
27
+ export declare const LAUNCH_JSON: string;
27
28
  export declare const PROMPTS: {
28
29
  readonly PROJECT_NAME: "Project name:";
29
30
  readonly SELECT_FRAMEWORK: "Select a framework:";
@@ -1 +1 @@
1
- {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,MAAM,WAAW,QAAQ;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,OAAO,KAAK,CAAC,MAAM,CAAC;CAC5B;AAED,eAAO,MAAM,SAAS,EAAE,QAAQ,EAG/B,CAAC;AAEF,eAAO,MAAM,oBAAoB,kBAAkB,CAAC;AACpD,eAAO,MAAM,uBAAuB,MAAM,CAAC;AAC3C,eAAO,MAAM,kBAAkB,QAAsB,CAAC;AAEtD,eAAO,MAAM,QAAQ;;;;;;;wCAaQ,MAAM;uCAEP,MAAM;sCACP,MAAM;4CAEA,MAAM;;;;;CAM7B,CAAC;AAEX,eAAO,MAAM,OAAO;;;;;;CAOV,CAAC;AAOX,eAAO,MAAM,2BAA2B,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAK9D,CAAC;AAKF,MAAM,WAAW,eAAe;IAC9B,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,eAAO,MAAM,SAAS,GACpB,aAAa,MAAM,EACnB,8BAA8B,eAAe,KAC5C,MA+DF,CAAC;AAEF,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,OAAO,KAAK,CAAC,MAAM,CAAC;IAC3B,WAAW,CAAC,EAAE,MAAM,CAAC;IAIrB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B;AAED,eAAO,MAAM,cAAc,EAAE,WAAW,EA6CvC,CAAC;AAEF,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,KAAK,EAAE,OAAO,KAAK,CAAC,MAAM,CAAC;IAC3B,eAAe,EAAE,MAAM,CAAC;IACxB,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AAED,eAAO,MAAM,aAAa,EAAE,WAAW,EA4CtC,CAAC"}
1
+ {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,MAAM,WAAW,QAAQ;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,OAAO,KAAK,CAAC,MAAM,CAAC;CAC5B;AAED,eAAO,MAAM,SAAS,EAAE,QAAQ,EAG/B,CAAC;AAEF,eAAO,MAAM,oBAAoB,kBAAkB,CAAC;AACpD,eAAO,MAAM,uBAAuB,MAAM,CAAC;AAC3C,eAAO,MAAM,kBAAkB,QAAsB,CAAC;AAEtD,eAAO,MAAM,QAAQ;;;;;;;wCAaQ,MAAM;uCAEP,MAAM;sCACP,MAAM;4CAEA,MAAM;;;;;CAM7B,CAAC;AASX,eAAO,MAAM,WAAW,QAed,CAAC;AAEX,eAAO,MAAM,OAAO;;;;;;CAOV,CAAC;AAOX,eAAO,MAAM,2BAA2B,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAK9D,CAAC;AAKF,MAAM,WAAW,eAAe;IAC9B,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,eAAO,MAAM,SAAS,GACpB,aAAa,MAAM,EACnB,8BAA8B,eAAe,KAC5C,MAoEF,CAAC;AAEF,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,OAAO,KAAK,CAAC,MAAM,CAAC;IAC3B,WAAW,CAAC,EAAE,MAAM,CAAC;IAIrB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B;AAED,eAAO,MAAM,cAAc,EAAE,WAAW,EA6CvC,CAAC;AAEF,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,KAAK,EAAE,OAAO,KAAK,CAAC,MAAM,CAAC;IAC3B,eAAe,EAAE,MAAM,CAAC;IACxB,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AAED,eAAO,MAAM,aAAa,EAAE,WAAW,EA4CtC,CAAC"}
package/dist/constants.js CHANGED
@@ -23,8 +23,26 @@ export const MESSAGES = {
23
23
  PROJECT_CREATED: 'βœ” Done! Project created successfully.',
24
24
  NEXT_STEPS: 'Next steps:',
25
25
  HAPPY_CODING: 'Happy coding! πŸŽ‰',
26
- SKILLS_ADDED: 'βœ” Installed bestax AI skills into .claude/skills/ (+ CLAUDE.md)',
26
+ SKILLS_ADDED: 'βœ” Installed bestax AI skills into .claude/skills/ (+ CLAUDE.md, .claude/launch.json)',
27
27
  };
28
+ // Dev-server manifest written into .claude/ with the skills opt-in so Claude
29
+ // Code's browser preview (`preview_start`) can boot the app by name instead of
30
+ // rediscovering the dev command from package.json. `npm` is deliberately
31
+ // package-manager-neutral (`npm run dev` works whichever PM installed the
32
+ // project), and `--strictPort` stops Vite from silently auto-incrementing to
33
+ // 5174 when 5173 is busy β€” a mismatch with the declared `port` must fail
34
+ // loudly, not point the preview at nothing.
35
+ export const LAUNCH_JSON = JSON.stringify({
36
+ version: '0.0.1',
37
+ configurations: [
38
+ {
39
+ name: 'dev',
40
+ runtimeExecutable: 'npm',
41
+ runtimeArgs: ['run', 'dev', '--', '--strictPort'],
42
+ port: 5173,
43
+ },
44
+ ],
45
+ }, null, 2) + '\n';
28
46
  export const PROMPTS = {
29
47
  PROJECT_NAME: 'Project name:',
30
48
  SELECT_FRAMEWORK: 'Select a framework:',
@@ -93,9 +111,14 @@ automatically when the task matches:
93
111
  - **bestax-theming** β€” colors, branding, and dark mode via the \`Theme\` component (\`colorMode\`).
94
112
  - **bestax-layout-scaffold** β€” scaffold full pages (app shell, landing, centered, card grid).
95
113
  - **bestax-icons** β€” icons via \`Icon\`/\`IconText\`: library setup, name formats, variants, a11y.
114
+ - **bestax-optimize** β€” shrink the built CSS: measure raw+gzip, then flavor switch or a modular Sass build.
96
115
 
97
116
  Prefer the library's components and these skills over hand-written Bulma markup or custom CSS.
98
117
 
118
+ \`.claude/launch.json\` declares this app's dev server for Claude Code's browser preview
119
+ (\`npm run dev\` on port 5173, \`--strictPort\`) β€” start it from there rather than rediscovering
120
+ the command.
121
+
99
122
  ## Docs
100
123
 
101
124
  - Docs site: https://bestax.io
@@ -1 +1 @@
1
- {"version":3,"file":"project-creator.d.ts","sourceRoot":"","sources":["../src/project-creator.ts"],"names":[],"mappings":"AA2BA,OAAO,EAML,KAAK,eAAe,EACrB,MAAM,gBAAgB,CAAC;AAIxB,MAAM,WAAW,aAAa;IAC5B,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,GAAG,CAAC,EAAE,OAAO,CAAC;CACf;AAED,qBAAa,cAAc;IACzB,OAAO,CAAC,YAAY,CAAS;gBAEjB,YAAY,CAAC,EAAE,MAAM;IAI3B,cAAc,CAAC,UAAU,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAa3D,sBAAsB,CAC1B,UAAU,EAAE,MAAM,EAClB,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,OAAO,CAAC;IAkBnB,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM;IAInC,YAAY,CAAC,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAMjE,WAAW,CACf,UAAU,EAAE,MAAM,EAClB,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE,eAAe,GACvB,OAAO,CAAC,IAAI,CAAC;IAiBV,gBAAgB,CACpB,UAAU,EAAE,MAAM,EAClB,WAAW,EAAE,MAAM,EACnB,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,IAAI,CAAC;IAmDhB,OAAO,CAAC,WAAW;IA2BnB,OAAO,CAAC,YAAY;IAYd,gBAAgB,CACpB,UAAU,EAAE,MAAM,EAClB,WAAW,EAAE,MAAM,EACnB,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,IAAI,CAAC;IAgJV,mBAAmB,CACvB,UAAU,EAAE,MAAM,EAClB,WAAW,EAAE,MAAM,EACnB,WAAW,EAAE,MAAM,EACnB,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,IAAI,CAAC;IAmEV,MAAM,CAAC,UAAU,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;CAwIvE"}
1
+ {"version":3,"file":"project-creator.d.ts","sourceRoot":"","sources":["../src/project-creator.ts"],"names":[],"mappings":"AA2BA,OAAO,EAOL,KAAK,eAAe,EACrB,MAAM,gBAAgB,CAAC;AAIxB,MAAM,WAAW,aAAa;IAC5B,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,GAAG,CAAC,EAAE,OAAO,CAAC;CACf;AAED,qBAAa,cAAc;IACzB,OAAO,CAAC,YAAY,CAAS;gBAEjB,YAAY,CAAC,EAAE,MAAM;IAI3B,cAAc,CAAC,UAAU,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAa3D,sBAAsB,CAC1B,UAAU,EAAE,MAAM,EAClB,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,OAAO,CAAC;IAkBnB,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM;IAInC,YAAY,CAAC,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAMjE,WAAW,CACf,UAAU,EAAE,MAAM,EAClB,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE,eAAe,GACvB,OAAO,CAAC,IAAI,CAAC;IAqBV,gBAAgB,CACpB,UAAU,EAAE,MAAM,EAClB,WAAW,EAAE,MAAM,EACnB,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,IAAI,CAAC;IAmDhB,OAAO,CAAC,WAAW;IA2BnB,OAAO,CAAC,YAAY;IAYd,gBAAgB,CACpB,UAAU,EAAE,MAAM,EAClB,WAAW,EAAE,MAAM,EACnB,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,IAAI,CAAC;IAgJV,mBAAmB,CACvB,UAAU,EAAE,MAAM,EAClB,WAAW,EAAE,MAAM,EACnB,WAAW,EAAE,MAAM,EACnB,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,IAAI,CAAC;IAmEV,MAAM,CAAC,UAAU,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;CAwIvE"}
@@ -6,7 +6,7 @@ import { checkDirectoryExists, isDirectoryEmpty, emptyDirectory, ensureDirectory
6
6
  import { promptProjectName, promptOverwriteDirectory, promptTemplate, promptIconLibrary, promptBulmaFlavor, promptInstallSkills, } from './prompts.js';
7
7
  import { displayHeader, displaySuccess, displayError, displayCancelled, } from './display.js';
8
8
  import { validateProjectName } from './validators.js';
9
- import { MESSAGES, ICON_LIBRARIES, BULMA_FLAVORS, CLAUDE_MD, CONFIG_PROVIDER_ICON_VALUES, } from './constants.js';
9
+ import { MESSAGES, ICON_LIBRARIES, BULMA_FLAVORS, CLAUDE_MD, LAUNCH_JSON, CONFIG_PROVIDER_ICON_VALUES, } from './constants.js';
10
10
  const __dirname = path.dirname(fileURLToPath(import.meta.url));
11
11
  export class ProjectCreator {
12
12
  templatesDir;
@@ -52,6 +52,7 @@ export class ProjectCreator {
52
52
  return;
53
53
  }
54
54
  await fs.copy(skillsSrc, path.join(targetPath, '.claude', 'skills'));
55
+ await fs.writeFile(path.join(targetPath, '.claude', 'launch.json'), LAUNCH_JSON);
55
56
  await fs.writeFile(path.join(targetPath, 'CLAUDE.md'), CLAUDE_MD(projectName, options));
56
57
  console.log(chalk.green(MESSAGES.SKILLS_ADDED));
57
58
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-bestax",
3
- "version": "3.3.3",
3
+ "version": "3.5.0",
4
4
  "description": "Create a new bestax-bulma project",
5
5
  "type": "module",
6
6
  "bin": {
@@ -14,8 +14,8 @@ instead of hand-writing markup.
14
14
  (`m`/`p` spacing, `textColor`/`bgColor`, `textAlign`, `display`, flex, …) β€”
15
15
  documented once in `references/api.md`.
16
16
  - **Compound components** expose sub-parts via dot access (e.g. `Card.Header`,
17
- `Navbar.Item`, `Tabs.Tab`, `Hero.Body`); see the component's linked page for the
18
- full set.
17
+ `Navbar.Item`, `Tabs.Tab`, `Hero.Body`, `Columns.Column`, `Table.Tr`); see the
18
+ component's linked page for the full set.
19
19
  - Raw `*Base` form exports (`InputBase`, `SelectBase`, `TextAreaBase`, …) are
20
20
  escape-hatch variants of the convenience wrappers above them; see the Form docs.
21
21
 
@@ -91,7 +91,8 @@ Every component also accepts the shared Bulma helper props (`m`/`p` spacing, `te
91
91
 
92
92
  ## Columns / Column
93
93
 
94
- The responsive grid. `Columns` is the row; `Column` is a cell.
94
+ The responsive grid. `Columns` is the row; `Column` is a cell (also reachable as
95
+ `Columns.Column`).
95
96
 
96
97
  **Columns**
97
98
 
@@ -156,7 +157,7 @@ the column's auto height). Make the `Column` a flex container and let the card g
156
157
 
157
158
  ## Grid / Cell
158
159
 
159
- Bulma's CSS Grid. **Preferred for uniform grids** β€” same-shaped items in a repeating pattern
160
+ Bulma's CSS Grid (`Cell` is also reachable as `Grid.Cell`). **Preferred for uniform grids** β€” same-shaped items in a repeating pattern
160
161
  (card grids, galleries, dashboards): CSS Grid gives **equal-height cells for free** (per row β€”
161
162
  each row's cells match its tallest), with no flex recipe needed. Reach for `Columns`/`Column` instead when you need proportional or
162
163
  per-breakpoint column _sizes_ (a 2/3 + 1/3 split, different counts per breakpoint).
@@ -0,0 +1,131 @@
1
+ ---
2
+ name: bestax-optimize
3
+ description: Reduce the built CSS size of an app using @allxsmith/bestax-bulma β€” measure raw and gzip size, then apply the cheapest lever that fits (lighter prebuilt CSS flavor, hand-rolled modular Sass build, import and icon-asset hygiene). Use when the CSS bundle looks too big, a size budget or Lighthouse audit flags stylesheet weight, switching bestax.css to a versions/*.css flavor, or setting up a modular @use Bulma/Sass build.
4
+ license: MIT
5
+ ---
6
+
7
+ # Optimizing CSS size with @allxsmith/bestax-bulma
8
+
9
+ The JS side is tree-shakable (the **entire** library is ~49 KB min+gzip). The stylesheet is
10
+ not: a prebuilt flavor ships all of Bulma + the bestax extras regardless of which components
11
+ the app renders. Judge stylesheet weight by the **gzipped** transfer size β€” never the raw
12
+ `dist/` number.
13
+
14
+ ## Always measure first
15
+
16
+ Run the production build, then measure the built CSS β€” raw and gzip:
17
+
18
+ ```sh
19
+ npm run build
20
+ wc -c dist/assets/*.css # raw bytes (what Vite reports)
21
+ gzip -c dist/assets/*.css | wc -c # transfer bytes (what users download)
22
+ ```
23
+
24
+ Re-measure after **every** step below and report the before/after delta (raw + gzip). Never
25
+ claim a saving without a number.
26
+
27
+ ⚠️ **~800 KB raw is ~82 KB over the wire.** Seeing ~800 KB of CSS in `dist/` is expected
28
+ with the default flavor, not a build misconfiguration β€” servers and CDNs gzip/brotli by
29
+ default. If the gzip number is already within the app's budget, say so and stop: "your CSS is
30
+ already fine" is a valid, honest outcome.
31
+
32
+ ## Decision flow
33
+
34
+ Cheapest first. Use only the library's own shipped CSS builds and SCSS sources β€” do not add
35
+ third-party build plugins (no CSS purgers/post-processors).
36
+
37
+ 1. **Flavor switch** β€” one-line import change, minutes (up to ~15 KB gzip).
38
+ 2. **Modular Sass build** β€” small `@use` file, the biggest honest win.
39
+ 3. **Import & icon-asset hygiene** β€” minor; JS and icon fonts, not the Bulma CSS.
40
+
41
+ ## Lever 1 β€” lighter prebuilt flavor
42
+
43
+ Swap the single CSS import (in `src/main.tsx` / `src/main.jsx`) between the shipped flavors.
44
+ Measured sizes drift slightly between releases β€” hence measure:
45
+
46
+ | Flavor | Import | Raw | Gzip |
47
+ | ------------ | -------------------------------------------------------------------- | -----: | -----: |
48
+ | complete | `import '@allxsmith/bestax-bulma/bestax.css';` | ~800KB | ~82 KB |
49
+ | no-dark-mode | `import '@allxsmith/bestax-bulma/versions/bestax-no-dark-mode.css';` | ~680KB | ~70 KB |
50
+ | no-helpers | `import '@allxsmith/bestax-bulma/versions/bestax-no-helpers.css';` | ~595KB | ~67 KB |
51
+
52
+ Prefixed variants (`versions/bestax-prefixed.css` ~875 KB/~84 KB,
53
+ `versions/bestax-no-helpers-prefixed.css` ~655 KB/~69 KB) exist for CSS-collision
54
+ **compatibility, not size** β€” a prefixed flavor must pair with
55
+ `<ConfigProvider classPrefix="bestax-">` at the app root, and switching a non-prefixed app to
56
+ one is never a size optimization.
57
+
58
+ - `no-dark-mode` (~12 KB gzip saved) β€” only when the app pins a single color scheme (a fixed
59
+ `Theme colorMode` / `data-theme`).
60
+ - `no-helpers` (~15 KB gzip saved) β€” **hard gate below**.
61
+
62
+ ⚠️ **The `no-helpers` gate: check for helper props first.** That flavor drops every class the
63
+ helper props compile to β€” components still render, but the props silently do nothing. Before
64
+ recommending it, grep the app's source for helper props on bestax components:
65
+
66
+ - spacing: `m`, `mt`, `mr`, `mb`, `ml`, `mx`, `my`, `p`, `pt`, `pr`, `pb`, `pl`, `px`, `py`
67
+ - color: `color`, `backgroundColor` (+ `colorShade`/`backgroundColorShade`), `textColor`, `bgColor`
68
+ - typography: `textSize`, `textAlign`, `textTransform`, `textWeight`, `fontFamily`
69
+ - display/visibility: `display`, `visibility` (+ `displayMobile`…`visibilityFullhd` viewport variants)
70
+ - flexbox: `flexDirection`, `flexWrap`, `justifyContent`, `alignContent`, `alignItems`, `alignSelf`, `flexGrow`, `flexShrink`
71
+ - misc: `float`, `overflow`, `overlay`, `interaction`, `cursor`, `radius`, `shadow`, `skeleton`, `clearfix`, `relative`, `fullHeight`
72
+
73
+ …and for raw Bulma helper classes in `className` strings (`is-*`, `has-*`, `m*-*`, `p*-*`,
74
+ `is-size-*`, `is-hidden*`, `is-flex*`). **Any hit β†’ do not use `no-helpers`**; fall back to
75
+ `no-dark-mode` or Lever 2. The bestax extras helpers (`is-cursor-*`, sizing) are dropped too.
76
+
77
+ ## Lever 2 β€” modular Sass build
78
+
79
+ Compile only the Bulma modules + bestax extras partials the app actually uses. Needs the
80
+ `sass` compiler as a dev dependency (Bulma's own build tool β€” Vite compiles `.scss` natively):
81
+
82
+ ```sh
83
+ npm install -D sass
84
+ ```
85
+
86
+ Create `src/styles.scss` β€” base + themes always come first:
87
+
88
+ ```scss
89
+ // Configure shared variables FIRST (before anything loads utilities) β€”
90
+ // the prebuilt flavors set this brand primary; omit it and buttons revert
91
+ // to Bulma's default turquoise:
92
+ @use 'bulma/sass/utilities' with (
93
+ $primary: #1e6b99
94
+ );
95
+
96
+ // Required base: reset + CSS variable definitions
97
+ @use 'bulma/sass/base';
98
+ @use 'bulma/sass/themes';
99
+
100
+ // One line per stock Bulma component the app imports…
101
+ @use 'bulma/sass/elements/button';
102
+ @use 'bulma/sass/components/navbar';
103
+ // …and per bestax extras component:
104
+ @use '@allxsmith/bestax-bulma/scss/components/dialog';
105
+ // Helper categories only if the app uses those helper props:
106
+ @use 'bulma/sass/helpers/spacing';
107
+ ```
108
+
109
+ Then replace the prebuilt CSS import in `src/main.tsx` with `import './styles.scss';`,
110
+ build, and measure. Derive the `@use` list from the components the app imports from
111
+ `@allxsmith/bestax-bulma` — the full component→partial mapping, the authoritative extras
112
+ partial inventory, and a worked example are in `references/modular-build.md`.
113
+
114
+ ## Lever 3 β€” import & icon-asset hygiene (minor)
115
+
116
+ - **Named imports.** `import * as Bestax from '@allxsmith/bestax-bulma'` defeats tree
117
+ shaking. Convert to named imports (`import { Button, Card } from …`) β€” a JS-side saving
118
+ (whole library β‰ˆ 49 KB min+gzip), so report it honestly as minor.
119
+ - **Unused icon libraries.** Scaffolded apps may carry an icon library the app never uses:
120
+ icon-font packages in `package.json` (`@fortawesome/fontawesome-free`, `@mdi/font`,
121
+ `material-icons`, `material-symbols`) with their CSS imports in `src/main.*`, or Ionicons
122
+ CDN `<script>` tags in `index.html`. Icon fonts often outweigh Bulma itself β€” if no
123
+ `<Icon>` uses that library, delete the dependency/import/script. Pure win, no tooling.
124
+
125
+ ## References
126
+
127
+ - `references/modular-build.md` — full Lever 2 procedure: component→partial mapping, the
128
+ authoritative extras partial inventory, helper categories, and a worked `styles.scss`.
129
+ - Docs: [Optimizing CSS Size](https://bestax.io/docs/guides/getting-started/optimizing-css) Β·
130
+ [Modular β€” Option C](https://bestax.io/docs/guides/getting-started/modular#option-c--hand-rolled-modular-scss-advanced) Β·
131
+ [CSS Variations](https://bestax.io/docs/guides/getting-started/variations#file-size-comparison)
@@ -0,0 +1,173 @@
1
+ # Modular Sass build — component→partial mapping and procedure
2
+
3
+ Build a stylesheet containing only what the app uses, from the library's own SCSS sources.
4
+ This is the "Option C" pattern from the
5
+ [Modular guide](https://bestax.io/docs/guides/getting-started/modular#option-c--hand-rolled-modular-scss-advanced).
6
+
7
+ ## Prerequisites
8
+
9
+ ```sh
10
+ npm install -D sass
11
+ ```
12
+
13
+ `sass` is Bulma's own compiler, dev-only. Vite compiles `.scss` out of the box β€” no plugin.
14
+ `bulma` is already present as a dependency of `@allxsmith/bestax-bulma`, and the library
15
+ publishes its SCSS sources (`src/scss` ships in the npm package, exposed via the
16
+ `@allxsmith/bestax-bulma/scss/*` export).
17
+
18
+ ## The required base β€” always first
19
+
20
+ ```scss
21
+ // Configure shared variables FIRST β€” a Sass module can only be configured on
22
+ // its first load, and every Bulma module loads utilities internally. The
23
+ // prebuilt bestax flavors set this brand primary; omit it and is-primary
24
+ // reverts to Bulma's default turquoise (verified failure mode).
25
+ @use 'bulma/sass/utilities' with (
26
+ $primary: #1e6b99
27
+ );
28
+
29
+ // Required: reset + CSS variable definitions
30
+ @use 'bulma/sass/base';
31
+ @use 'bulma/sass/themes';
32
+ ```
33
+
34
+ - `base` β€” minireset, generic element styles, keyframes.
35
+ - `themes` β€” registers the `--bulma-*` custom properties (colors, radii, schemes) and
36
+ light/dark setup. Without it, components render unstyled-looking because every color
37
+ resolves to nothing.
38
+ - Exception: `bulma/sass/grid/columns` and `bulma/sass/grid/grid` register their own CSS
39
+ vars and can technically stand alone β€” include base + themes anyway; it is the safe
40
+ default.
41
+
42
+ ## Component β†’ partial mapping
43
+
44
+ **Rule:** stock Bulma components map to `bulma/sass/<category>/<lowercased-name>`; bestax
45
+ extras map to `@allxsmith/bestax-bulma/scss/<category>/<lowercased-name>`. Components that
46
+ are pure stock Bulma (Button, Box, Card, Navbar, Modal, Hero, …) have **no** extras partial β€”
47
+ Bulma's own module is all they need.
48
+
49
+ Stock Bulma examples:
50
+
51
+ ```scss
52
+ @use 'bulma/sass/elements/button'; // Button, Buttons
53
+ @use 'bulma/sass/elements/box'; // Box
54
+ @use 'bulma/sass/elements/notification'; // Notification
55
+ @use 'bulma/sass/elements/title'; // Title, SubTitle
56
+ @use 'bulma/sass/form/input'; // Input
57
+ @use 'bulma/sass/form/select'; // Select
58
+ @use 'bulma/sass/components/card'; // Card
59
+ @use 'bulma/sass/components/modal'; // Modal
60
+ @use 'bulma/sass/components/navbar'; // Navbar
61
+ @use 'bulma/sass/grid/columns'; // Columns, Column
62
+ @use 'bulma/sass/grid/grid'; // Grid, Cell
63
+ @use 'bulma/sass/layout/container'; // Container
64
+ @use 'bulma/sass/layout/section'; // Section
65
+ ```
66
+
67
+ ## Authoritative bestax extras inventory
68
+
69
+ Every extras partial that exists (from the library's `src/scss/**/_index.scss` β€” this list
70
+ is **more complete** than the docs page's Option C example, which omits several):
71
+
72
+ **Components** (`@allxsmith/bestax-bulma/scss/components/<name>`):
73
+ `loading`, `collapse`, `tooltip`, `steps`, `sidebar`, `toast`, `dialog`, `carousel`, `tabs`,
74
+ `reveal`, `avatar`, `avatars`, `badge`
75
+
76
+ **Form** (`@allxsmith/bestax-bulma/scss/form/<name>`):
77
+ `checkbox`, `radio`, `switch`, `slider`, `numberinput`, `rate`, `autocomplete`, `taginput`,
78
+ `picker-popover`, `dateinput`, `timeinput`, `datetimeinput`
79
+
80
+ **Elements** (`@allxsmith/bestax-bulma/scss/elements/<name>`): `linkbutton`
81
+
82
+ **Helpers** (`@allxsmith/bestax-bulma/scss/helpers/<name>`): `cursor`, `sizing`
83
+
84
+ Notes:
85
+
86
+ - The extras partial name is the component name lowercased (`Dialog` β†’
87
+ `scss/components/dialog`; `NumberInput` β†’ `scss/form/numberinput`).
88
+ - Extras `Tabs` **extends** stock Bulma tabs (vertical variant) β€” an app using `Tabs` needs
89
+ both `bulma/sass/components/tabs` and `@allxsmith/bestax-bulma/scss/components/tabs`.
90
+ - `DateInput`/`TimeInput`/`DateTimeInput` also need `picker-popover`.
91
+ - Stock-Bulma form controls still need their Bulma module (`bulma/sass/form/…`); the extras
92
+ form partials above style only the bestax-specific behavior.
93
+ - Bulma component modules pull their own internal sub-elements β€” e.g.
94
+ `elements/notification` styles its `delete` close button itself (verified). No extra
95
+ `@use` lines are needed for pieces rendered _inside_ a component you've already included.
96
+
97
+ ## Bulma helper categories
98
+
99
+ Include a helper module **only if the app's helper props (or `className` strings) need it**:
100
+
101
+ ⚠️ The `display` prop (`display="flex"`, `is-flex`, `is-block`, …) lives in **`visibility`**,
102
+ not `flexbox` β€” `flexbox` holds only the alignment props. Verified failure mode: omit
103
+ `visibility` and every `display="flex"` silently renders `block`.
104
+
105
+ ```scss
106
+ @use 'bulma/sass/helpers/spacing'; // m*/p* props
107
+ @use 'bulma/sass/helpers/color'; // color/backgroundColor props, has-text-*/has-background-*
108
+ @use 'bulma/sass/helpers/typography'; // textSize/textAlign/textTransform/textWeight/fontFamily
109
+ @use 'bulma/sass/helpers/visibility'; // display/visibility props incl. display="flex" (is-flex/is-block/is-hidden*)
110
+ @use 'bulma/sass/helpers/flexbox'; // flex* alignment props (justifyContent/alignItems/flexGrow…) β€” NOT display="flex"
111
+ @use 'bulma/sass/helpers/other'; // overlay/interaction/radius/shadow/clearfix/relative…
112
+ ```
113
+
114
+ ## Procedure
115
+
116
+ 1. **Inventory** β€” list every component the app imports from `@allxsmith/bestax-bulma`
117
+ (grep the import statements; remember re-exports through local files).
118
+ 2. **Map** β€” one `@use` line per component via the rule above; add the helper categories the
119
+ app's helper props require; dedupe.
120
+ 3. **Write `src/styles.scss`** β€” the `utilities` config first, then base + themes, then the
121
+ mapped lines.
122
+ 4. **Swap the import** β€” in `src/main.tsx`/`src/main.jsx`, replace the prebuilt CSS import
123
+ (`bestax.css` or `versions/*.css`) with `import './styles.scss';`.
124
+ 5. **Build and measure** β€” raw + gzip, compare against the prebuilt baseline, report the
125
+ delta.
126
+ 6. **Verify visually** β€” open the app; a missing partial shows up as an unstyled component,
127
+ an omitted helper module as ignored spacing/color props. Add the missing `@use` line β€”
128
+ never paper over it with custom CSS.
129
+
130
+ ## Worked example β€” the create-bestax starter app
131
+
132
+ The `npm create bestax` starter renders `Container`, `Section`, `Columns`/`Column`, `Image`,
133
+ `Title`/`SubTitle`, `Box`, `Card`, `Buttons`/`Button`, and `Notification` β€” all stock Bulma,
134
+ no bestax extras. Its helper props are `display`/`justifyContent` (visibility + flexbox),
135
+ `textAlign` (typography), and `textColor` (color); it uses no spacing props. That inventory
136
+ compiles to the following β€” verified pixel-equivalent to the prebuilt `complete` flavor in
137
+ headless Chromium (light and dark), at 453 KB raw / 40 KB gzip vs 813 KB / 83 KB:
138
+
139
+ ```scss
140
+ // src/styles.scss
141
+ @use 'bulma/sass/utilities' with (
142
+ $primary: #1e6b99
143
+ );
144
+
145
+ @use 'bulma/sass/base';
146
+ @use 'bulma/sass/themes';
147
+
148
+ @use 'bulma/sass/elements/box';
149
+ @use 'bulma/sass/elements/button'; // Button + Buttons
150
+ @use 'bulma/sass/elements/image';
151
+ @use 'bulma/sass/elements/notification';
152
+ @use 'bulma/sass/elements/title'; // Title + SubTitle
153
+ @use 'bulma/sass/components/card';
154
+ @use 'bulma/sass/grid/columns';
155
+ @use 'bulma/sass/layout/container';
156
+ @use 'bulma/sass/layout/section';
157
+
158
+ @use 'bulma/sass/helpers/visibility'; // display="flex"
159
+ @use 'bulma/sass/helpers/flexbox'; // justifyContent/flexGrow/flexShrink
160
+ @use 'bulma/sass/helpers/typography'; // textAlign
161
+ @use 'bulma/sass/helpers/color'; // textColor
162
+ ```
163
+
164
+ ```tsx
165
+ // src/main.tsx β€” before
166
+ import '@allxsmith/bestax-bulma/bestax.css';
167
+ // after
168
+ import './styles.scss';
169
+ ```
170
+
171
+ A custom class prefix is `$class-prefix` in the same `with (…)` block as `$primary`, paired
172
+ with `<ConfigProvider classPrefix="my-">` at the app root (the library's own
173
+ `src/scss/versions/*.scss` flavor builds use exactly this mechanism).