bitwrench 2.0.15 → 2.0.17

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.
Files changed (53) hide show
  1. package/README.md +57 -21
  2. package/dist/bitwrench-bccl.cjs.js +3750 -0
  3. package/dist/bitwrench-bccl.cjs.min.js +40 -0
  4. package/dist/bitwrench-bccl.esm.js +3745 -0
  5. package/dist/bitwrench-bccl.esm.min.js +40 -0
  6. package/dist/bitwrench-bccl.umd.js +3756 -0
  7. package/dist/bitwrench-bccl.umd.min.js +40 -0
  8. package/dist/bitwrench-code-edit.cjs.js +57 -7
  9. package/dist/bitwrench-code-edit.cjs.min.js +9 -2
  10. package/dist/bitwrench-code-edit.es5.js +74 -11
  11. package/dist/bitwrench-code-edit.es5.min.js +9 -2
  12. package/dist/bitwrench-code-edit.esm.js +57 -7
  13. package/dist/bitwrench-code-edit.esm.min.js +9 -2
  14. package/dist/bitwrench-code-edit.umd.js +57 -7
  15. package/dist/bitwrench-code-edit.umd.min.js +9 -2
  16. package/dist/bitwrench-lean.cjs.js +905 -157
  17. package/dist/bitwrench-lean.cjs.min.js +7 -7
  18. package/dist/bitwrench-lean.es5.js +931 -157
  19. package/dist/bitwrench-lean.es5.min.js +5 -5
  20. package/dist/bitwrench-lean.esm.js +904 -157
  21. package/dist/bitwrench-lean.esm.min.js +7 -7
  22. package/dist/bitwrench-lean.umd.js +905 -157
  23. package/dist/bitwrench-lean.umd.min.js +7 -7
  24. package/dist/bitwrench.cjs.js +910 -158
  25. package/dist/bitwrench.cjs.min.js +8 -8
  26. package/dist/bitwrench.css +60 -17
  27. package/dist/bitwrench.es5.js +939 -158
  28. package/dist/bitwrench.es5.min.js +6 -6
  29. package/dist/bitwrench.esm.js +909 -158
  30. package/dist/bitwrench.esm.min.js +8 -8
  31. package/dist/bitwrench.min.css +1 -1
  32. package/dist/bitwrench.umd.js +910 -158
  33. package/dist/bitwrench.umd.min.js +8 -8
  34. package/dist/builds.json +168 -80
  35. package/dist/bwserve.cjs.js +660 -0
  36. package/dist/bwserve.esm.js +652 -0
  37. package/dist/sri.json +36 -28
  38. package/package.json +20 -3
  39. package/readme.html +62 -23
  40. package/src/bitwrench-bccl-entry.js +72 -0
  41. package/src/bitwrench-bccl.js +5 -1
  42. package/src/bitwrench-code-edit.js +56 -6
  43. package/src/bitwrench-color-utils.js +5 -6
  44. package/src/bitwrench-styles.js +20 -8
  45. package/src/bitwrench.js +876 -140
  46. package/src/bwserve/client.js +182 -0
  47. package/src/bwserve/index.js +363 -0
  48. package/src/bwserve/shell.js +106 -0
  49. package/src/cli/index.js +36 -15
  50. package/src/cli/layout-default.js +47 -32
  51. package/src/cli/serve.js +325 -0
  52. package/src/version.js +3 -3
  53. /package/bin/{bitwrench.js → bwcli.js} +0 -0
package/dist/sri.json CHANGED
@@ -1,33 +1,41 @@
1
1
  {
2
- "version": "2.0.15",
2
+ "version": "2.0.17",
3
3
  "algorithm": "sha384",
4
- "generated": "2026-03-10",
4
+ "generated": "2026-03-13",
5
5
  "files": {
6
- "bitwrench-code-edit.cjs.js": "sha384-/bNOqn95bkCYJCgvldLJRxaxrEMiOL9piW7D31QjgOnE0Bj8ke48M7R3K/ZHi5vz",
7
- "bitwrench-code-edit.cjs.min.js": "sha384-ps1tCwgt+YjAGinSLyGKY5ZsnV7KutVYKxVWYruS3gP3TbyafQJySwih5Fn80ZFK",
8
- "bitwrench-code-edit.es5.js": "sha384-vGhHBjXz591gQgE+pckuNJWsnPqisOchcSe04rudf6hYVBAwoNhRSemylUapsDv7",
9
- "bitwrench-code-edit.es5.min.js": "sha384-g6K2l3no0codjtoRbKBLqn2eYGqYbRitFqxpw7aO2u8Nbx++4EOmAG/XqcENBTAK",
10
- "bitwrench-code-edit.esm.js": "sha384-xEJF0fnbv5RPG+mh6uPb6tKmV1icZ1ZV46+LP+JzNNDYy43AOc32UdmRtbPM/CnX",
11
- "bitwrench-code-edit.esm.min.js": "sha384-kxjp+unxOUGXueWiOYK7r9snqgLE2d1wpjybHrEILes1+bS3rnWVhg2OVFScnzY/",
12
- "bitwrench-code-edit.umd.js": "sha384-B5lapHaMiyQ0mnd41EYO8N2F9vWyw+G1pocd0s2IxztRCoqLxQ9yMfyFJqdUB7s1",
13
- "bitwrench-code-edit.umd.min.js": "sha384-IHAz1etjFsiS5iYQUamcrysiuhJ64CrgwaXcTyyoxOAiXnDpCcGW/q1C/+/RddbX",
14
- "bitwrench-lean.cjs.js": "sha384-qlWuZnAZS14Zp/FKrTGtfH8AwI4A9mrXNh3cq8kBDkUlo4ZI3hQEiCRQwfQpn0ic",
15
- "bitwrench-lean.cjs.min.js": "sha384-pVY2BB/U0dn5JZM/r47Hv61bgiSryf9ZIePN+hQkhkFAkFJrsDqIT+HjQB3D7WRw",
16
- "bitwrench-lean.es5.js": "sha384-Xb+Lra8oUB0jRRTwFyfVppS/lFOiHthdu4eYWYbRqWkJ/PbByyhEoQV5bHB8EvPI",
17
- "bitwrench-lean.es5.min.js": "sha384-z4Qf0p+RbLyXVhft6XrqDFapRaKh4fh6CrJSwdRruVlY1oHp+sMpuEtoyhuR5nGA",
18
- "bitwrench-lean.esm.js": "sha384-JtZWDCq1UZGqvFUUtuMFeSAruMdCSK7xZq3XOjZv8AE03IF8+nRjmlyfJCZDGVNV",
19
- "bitwrench-lean.esm.min.js": "sha384-8uBjskc3WvHSTbe8ZGOUOCc1UJH85iBRcdDqnsjBC6EI1Skzu5fWR/i9hgpA3psD",
20
- "bitwrench-lean.umd.js": "sha384-iV0Un/IlMdxbT3Mfi6fVTXkaVP2NDVLa2u3K5dQtKXBEhVYfPMv+jv9lultT+kSh",
21
- "bitwrench-lean.umd.min.js": "sha384-mhHV7Zd3oamSfYyU/mX5OD3xw3gqCiUvYmm2IM9/T4GrrD0Aj9Bvif9Aae/eLT36",
22
- "bitwrench.cjs.js": "sha384-Gl3hM4aTs/afOUDefxOfyriRruD69mJsC7pChob/Esg3qdV3+RoY90wLsThEJN4n",
23
- "bitwrench.cjs.min.js": "sha384-/mPUPWrJE0/9176PeMBw0hZGBFtQ0LNzRk8F9EK3mkVBQFQUpRmOrxy7q7KDEP4C",
24
- "bitwrench.css": "sha384-G7kC+3If3rNHBh23G8LHZa3NvPsf+s5fNGaXAZkqtg8Nas0WmhOdWHTbqTEijKQM",
25
- "bitwrench.es5.js": "sha384-Q8ctFLQAXaBuM5JXFwCUQelQUKE21k0Gc5i+2nsM3Ym329Fh930RYk4b5ateACSp",
26
- "bitwrench.es5.min.js": "sha384-pb/2mUSIQW5L3jH21snKnd3Hp+VD8CmxKgFVr2qgZQbruDeY1PLCp/eLU70C+A1T",
27
- "bitwrench.esm.js": "sha384-HAlG1Fs6lhPxVP5zn0rkgyf2GqvLCjos71Va0lTF1HvSX6eWOs8LWXQ1ku+J7/9I",
28
- "bitwrench.esm.min.js": "sha384-GWl9IOVhYVEa51cA+COtFM9wFkfD3fQqO3DYTVGl8QJOP3dbuuDLWtP0aFwZBveF",
29
- "bitwrench.min.css": "sha384-okjJZx1EoXcKaEospKzJk0MxyQprKaGYaqBYGWEHkknFyOWhfAsf0gYCw7hU7mAs",
30
- "bitwrench.umd.js": "sha384-MvEk3PxsoQTdUunY7vEMh+ysBA7tIErjU/vCj5MF3INyxTWXbqiwYwud+8erXEQ9",
31
- "bitwrench.umd.min.js": "sha384-aXIq51Hw9LQDyIeq4mJEbvUkPf5E8tfkj/ffyQ+fOdE569kRu0IBglpMIiE2Cpt9"
6
+ "bitwrench-bccl.cjs.js": "sha384-JtHrGKdL2R+Np/4hJCUnnKa+gVhO1HMojkcUDQsnX4iyyf/CVq4SaTuCWQyz1q1q",
7
+ "bitwrench-bccl.cjs.min.js": "sha384-gKYoqvlm7yhCh7//O/fkRZtdC6X2j7+cTrl85bAj6fNfB8DnZqvhqnXGPdKSthF7",
8
+ "bitwrench-bccl.esm.js": "sha384-go+h+i6cxCy1JnOTEQ3ukm9RCf5KwBInhSnofh++ktdhKAfqoWmB766VseRGCtXY",
9
+ "bitwrench-bccl.esm.min.js": "sha384-zt2eb/zS5QAotiywhp3nZXmxwBRR4rb4R8A8mKo0IpZIXL3tWYTwSrr87k+aUOa5",
10
+ "bitwrench-bccl.umd.js": "sha384-85C9Wud5azObw2tgX7KVS0zOo/+GhNSYldFZehW5f917xe86WR6ai28Yqb2bV7BG",
11
+ "bitwrench-bccl.umd.min.js": "sha384-MnURAnFgYO7gpv2AD/nSra7oCppx/LaeWr7Zhn++o66Grw+tfBcIjmbmTBzR8suQ",
12
+ "bitwrench-code-edit.cjs.js": "sha384-pYMU67JSAuOzmvDIptwgJU9l1ATHRZVIKYIbmJtxJJiwmbTBF023aYxNYuU2kCFh",
13
+ "bitwrench-code-edit.cjs.min.js": "sha384-gyKZwcVfwGq+oJdbhzOrjROdtQUW9GR+m1iU69kh+ybPZ+OzSAH7cOx1Z3Cib0EM",
14
+ "bitwrench-code-edit.es5.js": "sha384-i6eXPifX0VPfeKo4jI1JYD26PQJh2HxtDQblAFeeFC0k5y8jmOgLKtk86UPT14vs",
15
+ "bitwrench-code-edit.es5.min.js": "sha384-I2r5vCUHcQT/UqKdbMqLk5uhc7rqBKhP4qJzoItEHBcuLFdzMbfRrTj5l3lk15QJ",
16
+ "bitwrench-code-edit.esm.js": "sha384-CVdqruuHB4k6wehD26cio10tl8xCcQfdQmdMWlDuYFYF3R2re7ZjTZClz1TAvxlb",
17
+ "bitwrench-code-edit.esm.min.js": "sha384-kKtUe03iCRXxIV1bpLffhl1apf8JJeteXVSdfM2HS9HyKkvf5uiFN96CC2VzFt24",
18
+ "bitwrench-code-edit.umd.js": "sha384-qzPZG4wK/7oBf+uXwbUBNNRA9zuOsxChJXXipoZBg8gt51e/uhmkiD5jVBDsXPNF",
19
+ "bitwrench-code-edit.umd.min.js": "sha384-zEBjo8SgTdGymQQwRYva/iW2iCUjT0Tdtocik63xi00qE88OEFl8kejj5KCrxCNc",
20
+ "bitwrench-lean.cjs.js": "sha384-XP0qyS4rfU2MUK93n0zgpIhOMjyTxEqMtTrErOopcsDRuYIsY0b4zeS/wa+6GEJn",
21
+ "bitwrench-lean.cjs.min.js": "sha384-Aep5GOW8Qu0H5ZDbMXna4ku9QQQgrAAfpJFMBiRHY+XuglwZooFfgSTezhR1eftj",
22
+ "bitwrench-lean.es5.js": "sha384-bkwm+dTlJQ/DyPOz04TVSpDd0UqdCY7B6/y01N/P9pAnTlx/S94mkm8TQfzQW+gy",
23
+ "bitwrench-lean.es5.min.js": "sha384-+JD7oSIx3Gl1wsUNWXeSZqBz1mOLcjpI+ScQR1d0oFyhf62zyyWSl02KhC1vO46m",
24
+ "bitwrench-lean.esm.js": "sha384-5lIJxbMwgIeJnNk9yNMvUf7PnIdt4e6b1QzQD3psRv46xDLDcTFRxXA1rloyAY1i",
25
+ "bitwrench-lean.esm.min.js": "sha384-XLQK7n6rfH6mXKYJFWi0TlwDyE20YyzGtkuFffQRwKCLD7yMn1ZAHxQxwKP1MvuW",
26
+ "bitwrench-lean.umd.js": "sha384-HHotDwMh/Ipq3JcDJzr2anOJcLynPS8XBJkPFsbUOz+Irbwd1LyEYZ7HkUCgmrJu",
27
+ "bitwrench-lean.umd.min.js": "sha384-G18BfqAXGt/2VzZ0oCTxpdZZSh/eriVzz8xlf0MxFrEDfj6NWLWn6Rqp9pHEtyHf",
28
+ "bitwrench.cjs.js": "sha384-TjEj7ETG/CylzHHnyc3dbxjJ9A8CXoaCouPzBpdex/u6wU68YayPG+yXyt+Jcg83",
29
+ "bitwrench.cjs.min.js": "sha384-w1Gl0tTOOSMBqXYVAKMudrFfXJ+nNf5va7q5GEPKMYtxVQQyDpDP4yL9+/uyZtTW",
30
+ "bitwrench.css": "sha384-TLf4tWABJynZ7cb9epG9VhRM1IvuK5k4VD5wHE2esbGXcuKzG6iArqimHPzZDLD2",
31
+ "bitwrench.es5.js": "sha384-FE2hzUIF9en6TGljWhEr1vKvofcNSLQJsjU6XlDiezwG3DgJgDKIafuSDu00NWfK",
32
+ "bitwrench.es5.min.js": "sha384-c3gOIHjeEUGSVtcv6M1N6KmGoWuOUz3H8hGbcIOh90dIZY7Xflx2SLdSaSl5yRWJ",
33
+ "bitwrench.esm.js": "sha384-08iatqu6LAtx8cZsgXkE34sK7FvN99nn+wXNx0YEEMMRuGRRq35uATUNKv7FcO5U",
34
+ "bitwrench.esm.min.js": "sha384-S/DNxHQzWvbbrszBTs9wc78m7NnO6Ml7iw18/V5mki40a7WKfckhLGmsFMKfQw+N",
35
+ "bitwrench.min.css": "sha384-Sl7+BxWfINNnNdN+ZCL1s/p4Hn+5WeJPciWS9svNuzal8h9baX19xGeOJNzradRY",
36
+ "bitwrench.umd.js": "sha384-8nLO+4nHEnvnbslfteLo04OfUqDTZcB/Q5uelctfeIuPU2MXP02BO3iE4Jsz3Bp5",
37
+ "bitwrench.umd.min.js": "sha384-y+l0IvKb1/9dBiradZkR1Alh6o0KtJgrkupdlYVLw/x4By7+tNtJcSu5D7N5u4IE",
38
+ "bwserve.cjs.js": "sha384-ShnkqIcaohORoeDTsw/KEij2kTbtuj6dFtZExUgLJdvgy3hWmHWVpktT9jhUczTg",
39
+ "bwserve.esm.js": "sha384-Je3FPrcpT8TjizTUMW3tzlRgmJxKnLFabVV+eaCfZRnPDx5uJVARuS+TEXbnrWWt"
32
40
  }
33
41
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "bitwrench",
3
- "version": "2.0.15",
3
+ "version": "2.0.17",
4
4
  "description": "A library for javascript UI functions.",
5
5
  "main": "./dist/bitwrench.umd.js",
6
6
  "repository": {
@@ -13,7 +13,7 @@
13
13
  "author": "manu a. chatterjee <deftio@deftio.com> (https://deftio.com/)",
14
14
  "license": "BSD-2-Clause",
15
15
  "bin": {
16
- "bitwrench": "./bin/bitwrench.js"
16
+ "bwcli": "./bin/bwcli.js"
17
17
  },
18
18
  "type": "module",
19
19
  "module": "./dist/bitwrench.esm.js",
@@ -22,6 +22,20 @@
22
22
  "import": "./dist/bitwrench.esm.js",
23
23
  "require": "./dist/bitwrench.cjs.js",
24
24
  "default": "./dist/bitwrench.umd.js"
25
+ },
26
+ "./lean": {
27
+ "import": "./dist/bitwrench-lean.esm.js",
28
+ "require": "./dist/bitwrench-lean.cjs.js",
29
+ "default": "./dist/bitwrench-lean.umd.js"
30
+ },
31
+ "./bccl": {
32
+ "import": "./dist/bitwrench-bccl.esm.js",
33
+ "require": "./dist/bitwrench-bccl.cjs.js",
34
+ "default": "./dist/bitwrench-bccl.umd.js"
35
+ },
36
+ "./bwserve": {
37
+ "import": "./dist/bwserve.esm.js",
38
+ "require": "./dist/bwserve.cjs.js"
25
39
  }
26
40
  },
27
41
  "types": "./dist/bitwrench.d.ts",
@@ -81,7 +95,8 @@
81
95
  "build_1_x": "./tools/update-bw-package.js package.json package.json && ./tools/export-bw-default-css.js bitwrench.css && uglifyjs bitwrench.js -o bitwrench.min.js && uglifyjs bitwrench_ESM.js -o bitwrench_ESM.min.js && ./tools/umd2ModuleHack.js && npm pack",
82
96
  "cleanbuild": "npm run clean && npm run build && npm run build:generated",
83
97
  "oldtest": "./node_modules/mocha/bin/mocha test/bitwrench_test.js --reporter spec",
84
- "test": "c8 --reporter=text mocha ./test/bitwrench_ci.js ./test/bitwrench_test_coverage.js ./test/bitwrench_test_pubsub.js ./test/bitwrench_test_theme.js ./test/bitwrench_test_nodemap.js ./test/bitwrench_test_components.js ./test/bitwrench_test_component_handle.js ./test/bitwrench_test_coverage_gaps.js -r jsdom-global/register",
98
+ "test": "c8 --reporter=text mocha ./test/bitwrench_ci.js ./test/bitwrench_test_coverage.js ./test/bitwrench_test_pubsub.js ./test/bitwrench_test_theme.js ./test/bitwrench_test_nodemap.js ./test/bitwrench_test_components.js ./test/bitwrench_test_component_handle.js ./test/bitwrench_test_coverage_gaps.js ./test/bitwrench_test_bwserve.js ./test/bitwrench_test_code_edit.js ./test/bitwrench_test_html_page.js -r jsdom-global/register",
99
+ "test:bwserve": "mocha ./test/bitwrench_test_bwserve.js -r jsdom-global/register",
85
100
  "test:components": "mocha ./test/bitwrench_test_components.js -r jsdom-global/register",
86
101
  "test:v1": "c8 --reporter=text mocha ./test/bitwrench_test.js -r jsdom-global/",
87
102
  "test:pending": "mocha ./test/bitwrench_test_pending.js -r jsdom-global/",
@@ -96,6 +111,8 @@
96
111
  "generate-sri": "node tools/generate-sri.js",
97
112
  "test:nodemap": "mocha ./test/bitwrench_test_nodemap.js -r jsdom-global/register",
98
113
  "test:cli": "mocha ./test/bitwrench_test_cli.js",
114
+ "test:code-edit": "mocha ./test/bitwrench_test_code_edit.js -r jsdom-global/register",
115
+ "test:html-page": "mocha ./test/bitwrench_test_html_page.js -r jsdom-global/register",
99
116
  "test:e2e": "playwright test",
100
117
  "test:e2e:headed": "playwright test --headed",
101
118
  "test:e2e:debug": "playwright test --debug",
package/readme.html CHANGED
@@ -3,7 +3,7 @@
3
3
  <head>
4
4
  <meta charset="UTF-8">
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
- <meta name="generator" content="bitwrench v2.0.15">
6
+ <meta name="generator" content="bitwrench v2.0.17">
7
7
  <title>bitwrench.js - README</title>
8
8
  <link rel="icon" type="image/x-icon" href="images/favicon.ico">
9
9
  <script src="dist/bitwrench.umd.js"></script>
@@ -96,7 +96,8 @@ const bw = require(&#39;bitwrench&#39;);</code></pre><p>Or include directly in a
96
96
  <li class="quikdown-li"><strong class="quikdown-strong">Built-in reactivity</strong> — <code class="quikdown-code">bw.update()</code> re-renders components when state changes, <code class="quikdown-code">bw.patch()</code> updates individual elements by ID, <code class="quikdown-code">bw.pub()</code>/<code class="quikdown-code">bw.sub()</code> provides decoupled messaging between any part of the application</li>
97
97
  <li class="quikdown-li"><strong class="quikdown-strong">CSS and theme generation</strong> — <code class="quikdown-code">bw.css()</code> generates stylesheets from objects, <code class="quikdown-code">bw.generateTheme()</code> derives a complete visual theme (buttons, alerts, badges, cards, forms, tables, dark mode) from 2-3 seed colors</li>
98
98
  <li class="quikdown-li"><strong class="quikdown-strong">45+ ready-made components</strong> — cards, buttons, sortable tables, form inputs, modals, dropdowns, accordions, tooltips, popovers, toasts, timelines, steppers, file uploads, stat cards — each a single function call that returns a composable object</li>
99
- <li class="quikdown-li"><strong class="quikdown-strong">Static site CLI</strong> — the <code class="quikdown-code">bitwrench</code> command converts Markdown, HTML, and JSON files into styled, self-contained pages with theme support</li>
99
+ <li class="quikdown-li"><strong class="quikdown-strong">Server-driven UI (bwserve)</strong> — push TACO rendering commands from Node.js to the browser over SSE; same protocol works from C (ESP32), Python, Rust, or any language via the <code class="quikdown-code">bwcli serve</code> pipe server</li>
100
+ <li class="quikdown-li"><strong class="quikdown-strong">Static site CLI</strong> — the <code class="quikdown-code">bwcli</code> command converts Markdown, HTML, and JSON files into styled, self-contained pages with theme support</li>
100
101
  <li class="quikdown-li"><strong class="quikdown-strong">Utilities</strong> — color interpolation, random data generation, lorem ipsum, cookies, URL params, file I/O for both browser and Node.js</li>
101
102
  </ul><h2 class="quikdown-h2">Getting Started</h2>
102
103
  <p><pre class="quikdown-pre"><code class="language-html">&lt;!DOCTYPE html&gt;
@@ -123,23 +124,24 @@ const bw = require(&#39;bitwrench&#39;);</code></pre><p>Or include directly in a
123
124
  &lt;/script&gt;
124
125
  &lt;/body&gt;
125
126
  &lt;/html&gt;</code></pre></p><h2 class="quikdown-h2">Adding State</h2>
126
- <p>The <code class="quikdown-code">o</code> key adds state and a render function to any element. When state changes, call <code class="quikdown-code">bw.update()</code> to re-render:</p><pre class="quikdown-pre"><code class="language-javascript">bw.DOM(&#39;#counter&#39;, {
127
- t: &#39;div&#39;,
127
+ <p>Wrap any TACO in <code class="quikdown-code">bw.component()</code> to get a reactive component with <code class="quikdown-code">.get()</code>, <code class="quikdown-code">.set()</code>, and template bindings:</p><pre class="quikdown-pre"><code class="language-javascript">var counter = bw.component({
128
+ t: &#39;div&#39;, c: [
129
+ { t: &#39;span&#39;, c: &#39;Count: ${count}&#39; },
130
+ { t: &#39;button&#39;, c: &#39;+1&#39;, a: {
131
+ onclick: function() { counter.set(&#39;count&#39;, counter.get(&#39;count&#39;) + 1); }
132
+ }}
133
+ ],
128
134
  o: {
129
135
  state: { count: 0 },
130
- render: function(el) {
131
- var s = el._bw_state;
132
- bw.DOM(el, {
133
- t: &#39;div&#39;, c: [
134
- { t: &#39;span&#39;, c: &#39;Count: &#39; + s.count },
135
- { t: &#39;button&#39;, a: {
136
- onclick: function() { s.count++; bw.update(el); }
137
- }, c: &#39;+1&#39; }
138
- ]
139
- });
136
+ methods: {
137
+ reset: function(comp) { comp.set(&#39;count&#39;, 0); }
140
138
  }
141
139
  }
142
- });</code></pre><p>For communication between components, use pub/sub:</p><pre class="quikdown-pre"><code class="language-javascript">bw.sub(&#39;item-added&#39;, function(detail) {
140
+ });
141
+
142
+ bw.DOM(&#39;#app&#39;, counter);
143
+ counter.set(&#39;count&#39;, 42); // DOM updates automatically
144
+ counter.reset(); // methods from o.methods are callable on the handle</code></pre><p>For low-level control, you can also use <code class="quikdown-code">o.render</code> + <code class="quikdown-code">bw.update()</code> directly — see the <a class="quikdown-a" href="docs/state-management.md">State Management guide</a>.</p><p>For communication between components, use pub/sub:</p><pre class="quikdown-pre"><code class="language-javascript">bw.sub(&#39;item-added&#39;, function(detail) {
143
145
  console.log(&#39;New item:&#39;, detail.name);
144
146
  });
145
147
 
@@ -167,6 +169,10 @@ bw.toggleTheme(); // switch between primary and alternate palettes</code></pre>
167
169
  <td class="quikdown-td">Mount an object to a DOM element</td>
168
170
  </tr>
169
171
  <tr class="quikdown-tr">
172
+ <td class="quikdown-td"><code class="quikdown-code">bw.component(taco)</code></td>
173
+ <td class="quikdown-td">Wrap a TACO in a ComponentHandle with <code class="quikdown-code">.get()/.set()</code> reactive API</td>
174
+ </tr>
175
+ <tr class="quikdown-tr">
170
176
  <td class="quikdown-td"><code class="quikdown-code">bw.css(rules)</code></td>
171
177
  <td class="quikdown-td">Generate CSS from a JS object</td>
172
178
  </tr>
@@ -187,6 +193,10 @@ bw.toggleTheme(); // switch between primary and alternate palettes</code></pre>
187
193
  <td class="quikdown-td">Re-render via the element&#39;s <code class="quikdown-code">o.render</code> function</td>
188
194
  </tr>
189
195
  <tr class="quikdown-tr">
196
+ <td class="quikdown-td"><code class="quikdown-code">bw.message(target, action, data)</code></td>
197
+ <td class="quikdown-td">Send a message to a component by tag name</td>
198
+ </tr>
199
+ <tr class="quikdown-tr">
190
200
  <td class="quikdown-td"><code class="quikdown-code">bw.pub(topic, detail)</code></td>
191
201
  <td class="quikdown-td">Publish a message to subscribers</td>
192
202
  </tr>
@@ -194,16 +204,34 @@ bw.toggleTheme(); // switch between primary and alternate palettes</code></pre>
194
204
  <td class="quikdown-td"><code class="quikdown-code">bw.sub(topic, handler)</code></td>
195
205
  <td class="quikdown-td">Subscribe to a topic; returns an unsub function</td>
196
206
  </tr>
207
+ <tr class="quikdown-tr">
208
+ <td class="quikdown-td"><code class="quikdown-code">bw.inspect(target)</code></td>
209
+ <td class="quikdown-td">Debug a component in the browser console</td>
210
+ </tr>
211
+ <tr class="quikdown-tr">
212
+ <td class="quikdown-td"><code class="quikdown-code">bw.clientConnect(url, opts)</code></td>
213
+ <td class="quikdown-td">Connect to a bwserve SSE endpoint</td>
214
+ </tr>
215
+ <tr class="quikdown-tr">
216
+ <td class="quikdown-td"><code class="quikdown-code">bw.clientApply(msg)</code></td>
217
+ <td class="quikdown-td">Apply a bwserve protocol message to the DOM</td>
218
+ </tr>
219
+ <tr class="quikdown-tr">
220
+ <td class="quikdown-td"><code class="quikdown-code">bw.clientParse(str)</code></td>
221
+ <td class="quikdown-td">Parse strict or r-prefix relaxed JSON</td>
222
+ </tr>
197
223
  </tbody>
198
224
  </table><p>See the full <a class="quikdown-a" href="https://deftio.github.io/bitwrench/pages/08-api-reference.html" rel="noopener noreferrer">API Reference</a> for all functions.</p><h2 class="quikdown-h2">CLI</h2>
199
225
  <p>Convert Markdown, HTML, or JSON files to styled standalone pages:</p><pre class="quikdown-pre"><code class="language-bash"># Convert Markdown to a self-contained HTML page
200
- bitwrench README.md -o index.html --standalone
226
+ bwcli README.md -o index.html --standalone
201
227
 
202
228
  # Apply a theme preset
203
- bitwrench doc.md -o doc.html --standalone --theme ocean
229
+ bwcli doc.md -o doc.html --standalone --theme ocean
204
230
 
205
231
  # Custom colors
206
- bitwrench doc.md -o doc.html --standalone --theme &quot;#336699,#cc6633&quot;</code></pre><p>Flags: <code class="quikdown-code">--output/-o</code>, <code class="quikdown-code">--standalone/-s</code>, <code class="quikdown-code">--cdn</code>, <code class="quikdown-code">--theme/-t</code>, <code class="quikdown-code">--css/-c</code>, <code class="quikdown-code">--title</code>, <code class="quikdown-code">--favicon/-f</code>, <code class="quikdown-code">--highlight</code>, <code class="quikdown-code">--verbose/-v</code></p><h2 class="quikdown-h2">Build Formats</h2>
232
+ bwcli doc.md -o doc.html --standalone --theme &quot;#336699,#cc6633&quot;</code></pre><p>Flags: <code class="quikdown-code">--output/-o</code>, <code class="quikdown-code">--standalone/-s</code>, <code class="quikdown-code">--cdn</code>, <code class="quikdown-code">--theme/-t</code>, <code class="quikdown-code">--css/-c</code>, <code class="quikdown-code">--title</code>, <code class="quikdown-code">--favicon/-f</code>, <code class="quikdown-code">--highlight</code>, <code class="quikdown-code">--verbose/-v</code></p><h3 class="quikdown-h3">Pipe Server</h3>
233
+ <p><code class="quikdown-code">bwcli serve</code> turns any language into a bwserve backend — send JSON protocol messages via HTTP POST or stdin, and connected browsers update in real time:</p><pre class="quikdown-pre"><code class="language-bash">bwcli serve --port 8080 --input-port 9000
234
+ curl -X POST http://localhost:9000 -d &#39;{&quot;type&quot;:&quot;patch&quot;,&quot;target&quot;:&quot;temp&quot;,&quot;content&quot;:&quot;23.5 C&quot;}&#39;</code></pre><h2 class="quikdown-h2">Build Formats</h2>
207
235
  <table class="quikdown-table">
208
236
  <thead class="quikdown-thead">
209
237
  <tr class="quikdown-tr">
@@ -235,19 +263,30 @@ bitwrench doc.md -o doc.html --standalone --theme &quot;#336699,#cc6633&quot;</c
235
263
  </tr>
236
264
  </tbody>
237
265
  </table><p>All formats include source maps. A separate CSS file (<code class="quikdown-code">bitwrench.css</code>) is also available for use without JavaScript.</p><h2 class="quikdown-h2">Documentation</h2>
238
- <ul class="quikdown-ul">
239
- <li class="quikdown-li"><a class="quikdown-a" href="https://deftio.github.io/bitwrench/pages/" rel="noopener noreferrer">Interactive docs and demos</a> — full tutorial site with live examples</li>
266
+ <strong class="quikdown-strong">Guides</strong> (in <code class="quikdown-code">docs/</code>):</p><ul class="quikdown-ul">
267
+ <li class="quikdown-li"><a class="quikdown-a" href="docs/taco-format.md">TACO Format</a> — the <code class="quikdown-code">{t, a, c, o}</code> object format</li>
268
+ <li class="quikdown-li"><a class="quikdown-a" href="docs/state-management.md">State Management</a> — three-level component model, ComponentHandle, reactive state</li>
269
+ <li class="quikdown-li"><a class="quikdown-a" href="docs/component-library.md">Component Library</a> — all 50+ <code class="quikdown-code">make*()</code> functions with signatures and examples</li>
270
+ <li class="quikdown-li"><a class="quikdown-a" href="docs/theming.md">Theming</a> — palette-driven theme generation, presets, design tokens</li>
271
+ <li class="quikdown-li"><a class="quikdown-a" href="docs/cli.md">CLI</a> — the <code class="quikdown-code">bwcli</code> command for file conversion and pipe server</li>
272
+ <li class="quikdown-li"><a class="quikdown-a" href="docs/bwserve.md">bwserve</a> — server-driven UI protocol (SSE, actions, embedded devices)</li>
273
+ <li class="quikdown-li"><a class="quikdown-a" href="docs/llm-bitwrench-guide.md">LLM Guide</a> — compact single-file reference for AI-assisted development</li>
274
+ </ul><p><strong class="quikdown-strong">Tutorials:</strong></p><ul class="quikdown-ul">
275
+ <li class="quikdown-li"><a class="quikdown-a" href="docs/tutorial-website.md">Build a Website</a> — multi-section landing page from TACO objects</li>
276
+ <li class="quikdown-li"><a class="quikdown-a" href="docs/tutorial-bwserve.md">bwserve Dashboard</a> — Streamlit-style server-push dashboard</li>
277
+ <li class="quikdown-li"><a class="quikdown-a" href="docs/tutorial-embedded.md">ESP32 IoT Dashboard</a> — embedded sensor dashboard with C macros</li>
278
+ </ul><p><strong class="quikdown-strong">Interactive demos</strong> (live site):</p><ul class="quikdown-ul">
240
279
  <li class="quikdown-li"><a class="quikdown-a" href="https://deftio.github.io/bitwrench/pages/00-quick-start.html" rel="noopener noreferrer">Quick Start</a> — first steps with <code class="quikdown-code">bw.DOM()</code></li>
241
280
  <li class="quikdown-li"><a class="quikdown-a" href="https://deftio.github.io/bitwrench/pages/01-components.html" rel="noopener noreferrer">Components</a> — buttons, cards, alerts, badges, navbars</li>
242
281
  <li class="quikdown-li"><a class="quikdown-a" href="https://deftio.github.io/bitwrench/pages/03-styling.html" rel="noopener noreferrer">Styling &amp; Theming</a> — CSS generation and theming strategies</li>
243
- <li class="quikdown-li"><a class="quikdown-a" href="https://deftio.github.io/bitwrench/pages/05-state.html" rel="noopener noreferrer">State &amp; Interactivity</a> — <code class="quikdown-code">bw.patch()</code>, <code class="quikdown-code">bw.update()</code>, pub/sub</li>
282
+ <li class="quikdown-li"><a class="quikdown-a" href="https://deftio.github.io/bitwrench/pages/05-state.html" rel="noopener noreferrer">State &amp; Interactivity</a> — state patterns and ComponentHandle</li>
244
283
  <li class="quikdown-li"><a class="quikdown-a" href="https://deftio.github.io/bitwrench/pages/06-tic-tac-toe-tutorial.html" rel="noopener noreferrer">Tic Tac Toe Tutorial</a> — step-by-step game with state management</li>
245
284
  <li class="quikdown-li"><a class="quikdown-a" href="https://deftio.github.io/bitwrench/pages/07-framework-comparison.html" rel="noopener noreferrer">Framework Comparison</a> — bitwrench vs React, Vue, Svelte</li>
246
- <li class="quikdown-li"><a class="quikdown-a" href="https://deftio.github.io/bitwrench/pages/10-themes.html" rel="noopener noreferrer">Themes</a> — interactive theme generator with presets, dark mode, and CSS export</li>
285
+ <li class="quikdown-li"><a class="quikdown-a" href="https://deftio.github.io/bitwrench/pages/10-themes.html" rel="noopener noreferrer">Themes</a> — interactive theme generator with presets and CSS export</li>
247
286
  </ul><h2 class="quikdown-h2">Development</h2>
248
287
  <p><pre class="quikdown-pre"><code class="language-bash">npm install # install dev dependencies
249
288
  npm run build # build all dist formats (UMD, ESM, CJS, ES5)
250
- npm test # run unit tests (558 tests)
289
+ npm test # run unit tests (1000+ tests)
251
290
  npm run test:cli # run CLI tests (49 tests)
252
291
  npm run test:e2e # run Playwright browser tests
253
292
  npm run lint # run ESLint
@@ -0,0 +1,72 @@
1
+ /**
2
+ * bitwrench-bccl-entry.js — Standalone entry point for BCCL component library.
3
+ *
4
+ * Use this alongside bitwrench-lean when you want the core library and
5
+ * BCCL components as separate files. The UMD build auto-registers all
6
+ * make*() functions onto the global `bw` object if present.
7
+ *
8
+ * Usage (browser):
9
+ * <script src="bitwrench-lean.umd.min.js"></script>
10
+ * <script src="bitwrench-bccl.umd.min.js"></script>
11
+ *
12
+ * Usage (ESM):
13
+ * import bw from 'bitwrench/lean';
14
+ * import { registerBCCL } from 'bitwrench/bccl';
15
+ * registerBCCL(bw);
16
+ *
17
+ * @module bitwrench-bccl
18
+ * @license BSD-2-Clause
19
+ */
20
+
21
+ import * as components from './bitwrench-bccl.js';
22
+
23
+ /**
24
+ * Register all BCCL components onto a bitwrench instance.
25
+ * Called automatically in UMD builds when `bw` is a global.
26
+ *
27
+ * @param {Object} bw - The bitwrench instance to register on
28
+ */
29
+ export function registerBCCL(bw) {
30
+ if (!bw) return;
31
+
32
+ // Register all make* functions
33
+ Object.entries(components).forEach(function(entry) {
34
+ var name = entry[0], fn = entry[1];
35
+ if (name.indexOf('make') === 0) {
36
+ bw[name] = fn;
37
+ }
38
+ });
39
+
40
+ // Factory dispatch: bw.make('card', props) → bw.makeCard(props)
41
+ bw.make = components.make;
42
+
43
+ // Component registry
44
+ bw.BCCL = components.BCCL;
45
+
46
+ // Variant class helper
47
+ bw.variantClass = components.variantClass;
48
+
49
+ // Create functions that return handles
50
+ if (typeof bw.renderComponent === 'function') {
51
+ Object.entries(components).forEach(function(entry) {
52
+ var name = entry[0], fn = entry[1];
53
+ if (name.indexOf('make') === 0) {
54
+ var createName = 'create' + name.substring(4);
55
+ bw[createName] = function(props) {
56
+ var taco = fn(props);
57
+ return bw.renderComponent(taco);
58
+ };
59
+ }
60
+ });
61
+ }
62
+ }
63
+
64
+ // Re-export all components for direct import
65
+ export { BCCL, make, variantClass } from './bitwrench-bccl.js';
66
+
67
+ // UMD auto-registration: if `bw` exists as a global, register automatically
68
+ if (typeof window !== 'undefined' && typeof window.bw !== 'undefined') {
69
+ registerBCCL(window.bw);
70
+ } else if (typeof globalThis !== 'undefined' && typeof globalThis.bw !== 'undefined') {
71
+ registerBCCL(globalThis.bw);
72
+ }
@@ -3610,5 +3610,9 @@ export var BCCL = {
3610
3610
  export function make(type, props) {
3611
3611
  var def = BCCL[type];
3612
3612
  if (!def) throw new Error('bw.make: unknown component type "' + type + '". Available: ' + Object.keys(BCCL).join(', '));
3613
- return def.make(props || {});
3613
+ var taco = def.make(props || {});
3614
+ if (taco && typeof taco === 'object') {
3615
+ taco._bwFactory = { type: type, props: props || {} };
3616
+ }
3617
+ return taco;
3614
3618
  }
@@ -4,6 +4,13 @@
4
4
  * Provides bw.highlight() for tokenizing JS/CSS/HTML into TACO spans,
5
5
  * and bw.codeEditor() for a live editable code block with syntax coloring.
6
6
  *
7
+ * Theme integration: The editor chrome (background, text color, font) reads
8
+ * from CSS custom properties --bw_code_bg, --bw_code_text, --bw_font_mono,
9
+ * falling back to built-in dark values when no theme is active. Syntax
10
+ * highlighting colors are intentionally fixed (they are a code color scheme,
11
+ * not brand colors). The bw_ce_light class is still supported for manual
12
+ * light-mode override.
13
+ *
7
14
  * Can be loaded standalone (browser script tag after bitwrench.umd.js),
8
15
  * or imported as an ES module / CJS module.
9
16
  *
@@ -14,9 +21,9 @@
14
21
  // -- CSS (injected once) ----------------------------------------------
15
22
  var _cssInjected = false;
16
23
  var CSS_TEXT =
17
- '.bw_ce{background:#1e293b;border-radius:6px;border:1px solid rgba(255,255,255,0.08);overflow:auto}' +
24
+ '.bw_ce{background:var(--bw_code_bg,#1e293b);border-radius:6px;border:1px solid rgba(255,255,255,0.08);overflow:auto}' +
18
25
  '.bw_ce pre{margin:0;padding:0}' +
19
- '.bw_ce code{font-family:"SF Mono",Monaco,"Cascadia Code",Consolas,monospace;font-size:0.875rem;line-height:1.6;color:#e2e8f0;outline:none;white-space:pre-wrap;display:block;padding:0.75rem 1rem}' +
26
+ '.bw_ce code{font-family:var(--bw_font_mono,"SF Mono",Monaco,"Cascadia Code",Consolas,monospace);font-size:0.875rem;line-height:1.6;color:var(--bw_code_text,#e2e8f0);outline:none;white-space:pre-wrap;display:block;padding:0.75rem 1rem}' +
20
27
  '.bw_ce code:empty::before{content:"\\200b"}' +
21
28
  '.bw_ce .bw_ce_keyword{color:#c792ea}' +
22
29
  '.bw_ce .bw_ce_string{color:#c3e88d}' +
@@ -54,7 +61,12 @@ var CSS_TEXT =
54
61
  '.bw_ce_light.bw_ce .bw_ce_css_value{color:#ea580c}' +
55
62
  '.bw_ce_light.bw_ce .bw_ce_at_rule{color:#7c3aed}' +
56
63
  '.bw_ce_light.bw_ce .bw_ce_color{color:#ea580c}' +
57
- '.bw_ce_light.bw_ce .bw_ce_template_interp{color:#0891b2}';
64
+ '.bw_ce_light.bw_ce .bw_ce_template_interp{color:#0891b2}' +
65
+ // Line number gutter (opt-in via lineNumbers option)
66
+ '.bw_ce_wrap{display:flex;flex-direction:row}' +
67
+ '.bw_ce_gutter{flex:0 0 auto;padding:0.75rem 0;text-align:right;user-select:none;-webkit-user-select:none;color:#546e7a;font-family:var(--bw_font_mono,"SF Mono",Monaco,"Cascadia Code",Consolas,monospace);font-size:0.875rem;line-height:1.6;border-right:1px solid rgba(255,255,255,0.08);overflow:hidden}' +
68
+ '.bw_ce_gutter span{display:block;padding:0 0.5rem 0 0.75rem}' +
69
+ '.bw_ce_light .bw_ce_gutter{color:#9ca3af;border-right-color:#d8d8d8}';
58
70
 
59
71
  function ensureCSS(bw) {
60
72
  if (_cssInjected) return;
@@ -537,6 +549,7 @@ function codeEditor(opts) {
537
549
  var lang = opts.lang || 'js';
538
550
  var height = opts.height || '180px';
539
551
  var readOnly = !!opts.readOnly;
552
+ var showLineNumbers = !!opts.lineNumbers;
540
553
  var className = 'bw_ce' + (opts.className ? ' ' + opts.className : '');
541
554
 
542
555
  var highlighted = highlight(code, lang);
@@ -549,12 +562,26 @@ function codeEditor(opts) {
549
562
  codeAttrs.contenteditable = 'true';
550
563
  }
551
564
 
565
+ // Build line number gutter TACO if requested
566
+ var gutterTaco = null;
567
+ if (showLineNumbers) {
568
+ var lineCount = (code.match(/\n/g) || []).length + 1;
569
+ var gutterLines = [];
570
+ for (var li = 1; li <= lineCount; li++) {
571
+ gutterLines.push({ t: 'span', c: String(li) });
572
+ }
573
+ gutterTaco = { t: 'div', a: { class: 'bw_ce_gutter' }, c: gutterLines };
574
+ }
575
+
576
+ var preBlock = { t: 'pre', a: { style: 'flex:1;min-width:0;margin:0' }, c: { t: 'code', a: codeAttrs, c: highlighted } };
577
+ var innerContent = showLineNumbers
578
+ ? { t: 'div', a: { class: 'bw_ce_wrap' }, c: [gutterTaco, preBlock] }
579
+ : preBlock;
580
+
552
581
  return {
553
582
  t: 'div',
554
583
  a: { class: className, style: 'max-height:' + height + ';overflow:auto' },
555
- c: [
556
- { t: 'pre', c: { t: 'code', a: codeAttrs, c: highlighted } }
557
- ],
584
+ c: [innerContent],
558
585
  o: {
559
586
  mounted: function(el) {
560
587
  var codeEl = el.querySelector('.bw_ce_code');
@@ -562,21 +589,43 @@ function codeEditor(opts) {
562
589
 
563
590
  var currentCode = code;
564
591
  var debounceTimer = null;
592
+ var gutterEl = showLineNumbers ? el.querySelector('.bw_ce_gutter') : null;
565
593
 
566
594
  // Resolve bw from global or import context
567
595
  var bw = (typeof window !== 'undefined' && window.bw) || {};
568
596
 
569
597
  function getValue() { return codeEl.textContent || ''; }
570
598
 
599
+ function updateGutter(text) {
600
+ if (!gutterEl) return;
601
+ var count = (text.match(/\n/g) || []).length + 1;
602
+ var html = '';
603
+ for (var i = 1; i <= count; i++) html += '<span>' + i + '</span>';
604
+ gutterEl.innerHTML = html;
605
+ }
606
+
571
607
  function setValue(newCode) {
572
608
  currentCode = newCode;
573
609
  var tacos = highlight(newCode, lang);
574
610
  if (bw.html) codeEl.innerHTML = bw.html({ t: 'span', c: tacos });
611
+ updateGutter(newCode);
575
612
  }
576
613
 
577
614
  // Expose API on the element
578
615
  el._bwCodeEdit = { getValue: getValue, setValue: setValue };
579
616
 
617
+ // Scroll sync: keep gutter aligned with code
618
+ if (gutterEl) {
619
+ var scrollParent = codeEl.closest('.bw_ce') || el;
620
+ scrollParent.addEventListener('scroll', function() {
621
+ gutterEl.style.transform = 'translateY(' + (-scrollParent.scrollTop) + 'px)';
622
+ });
623
+ // If the outer .bw_ce has overflow, sync from there
624
+ el.addEventListener('scroll', function() {
625
+ gutterEl.style.transform = 'translateY(' + (-el.scrollTop) + 'px)';
626
+ });
627
+ }
628
+
580
629
  if (readOnly) return;
581
630
 
582
631
  function rehighlight() {
@@ -587,6 +636,7 @@ function codeEditor(opts) {
587
636
  var tacos = highlight(newCode, lang);
588
637
  if (bw.html) codeEl.innerHTML = bw.html({ t: 'span', c: tacos });
589
638
  setCaretOffset(codeEl, offset);
639
+ updateGutter(newCode);
590
640
  if (opts.onChange) opts.onChange(newCode);
591
641
  }
592
642
 
@@ -413,12 +413,11 @@ export function derivePalette(config) {
413
413
  var lightBase = config.light || hslToHex([h, 8, 97]);
414
414
  var darkBase = config.dark || hslToHex([h, 10, 13]);
415
415
 
416
- // Background & surface tokens — default to light (white/near-white).
417
- // Dark backgrounds require explicit config.background / config.surface.
418
- // Primary/secondary colors are accents, not page backgrounds, so
419
- // isLightPalette should NOT drive bg/surface defaults.
420
- var bgBase = config.background || '#ffffff';
421
- var surfBase = config.surface || '#f8f9fa';
416
+ // Background & surface tokens — tinted with primary hue for theme personality.
417
+ // Very subtle: bg at L=98/S=6, surface at L=96/S=8.
418
+ // User can override with config.background / config.surface.
419
+ var bgBase = config.background || hslToHex([h, 6, 98]);
420
+ var surfBase = config.surface || hslToHex([h, 8, 96]);
422
421
 
423
422
  var palette = {
424
423
  primary: deriveShades(config.primary),
@@ -1119,7 +1119,7 @@ var structuralRules = {
1119
1119
  '@media (min-width: 992px)': { '.bw_container': { 'max-width': '960px' } },
1120
1120
  '@media (min-width: 1200px)': { '.bw_container': { 'max-width': '1140px' } },
1121
1121
  '.bw_container_fluid': {
1122
- 'width': '100%', 'padding-right': '15px', 'padding-left': '15px',
1122
+ 'width': '100%', 'padding-right': '0.75rem', 'padding-left': '0.75rem',
1123
1123
  'margin-right': 'auto', 'margin-left': 'auto'
1124
1124
  },
1125
1125
  '.bw_row': {
@@ -1280,7 +1280,8 @@ var structuralRules = {
1280
1280
  '.bw_badge': {
1281
1281
  'display': 'inline-block', 'font-size': '0.875rem',
1282
1282
  'font-weight': '600', 'line-height': '1.3', 'text-align': 'center',
1283
- 'white-space': 'nowrap', 'vertical-align': 'baseline'
1283
+ 'white-space': 'nowrap', 'vertical-align': 'baseline',
1284
+ 'padding': '0.35rem 0.65rem', 'border-radius': '0.25rem'
1284
1285
  },
1285
1286
  '.bw_badge:empty': { 'display': 'none' },
1286
1287
  '.bw_badge_sm': { 'font-size': '0.75rem', 'padding': '0.25rem 0.5rem' },
@@ -1465,7 +1466,7 @@ var structuralRules = {
1465
1466
  // ---- Code demo ----
1466
1467
  codeDemo: {
1467
1468
  '.bw_code_demo': { 'margin-bottom': '2rem' },
1468
- '.bw_code_pre': { 'margin': '0', 'border': 'none', 'overflow-x': 'auto' },
1469
+ '.bw_code_pre': { 'margin': '0', 'border': 'none', 'overflow-x': 'auto', 'max-width': '100%' },
1469
1470
  '.bw_code_block': {
1470
1471
  'display': 'block', 'padding': '1.25rem',
1471
1472
  'font-family': '"SF Mono", Monaco, "Cascadia Code", "Roboto Mono", Consolas, "Courier New", monospace',
@@ -1562,7 +1563,7 @@ var structuralRules = {
1562
1563
  },
1563
1564
  '.bw_modal.bw_modal_show': { 'opacity': '1', 'visibility': 'visible', 'pointer-events': 'auto' },
1564
1565
  '.bw_modal_dialog': {
1565
- 'position': 'relative', 'width': '100%', 'max-width': '500px', 'margin': '1.75rem auto',
1566
+ 'position': 'relative', 'width': 'calc(100% - 1rem)', 'max-width': '500px', 'margin': '1.75rem auto',
1566
1567
  'pointer-events': 'none'
1567
1568
  },
1568
1569
  '.bw_modal.bw_modal_show .bw_modal_dialog': { 'transform': 'translateY(0)' },
@@ -1592,7 +1593,7 @@ var structuralRules = {
1592
1593
  '.bw_toast_container.bw_toast_top_center': { 'top': '0', 'left': '50%', 'transform': 'translateX(-50%)' },
1593
1594
  '.bw_toast_container.bw_toast_bottom_center': { 'bottom': '0', 'left': '50%', 'transform': 'translateX(-50%)' },
1594
1595
  '.bw_toast': {
1595
- 'pointer-events': 'auto', 'width': '350px', 'max-width': '100%', 'background-clip': 'padding-box',
1596
+ 'pointer-events': 'auto', 'width': '350px', 'max-width': 'calc(100vw - 2rem)', 'background-clip': 'padding-box',
1596
1597
  'opacity': '0'
1597
1598
  },
1598
1599
  '.bw_toast.bw_toast_show': { 'opacity': '1', 'transform': 'translateY(0)' },
@@ -1678,7 +1679,7 @@ var structuralRules = {
1678
1679
  '.bw_tooltip_wrapper': { 'position': 'relative', 'display': 'inline-block' },
1679
1680
  '.bw_tooltip': {
1680
1681
  'position': 'absolute', 'z-index': '999',
1681
- 'font-size': '0.875rem', 'white-space': 'nowrap', 'pointer-events': 'none',
1682
+ 'font-size': '0.875rem', 'white-space': 'nowrap', 'max-width': 'min(300px, calc(100vw - 1rem))', 'pointer-events': 'none',
1682
1683
  'opacity': '0', 'visibility': 'hidden'
1683
1684
  },
1684
1685
  '.bw_tooltip.bw_tooltip_show': { 'opacity': '1', 'visibility': 'visible' },
@@ -1698,7 +1699,7 @@ var structuralRules = {
1698
1699
  '.bw_popover_trigger': { 'cursor': 'pointer' },
1699
1700
  '.bw_popover': {
1700
1701
  'position': 'absolute', 'z-index': '1000',
1701
- 'min-width': '200px', 'max-width': '320px',
1702
+ 'min-width': '200px', 'max-width': 'min(320px, calc(100vw - 2rem))',
1702
1703
  'pointer-events': 'none', 'opacity': '0', 'visibility': 'hidden'
1703
1704
  },
1704
1705
  '.bw_popover.bw_popover_show': { 'opacity': '1', 'visibility': 'visible', 'pointer-events': 'auto' },
@@ -1881,7 +1882,18 @@ var structuralRules = {
1881
1882
  '.bw_hero, .bw_hero': { 'padding': '2rem 1rem' },
1882
1883
  '.bw_cta_actions, .bw_cta-actions': { 'flex-direction': 'column' },
1883
1884
  '.bw_hstack, .bw_hstack': { 'flex-direction': 'column' },
1884
- '.bw_feature_grid, .bw_feature-grid': { 'grid-template-columns': '1fr' }
1885
+ '.bw_feature_grid, .bw_feature-grid': { 'grid-template-columns': '1fr' },
1886
+ '.bw_modal_dialog': { 'margin': '0.5rem auto' },
1887
+ '.bw_modal_lg': { 'max-width': 'calc(100% - 1rem)' },
1888
+ '.bw_modal_xl': { 'max-width': 'calc(100% - 1rem)' },
1889
+ '.bw_navbar': { 'padding': '0.5rem 0.75rem' },
1890
+ '.bw_navbar_brand': { 'margin-right': '0.5rem', 'font-size': '1rem' },
1891
+ '.bw_navbar_nav': { 'flex-wrap': 'wrap' },
1892
+ '.bw_tooltip': { 'white-space': 'normal' },
1893
+ '.bw_table': { 'display': 'block', 'overflow-x': 'auto', '-webkit-overflow-scrolling': 'touch' },
1894
+ '.bw_col, .bw_col_1, .bw_col_2, .bw_col_3, .bw_col_4, .bw_col_5, .bw_col_6, .bw_col_7, .bw_col_8, .bw_col_9, .bw_col_10, .bw_col_11, .bw_col_12': { 'flex': '0 0 100%', 'max-width': '100%' },
1895
+ '.bw_container': { 'padding-right': '0.5rem', 'padding-left': '0.5rem' },
1896
+ '.bw_container_fluid': { 'padding-right': '0.5rem', 'padding-left': '0.5rem' }
1885
1897
  }
1886
1898
  }
1887
1899
  };