mevebu 1.2.0 → 1.4.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.
Files changed (167) hide show
  1. package/mevebu/app/mevebu.js +260 -208
  2. package/mevebu/app/tailwind.css +1639 -2077
  3. package/mevebu/app/tailwind.src.css +155 -1120
  4. package/mevebu/index.html +2 -2
  5. package/mevebu/libs/js/core.js +236 -96
  6. package/mevebu/libs/js/registry.js +11 -11
  7. package/mevebu/libs/js/tools/abstract-checklist.js +5 -7
  8. package/mevebu/libs/js/tools/add-subtract-days.js +9 -11
  9. package/mevebu/libs/js/tools/age-calculator.js +7 -8
  10. package/mevebu/libs/js/tools/api-request-builder.js +3 -4
  11. package/mevebu/libs/js/tools/area-converter.js +7 -9
  12. package/mevebu/libs/js/tools/aspect-ratio.js +8 -9
  13. package/mevebu/libs/js/tools/average-calculator.js +4 -5
  14. package/mevebu/libs/js/tools/base64.js +31 -11
  15. package/mevebu/libs/js/tools/binary-calculator.js +6 -7
  16. package/mevebu/libs/js/tools/border-radius.js +7 -9
  17. package/mevebu/libs/js/tools/box-shadow.js +6 -7
  18. package/mevebu/libs/js/tools/break-even.js +4 -5
  19. package/mevebu/libs/js/tools/business-days.js +7 -8
  20. package/mevebu/libs/js/tools/canonical-tag.js +5 -6
  21. package/mevebu/libs/js/tools/caption-counter.js +5 -7
  22. package/mevebu/libs/js/tools/case-converter.js +11 -12
  23. package/mevebu/libs/js/tools/case-inspector.js +14 -16
  24. package/mevebu/libs/js/tools/cash-denomination.js +7 -8
  25. package/mevebu/libs/js/tools/cash-flow.js +7 -8
  26. package/mevebu/libs/js/tools/cert-expiry.js +6 -10
  27. package/mevebu/libs/js/tools/changelog-generator.js +4 -6
  28. package/mevebu/libs/js/tools/character-counter.js +10 -13
  29. package/mevebu/libs/js/tools/checklist.js +6 -7
  30. package/mevebu/libs/js/tools/citation-number-check.js +10 -13
  31. package/mevebu/libs/js/tools/coin-flip.js +9 -11
  32. package/mevebu/libs/js/tools/color-converter.js +23 -17
  33. package/mevebu/libs/js/tools/color-palette.js +6 -8
  34. package/mevebu/libs/js/tools/color-picker.js +4 -5
  35. package/mevebu/libs/js/tools/content-calendar.js +3 -4
  36. package/mevebu/libs/js/tools/contrast-checker.js +5 -6
  37. package/mevebu/libs/js/tools/cron-builder.js +4 -6
  38. package/mevebu/libs/js/tools/css-clamp.js +5 -6
  39. package/mevebu/libs/js/tools/css-formatter.js +4 -7
  40. package/mevebu/libs/js/tools/css-grid.js +6 -7
  41. package/mevebu/libs/js/tools/css-minifier.js +5 -8
  42. package/mevebu/libs/js/tools/csv-to-json.js +2 -3
  43. package/mevebu/libs/js/tools/csv-viewer.js +9 -11
  44. package/mevebu/libs/js/tools/currency-format.js +5 -7
  45. package/mevebu/libs/js/tools/daily-planner.js +9 -10
  46. package/mevebu/libs/js/tools/data-masker.js +7 -9
  47. package/mevebu/libs/js/tools/data-storage.js +7 -9
  48. package/mevebu/libs/js/tools/data-validator.js +9 -11
  49. package/mevebu/libs/js/tools/date-difference.js +6 -7
  50. package/mevebu/libs/js/tools/date-format.js +11 -13
  51. package/mevebu/libs/js/tools/delimiter-converter.js +3 -5
  52. package/mevebu/libs/js/tools/discount-calculator.js +4 -5
  53. package/mevebu/libs/js/tools/doi-resolver.js +4 -5
  54. package/mevebu/libs/js/tools/env-formatter.js +3 -6
  55. package/mevebu/libs/js/tools/equation-formatter.js +5 -9
  56. package/mevebu/libs/js/tools/expense-split.js +6 -7
  57. package/mevebu/libs/js/tools/fake-data.js +20 -13
  58. package/mevebu/libs/js/tools/find-replace.js +3 -5
  59. package/mevebu/libs/js/tools/flashcard-creator.js +9 -10
  60. package/mevebu/libs/js/tools/font-pairing.js +6 -8
  61. package/mevebu/libs/js/tools/fraction-calculator.js +10 -13
  62. package/mevebu/libs/js/tools/git-command-builder.js +11 -22
  63. package/mevebu/libs/js/tools/gpa-calculator.js +8 -10
  64. package/mevebu/libs/js/tools/grade-calculator.js +7 -8
  65. package/mevebu/libs/js/tools/gradient-generator.js +10 -12
  66. package/mevebu/libs/js/tools/habit-tracker.js +8 -9
  67. package/mevebu/libs/js/tools/hash-generator.js +3 -5
  68. package/mevebu/libs/js/tools/hashtag-formatter.js +6 -8
  69. package/mevebu/libs/js/tools/hmac-generator.js +3 -5
  70. package/mevebu/libs/js/tools/hpp-calculator.js +4 -5
  71. package/mevebu/libs/js/tools/html-entity.js +2 -3
  72. package/mevebu/libs/js/tools/html-formatter.js +3 -6
  73. package/mevebu/libs/js/tools/http-status.js +5 -7
  74. package/mevebu/libs/js/tools/inventory-quantity.js +7 -8
  75. package/mevebu/libs/js/tools/json-formatter.js +3 -6
  76. package/mevebu/libs/js/tools/json-minifier.js +5 -8
  77. package/mevebu/libs/js/tools/json-to-csv.js +3 -5
  78. package/mevebu/libs/js/tools/json-to-typescript.js +2 -5
  79. package/mevebu/libs/js/tools/json-validator.js +2 -3
  80. package/mevebu/libs/js/tools/jwt-decoder.js +6 -7
  81. package/mevebu/libs/js/tools/jwt-expiry.js +5 -6
  82. package/mevebu/libs/js/tools/jwt-generator.js +4 -6
  83. package/mevebu/libs/js/tools/length-converter.js +7 -9
  84. package/mevebu/libs/js/tools/license-reference.js +10 -13
  85. package/mevebu/libs/js/tools/line-counter.js +5 -7
  86. package/mevebu/libs/js/tools/list-difference.js +5 -7
  87. package/mevebu/libs/js/tools/list-merger.js +4 -5
  88. package/mevebu/libs/js/tools/locale-number.js +5 -8
  89. package/mevebu/libs/js/tools/lorem-ipsum.js +4 -2
  90. package/mevebu/libs/js/tools/markdown-preview.js +5 -8
  91. package/mevebu/libs/js/tools/markdown-table.js +5 -7
  92. package/mevebu/libs/js/tools/markup-calculator.js +4 -5
  93. package/mevebu/libs/js/tools/meeting-agenda.js +8 -9
  94. package/mevebu/libs/js/tools/meta-preview.js +12 -13
  95. package/mevebu/libs/js/tools/meta-tags.js +6 -7
  96. package/mevebu/libs/js/tools/mime-types.js +5 -7
  97. package/mevebu/libs/js/tools/name-picker.js +2 -3
  98. package/mevebu/libs/js/tools/number-base-converter.js +9 -12
  99. package/mevebu/libs/js/tools/password-generator.js +9 -12
  100. package/mevebu/libs/js/tools/password-strength.js +21 -25
  101. package/mevebu/libs/js/tools/percent-to-fraction.js +6 -7
  102. package/mevebu/libs/js/tools/percentage-calculator.js +6 -9
  103. package/mevebu/libs/js/tools/percentage-change.js +4 -5
  104. package/mevebu/libs/js/tools/permutation-combination.js +9 -12
  105. package/mevebu/libs/js/tools/prefix-suffix.js +2 -3
  106. package/mevebu/libs/js/tools/priority-matrix.js +6 -10
  107. package/mevebu/libs/js/tools/profit-margin.js +4 -5
  108. package/mevebu/libs/js/tools/qr-generator.js +3 -4
  109. package/mevebu/libs/js/tools/qr-scanner.js +11 -12
  110. package/mevebu/libs/js/tools/quadratic-solver.js +7 -8
  111. package/mevebu/libs/js/tools/query-builder.js +2 -3
  112. package/mevebu/libs/js/tools/quiz-formatter.js +4 -6
  113. package/mevebu/libs/js/tools/ratio-calculator.js +7 -8
  114. package/mevebu/libs/js/tools/readability.js +12 -15
  115. package/mevebu/libs/js/tools/reading-time.js +5 -7
  116. package/mevebu/libs/js/tools/reference-completeness.js +6 -8
  117. package/mevebu/libs/js/tools/regex-tester.js +7 -10
  118. package/mevebu/libs/js/tools/remove-duplicate-lines.js +2 -3
  119. package/mevebu/libs/js/tools/remove-extra-spaces.js +3 -5
  120. package/mevebu/libs/js/tools/robots-txt.js +3 -4
  121. package/mevebu/libs/js/tools/roman-numeral-converter.js +6 -8
  122. package/mevebu/libs/js/tools/sales-commission.js +8 -9
  123. package/mevebu/libs/js/tools/scientific-calculator.js +10 -14
  124. package/mevebu/libs/js/tools/scientific-notation.js +8 -9
  125. package/mevebu/libs/js/tools/script-planner.js +8 -10
  126. package/mevebu/libs/js/tools/selling-price.js +4 -5
  127. package/mevebu/libs/js/tools/semver-helper.js +3 -5
  128. package/mevebu/libs/js/tools/sentence-length.js +9 -10
  129. package/mevebu/libs/js/tools/sequence-analyzer.js +7 -8
  130. package/mevebu/libs/js/tools/sitemap-xml.js +4 -7
  131. package/mevebu/libs/js/tools/slug-converter.js +3 -5
  132. package/mevebu/libs/js/tools/slug-preview.js +6 -7
  133. package/mevebu/libs/js/tools/sort-lines.js +3 -5
  134. package/mevebu/libs/js/tools/speed-converter.js +7 -9
  135. package/mevebu/libs/js/tools/spin-wheel.js +19 -17
  136. package/mevebu/libs/js/tools/sql-formatter.js +5 -9
  137. package/mevebu/libs/js/tools/sql-minifier.js +5 -8
  138. package/mevebu/libs/js/tools/standard-deviation.js +6 -9
  139. package/mevebu/libs/js/tools/stopwatch.js +4 -6
  140. package/mevebu/libs/js/tools/study-schedule.js +8 -9
  141. package/mevebu/libs/js/tools/subtitle-formatter.js +10 -11
  142. package/mevebu/libs/js/tools/table-to-markdown.js +8 -12
  143. package/mevebu/libs/js/tools/tax-calculator.js +4 -5
  144. package/mevebu/libs/js/tools/temperature-converter.js +8 -11
  145. package/mevebu/libs/js/tools/text-diff.js +11 -7
  146. package/mevebu/libs/js/tools/text-direction.js +3 -5
  147. package/mevebu/libs/js/tools/text-reverser.js +3 -5
  148. package/mevebu/libs/js/tools/time-duration.js +8 -9
  149. package/mevebu/libs/js/tools/timestamp-converter.js +4 -6
  150. package/mevebu/libs/js/tools/timezone-converter.js +9 -13
  151. package/mevebu/libs/js/tools/title-length.js +6 -7
  152. package/mevebu/libs/js/tools/unicode-inspector.js +4 -5
  153. package/mevebu/libs/js/tools/url-encoder.js +4 -2
  154. package/mevebu/libs/js/tools/url-inspector.js +9 -11
  155. package/mevebu/libs/js/tools/url-parser.js +12 -13
  156. package/mevebu/libs/js/tools/utf8-bytes.js +6 -9
  157. package/mevebu/libs/js/tools/uuid-generator.js +107 -15
  158. package/mevebu/libs/js/tools/version-compare.js +3 -4
  159. package/mevebu/libs/js/tools/video-duration.js +5 -7
  160. package/mevebu/libs/js/tools/volume-converter.js +7 -9
  161. package/mevebu/libs/js/tools/weekly-planner.js +8 -10
  162. package/mevebu/libs/js/tools/weight-converter.js +7 -9
  163. package/mevebu/libs/js/tools/weighted-average.js +4 -5
  164. package/mevebu/libs/js/tools/word-counter.js +10 -13
  165. package/mevebu/libs/js/tools/word-limit.js +4 -5
  166. package/mevebu/libs/js/tools/yaml-formatter.js +6 -7
  167. package/package.json +1 -1
@@ -23,10 +23,9 @@ export function mount(slot) {
23
23
  const source = textArea({
24
24
  rows: 14,
25
25
  "aria-label": "Questions",
26
- placeholder: "Question one\n- First option\n- Second option\n* The correct option\n\nQuestion two\n- ...",
27
- });
28
- const quiz = textArea({ rows: 12, readonly: true, class: "mvb-in mvb-in--area mvb-in--mono", "aria-label": "Quiz" });
29
- const key = textArea({ rows: 12, readonly: true, class: "mvb-in mvb-in--area mvb-in--mono", "aria-label": "Answer key" });
26
+ placeholder: "Question one\n- First option\n- Second option\n* The correct option\n\nQuestion two\n- ..."});
27
+ const quiz = textArea({ rows: 12, readonly: true, "aria-label": "Quiz" });
28
+ const key = textArea({ rows: 12, readonly: true, "aria-label": "Answer key" });
30
29
  const error = notice("error");
31
30
 
32
31
  function render() {
@@ -59,8 +58,7 @@ export function mount(slot) {
59
58
  foot: actions(
60
59
  copyButton(() => key.value, "Copy key"),
61
60
  copyButton(() => quiz.value, "Copy quiz", "fill")
62
- ),
63
- });
61
+ )});
64
62
  slot.append(card.node);
65
63
  render();
66
64
 
@@ -17,7 +17,7 @@ function fmt(n) {
17
17
  }
18
18
 
19
19
  const kvRow = (key, value) =>
20
- el("div", { class: "mvb-kv__row" }, el("span", { class: "mvb-kv__k" }, key), el("span", { class: "mvb-kv__v" }, value));
20
+ el("div", { class: "grid gap-3 bg-deck px-3 py-[9px] [grid-template-columns:minmax(90px,34%)_minmax(0,1fr)]" }, el("span", { class: "wrap-anywhere text-2xs font-semibold text-ink-2" }, key), el("span", { class: "wrap-anywhere font-mono text-2xs" }, value));
21
21
 
22
22
  export function mount(slot) {
23
23
  const ratioInput = textInput({ value: "12:18:24", "aria-label": "Ratio" });
@@ -25,12 +25,12 @@ export function mount(slot) {
25
25
  const b = numberInput({ placeholder: "B", "aria-label": "Second term" });
26
26
  const c = numberInput({ placeholder: "C", "aria-label": "Third term" });
27
27
  const d = numberInput({ placeholder: "D", "aria-label": "Fourth term" });
28
- const simplified = el("span", { class: "mvb-kv__v" }, "-");
29
- const decimal = el("span", { class: "mvb-kv__v" }, "-");
30
- const missing = el("span", { class: "mvb-kv__v" }, "-");
28
+ const simplified = el("span", { class: "wrap-anywhere font-mono text-2xs" }, "-");
29
+ const decimal = el("span", { class: "wrap-anywhere font-mono text-2xs" }, "-");
30
+ const missing = el("span", { class: "wrap-anywhere font-mono text-2xs" }, "-");
31
31
  const kv = el(
32
32
  "div",
33
- { class: "mvb-kv" },
33
+ { class: "grid gap-px overflow-hidden rounded-r1 border border-orbit bg-orbit" },
34
34
  kvRow("Simplified ratio", simplified),
35
35
  kvRow("Decimal", decimal),
36
36
  kvRow("Missing term", missing)
@@ -87,13 +87,12 @@ export function mount(slot) {
87
87
  body: bench(
88
88
  stack(
89
89
  panel("Ratio", ratioInput),
90
- panel("Proportion", el("div", { class: "mvb-row" }, a, b, c, d)),
90
+ panel("Proportion", el("div", { class: "flex min-w-0 flex-wrap items-center gap-2" }, a, b, c, d)),
91
91
  error
92
92
  ),
93
93
  stack(panel("Result", kv))
94
94
  ),
95
- foot: actions(copyButton(() => text, "Copy result", "fill")),
96
- });
95
+ foot: actions(copyButton(() => text, "Copy result", "fill"))});
97
96
  slot.append(card.node);
98
97
  run();
99
98
 
@@ -27,15 +27,15 @@ function syllablesOf(word) {
27
27
  }
28
28
 
29
29
  function tile(label, initial = "-") {
30
- const value = el("span", { class: "mvb-stat__v" }, initial);
31
- const node = el("div", { class: "mvb-stat" }, value, el("span", { class: "mvb-stat__k" }, label));
30
+ const value = el("span", { class: "wrap-anywhere text-xl font-bold tracking-[-0.02em] tabular-nums" }, initial);
31
+ const node = el("div", { class: "grid gap-0.5 rounded-r1 border border-orbit bg-deck-2 px-3.5 py-3" }, value, el("span", { class: "text-2xs font-semibold text-ink-3" }, label));
32
32
  node.set = (text) => { value.textContent = text; };
33
33
  return node;
34
34
  }
35
35
 
36
- const kvRow = (key, value) => el("div", { class: "mvb-kv__row" },
37
- el("span", { class: "mvb-kv__k" }, key),
38
- el("span", { class: "mvb-kv__v" }, value));
36
+ const kvRow = (key, value) => el("div", { class: "grid gap-3 bg-deck px-3 py-[9px] [grid-template-columns:minmax(90px,34%)_minmax(0,1fr)]" },
37
+ el("span", { class: "wrap-anywhere text-2xs font-semibold text-ink-2" }, key),
38
+ el("span", { class: "wrap-anywhere font-mono text-2xs" }, value));
39
39
 
40
40
  export function mount(slot) {
41
41
  const source = textArea({ rows: 12, "aria-label": "Text", placeholder: "Type or paste text" });
@@ -43,14 +43,13 @@ export function mount(slot) {
43
43
  const easeTile = tile("Reading ease");
44
44
  const gradeTile = tile("Grade level");
45
45
  const fogTile = tile("Gunning Fog");
46
- const stats = el("div", { class: "mvb-stats" }, easeTile, gradeTile, fogTile);
46
+ const stats = el("div", { class: "grid gap-2.5 [grid-template-columns:repeat(auto-fit,minmax(120px,1fr))]" }, easeTile, gradeTile, fogTile);
47
47
 
48
48
  const counts = {
49
- words: el("span", { class: "mvb-kv__v" }, "0"),
50
- sentences: el("span", { class: "mvb-kv__v" }, "0"),
51
- syllables: el("span", { class: "mvb-kv__v" }, "0"),
52
- };
53
- const countList = el("div", { class: "mvb-kv" },
49
+ words: el("span", { class: "wrap-anywhere font-mono text-2xs" }, "0"),
50
+ sentences: el("span", { class: "wrap-anywhere font-mono text-2xs" }, "0"),
51
+ syllables: el("span", { class: "wrap-anywhere font-mono text-2xs" }, "0")};
52
+ const countList = el("div", { class: "grid gap-px overflow-hidden rounded-r1 border border-orbit bg-orbit" },
54
53
  kvRow("Words", counts.words),
55
54
  kvRow("Sentences", counts.sentences),
56
55
  kvRow("Syllables", counts.syllables));
@@ -90,8 +89,7 @@ export function mount(slot) {
90
89
  `Reading ease ${ease.toFixed(1)}`,
91
90
  `Grade level ${grade.toFixed(1)}`,
92
91
  `Gunning Fog ${fog.toFixed(1)}`,
93
- `${words.length} words, ${sentences.length} sentences, ${syllableCount} syllables`,
94
- ].join("\n");
92
+ `${words.length} words, ${sentences.length} sentences, ${syllableCount} syllables`].join("\n");
95
93
  }
96
94
 
97
95
  source.addEventListener("input", run);
@@ -101,8 +99,7 @@ export function mount(slot) {
101
99
  stack(panel("Text", source)),
102
100
  stack(stats, countList, note)
103
101
  ),
104
- foot: actions(copyButton(() => summary, "Copy scores", "fill")),
105
- });
102
+ foot: actions(copyButton(() => summary, "Copy scores", "fill"))});
106
103
  slot.append(card.node);
107
104
  run();
108
105
 
@@ -23,8 +23,8 @@ const clock = (minutes) => {
23
23
  };
24
24
 
25
25
  function tile(label) {
26
- const value = el("span", { class: "mvb-stat__v" }, "0:00");
27
- const node = el("div", { class: "mvb-stat" }, value, el("span", { class: "mvb-stat__k" }, label));
26
+ const value = el("span", { class: "wrap-anywhere text-xl font-bold tracking-[-0.02em] tabular-nums" }, "0:00");
27
+ const node = el("div", { class: "grid gap-0.5 rounded-r1 border border-orbit bg-deck-2 px-3.5 py-3" }, value, el("span", { class: "text-2xs font-semibold text-ink-3" }, label));
28
28
  node.set = (text) => { value.textContent = text; };
29
29
  return node;
30
30
  }
@@ -36,7 +36,7 @@ export function mount(slot) {
36
36
  const wordsTile = tile("Words");
37
37
  const readTile = tile("Reading time");
38
38
  const speakTile = tile("Speaking time");
39
- const stats = el("div", { class: "mvb-stats" }, wordsTile, readTile, speakTile);
39
+ const stats = el("div", { class: "grid gap-2.5 [grid-template-columns:repeat(auto-fit,minmax(120px,1fr))]" }, wordsTile, readTile, speakTile);
40
40
  const note = notice("note");
41
41
  note.write("Reading and speaking speeds vary by person and text.");
42
42
 
@@ -53,8 +53,7 @@ export function mount(slot) {
53
53
  summary = [
54
54
  `${words} words`,
55
55
  `Reading ${words ? clock(readMinutes) : "0:00"} at ${wpm} words per minute`,
56
- `Speaking ${words ? clock(speakMinutes) : "0:00"} at 130 words per minute`,
57
- ].join("\n");
56
+ `Speaking ${words ? clock(speakMinutes) : "0:00"} at 130 words per minute`].join("\n");
58
57
  }
59
58
 
60
59
  source.addEventListener("input", run);
@@ -65,8 +64,7 @@ export function mount(slot) {
65
64
  stack(panel("Text", source), panel("Reading speed", speed, "Words per minute")),
66
65
  stack(stats, note)
67
66
  ),
68
- foot: actions(copyButton(() => summary, "Copy estimate", "fill")),
69
- });
67
+ foot: actions(copyButton(() => summary, "Copy estimate", "fill"))});
70
68
  slot.append(card.node);
71
69
  run();
72
70
 
@@ -4,8 +4,8 @@ import { el, bench, stack, panel, textArea, notice, copyButton, actions, toolcar
4
4
  const PARTS = ["Author", "Year", "Title", "Source"];
5
5
 
6
6
  function kvRow(key) {
7
- const value = el("span", { class: "mvb-kv__v" }, "-");
8
- const row = el("div", { class: "mvb-kv__row" }, el("span", { class: "mvb-kv__k" }, key), value);
7
+ const value = el("span", { class: "wrap-anywhere font-mono text-2xs" }, "-");
8
+ const row = el("div", { class: "grid gap-3 bg-deck px-3 py-[9px] [grid-template-columns:minmax(90px,34%)_minmax(0,1fr)]" }, el("span", { class: "wrap-anywhere text-2xs font-semibold text-ink-2" }, key), value);
9
9
  return { row, value };
10
10
  }
11
11
 
@@ -14,15 +14,14 @@ function check(text) {
14
14
  return {
15
15
  Author: /^[A-Z][A-Za-z'’.-]+,/.test(t) || /\b(and|&)\s+[A-Z]/.test(t),
16
16
  Year: /\b(1[5-9]\d{2}|20\d{2})\b/.test(t),
17
- Title: /["“][^"”]{2,}["”]/.test(t) || t.replace(/^[^.]*\./, "").trim().length > 8,
18
- Source: /https?:\/\/|www\.|\bIn\b|\b(Journal|Press|Publishing|Publishers|University|vol\.|pp\.|ed\.)\b/i.test(t),
19
- };
17
+ Title: /["“][^"”]{2}["”]/.test(t) || t.replace(/^[^.]*\./, "").trim().length > 8,
18
+ Source: /https?:\/\/|www\.|\bIn\b|\b(Journal|Press|Publishing|Publishers|University|vol\.|pp\.|ed\.)\b/i.test(t)};
20
19
  }
21
20
 
22
21
  export function mount(slot) {
23
22
  const source = textArea({ rows: 6, "aria-label": "Reference", placeholder: "Paste one reference" });
24
23
  const rows = {};
25
- const kv = el("div", { class: "mvb-kv" });
24
+ const kv = el("div", { class: "grid gap-px overflow-hidden rounded-r1 border border-orbit bg-orbit" });
26
25
  for (const key of PARTS) {
27
26
  rows[key] = kvRow(key);
28
27
  kv.append(rows[key].row);
@@ -51,8 +50,7 @@ export function mount(slot) {
51
50
  stack(panel("Reference", source), note),
52
51
  stack(panel("Parts", kv), status)
53
52
  ),
54
- foot: actions(copyButton(() => summary, "Copy check", "fill")),
55
- });
53
+ foot: actions(copyButton(() => summary, "Copy check", "fill"))});
56
54
  slot.append(card.node);
57
55
  run();
58
56
 
@@ -8,12 +8,10 @@ export function mount(slot) {
8
8
  const flagsInput = textInput({ value: "g", "aria-label": "Flags", spellcheck: "false", placeholder: "g i m s u y" });
9
9
  const source = textArea({
10
10
  rows: 8,
11
- class: "mvb-in mvb-in--area mvb-in--mono",
12
11
  "aria-label": "Text to test",
13
- value: "Contact ada@example.com or grace@navy.com for details.",
14
- });
15
- const pane = el("div", { class: "mvb-pane" });
16
- const listWrap = el("div", { class: "mvb-scroll" });
12
+ value: "Contact ada@example.com or grace@navy.com for details."});
13
+ const pane = el("div", { class: "min-h-[120px] max-h-[380px] overflow-auto wrap-anywhere rounded-r1 border border-orbit bg-deck-2 px-4 py-3.5 leading-normal [&>*:first-child]:mt-0 [&>*:last-child]:mb-0 [&_h1]:my-4 [&_h2]:my-4 [&_h3]:my-4 [&_h1]:tracking-[-0.01em] [&_h2]:tracking-[-0.01em] [&_h3]:tracking-[-0.01em] [&_p]:mb-2.5 [&_ul]:mb-2.5 [&_ol]:mb-2.5 [&_pre]:mb-2.5 [&_ul]:ps-[22px] [&_ol]:ps-[22px] [&_code]:rounded-[5px] [&_code]:bg-deck [&_code]:px-[5px] [&_code]:py-px [&_code]:font-mono [&_code]:text-2xs [&_pre]:overflow-auto [&_pre]:rounded-r1 [&_pre]:bg-deck [&_pre]:px-3 [&_pre]:py-2.5 [&_pre_code]:bg-transparent [&_pre_code]:p-0 [&_a]:text-jade [&_table]:border-collapse [&_th]:border [&_td]:border [&_th]:border-orbit [&_td]:border-orbit [&_th]:px-[9px] [&_td]:px-[9px] [&_th]:py-1.5 [&_td]:py-1.5" });
14
+ const listWrap = el("div", { class: "max-h-80 overflow-auto" });
17
15
  const error = notice("error");
18
16
  let lines = [];
19
17
 
@@ -42,7 +40,7 @@ export function mount(slot) {
42
40
  while ((match = re.exec(text)) && count < MAX_MATCHES) {
43
41
  if (match.index === re.lastIndex) re.lastIndex++;
44
42
  nodes.push(document.createTextNode(text.slice(last, match.index)));
45
- nodes.push(el("span", { class: "mvb-hl" }, match[0] || "\u200b"));
43
+ nodes.push(el("span", { class: "rounded-[3px] bg-star/40" }, match[0] || "\u200b"));
46
44
  last = match.index + match[0].length;
47
45
  const groups = match.slice(1).map((group) => group ?? "").join(", ");
48
46
  rows.push(el("tr", {},
@@ -56,10 +54,10 @@ export function mount(slot) {
56
54
  nodes.push(document.createTextNode(text.slice(last)));
57
55
  pane.append(...nodes);
58
56
  if (!count) {
59
- listWrap.append(el("p", { class: "mvb-note" }, "No matches."));
57
+ listWrap.append(el("p", { class: "border-s-[3px] border-transparent ps-2 text-sm text-ink-3" }, "No matches."));
60
58
  return;
61
59
  }
62
- const table = el("table", { class: "mvb-ttable" },
60
+ const table = el("table", { class: "w-full border-collapse font-mono text-sm [&_th]:wrap-anywhere [&_td]:wrap-anywhere [&_th]:border-b [&_td]:border-b [&_th]:border-orbit [&_td]:border-orbit [&_th]:px-2.5 [&_td]:px-2.5 [&_th]:py-2 [&_td]:py-2 [&_th]:text-start [&_td]:text-start [&_th]:font-sans [&_th]:text-2xs [&_th]:font-semibold [&_th]:text-ink-2 [&_tbody>tr:last-child>th]:border-b-0 [&_tbody>tr:last-child>td]:border-b-0" },
63
61
  el("thead", {}, el("tr", {}, el("th", {}, "#"), el("th", {}, "Match"), el("th", {}, "Groups"))),
64
62
  el("tbody", {}, ...rows)
65
63
  );
@@ -75,8 +73,7 @@ export function mount(slot) {
75
73
  stack(panel("Pattern", patternInput), panel("Flags", flagsInput), panel("Text", source), error),
76
74
  stack(panel("Matches", pane), panel("Groups", listWrap))
77
75
  ),
78
- foot: actions(copyButton(() => lines.join("\n"), "Copy matches", "fill")),
79
- });
76
+ foot: actions(copyButton(() => lines.join("\n"), "Copy matches", "fill"))});
80
77
  slot.append(card.node);
81
78
  run();
82
79
 
@@ -4,7 +4,7 @@ import { bench, stack, panel, textArea, checkbox, notice, copyButton, actions, t
4
4
  export function mount(slot) {
5
5
  const source = textArea({ rows: 12, "aria-label": "Text", placeholder: "Paste your list, one entry per line" });
6
6
  const ignoreCase = checkbox("Ignore case", { checked: false });
7
- const result = textArea({ rows: 12, readonly: true, class: "mvb-in mvb-in--area mvb-in--mono", "aria-label": "Result" });
7
+ const result = textArea({ rows: 12, readonly: true, "aria-label": "Result" });
8
8
  const note = notice("note");
9
9
 
10
10
  function run() {
@@ -35,8 +35,7 @@ export function mount(slot) {
35
35
  stack(panel("Text", source), ignoreCase, note),
36
36
  stack(panel("Result", result))
37
37
  ),
38
- foot: actions(copyButton(() => result.value, "Copy result", "fill")),
39
- });
38
+ foot: actions(copyButton(() => result.value, "Copy result", "fill"))});
40
39
  slot.append(card.node);
41
40
  run();
42
41
 
@@ -4,12 +4,11 @@ import { bench, stack, panel, textArea, toggleRow, copyButton, actions, toolcard
4
4
 
5
5
  export function mount(slot) {
6
6
  const source = textArea({ rows: 12, "aria-label": "Text", placeholder: "Paste your text" });
7
- const result = textArea({ rows: 12, readonly: true, class: "mvb-in mvb-in--area mvb-in--mono", "aria-label": "Result" });
7
+ const result = textArea({ rows: 12, readonly: true, "aria-label": "Result" });
8
8
  const options = toggleRow([
9
9
  { value: "collapse", label: "Collapse spaces", checked: true },
10
10
  { value: "trim", label: "Trim lines", checked: true },
11
- { value: "blank", label: "Remove blank lines", checked: false },
12
- ]);
11
+ { value: "blank", label: "Remove blank lines", checked: false }]);
13
12
 
14
13
  function run() {
15
14
  const text = source.value;
@@ -30,8 +29,7 @@ export function mount(slot) {
30
29
  stack(panel("Text", source), options),
31
30
  stack(panel("Result", result))
32
31
  ),
33
- foot: actions(copyButton(() => result.value, "Copy result", "fill")),
34
- });
32
+ foot: actions(copyButton(() => result.value, "Copy result", "fill"))});
35
33
  slot.append(card.node);
36
34
  run();
37
35
 
@@ -13,8 +13,8 @@ const isUrl = (value) => {
13
13
 
14
14
  export function mount(slot) {
15
15
  const agent = textInput({ value: "*", "aria-label": "User agent" });
16
- const disallow = textArea({ rows: 5, class: "mvb-in mvb-in--area mvb-in--mono", placeholder: "/admin\n/private", "aria-label": "Disallow paths" });
17
- const allow = textArea({ rows: 3, class: "mvb-in mvb-in--area mvb-in--mono", placeholder: "/public", "aria-label": "Allow paths" });
16
+ const disallow = textArea({ rows: 5, placeholder: "/admin\n/private", "aria-label": "Disallow paths" });
17
+ const allow = textArea({ rows: 3, placeholder: "/public", "aria-label": "Allow paths" });
18
18
  const sitemap = textInput({ value: "https://example.com/sitemap.xml", "aria-label": "Sitemap URL" });
19
19
  const result = output({ rows: 8 });
20
20
  const error = notice("error");
@@ -49,8 +49,7 @@ export function mount(slot) {
49
49
  ),
50
50
  stack(panel("robots.txt", result))
51
51
  ),
52
- foot: actions(copyButton(() => result.textContent, "Copy robots.txt", "fill")),
53
- });
52
+ foot: actions(copyButton(() => result.textContent, "Copy robots.txt", "fill"))});
54
53
  slot.append(card.node);
55
54
  build();
56
55
 
@@ -3,8 +3,7 @@ import { el, bench, stack, panel, textInput, notice, copyButton, actions, toolca
3
3
 
4
4
  const NUMERALS = [
5
5
  [1000, "M"], [900, "CM"], [500, "D"], [400, "CD"], [100, "C"], [90, "XC"],
6
- [50, "L"], [40, "XL"], [10, "X"], [9, "IX"], [5, "V"], [4, "IV"], [1, "I"],
7
- ];
6
+ [50, "L"], [40, "XL"], [10, "X"], [9, "IX"], [5, "V"], [4, "IV"], [1, "I"]];
8
7
 
9
8
  function toRoman(n) {
10
9
  let rest = n;
@@ -32,15 +31,15 @@ function fromRoman(text) {
32
31
  }
33
32
 
34
33
  const kvRow = (key, value) =>
35
- el("div", { class: "mvb-kv__row" }, el("span", { class: "mvb-kv__k" }, key), el("span", { class: "mvb-kv__v" }, value));
34
+ el("div", { class: "grid gap-3 bg-deck px-3 py-[9px] [grid-template-columns:minmax(90px,34%)_minmax(0,1fr)]" }, el("span", { class: "wrap-anywhere text-2xs font-semibold text-ink-2" }, key), el("span", { class: "wrap-anywhere font-mono text-2xs" }, value));
36
35
 
37
36
  export function mount(slot) {
38
37
  const source = textInput({ value: "2026", "aria-label": "Number or Roman numeral", placeholder: "2026 or MMXXVI" });
39
- const detected = el("span", { class: "mvb-kv__v" }, "-");
40
- const result = el("span", { class: "mvb-kv__v" }, "-");
38
+ const detected = el("span", { class: "wrap-anywhere font-mono text-2xs" }, "-");
39
+ const result = el("span", { class: "wrap-anywhere font-mono text-2xs" }, "-");
41
40
  const kv = el(
42
41
  "div",
43
- { class: "mvb-kv" },
42
+ { class: "grid gap-px overflow-hidden rounded-r1 border border-orbit bg-orbit" },
44
43
  kvRow("Input", detected),
45
44
  kvRow("Result", result)
46
45
  );
@@ -95,8 +94,7 @@ export function mount(slot) {
95
94
  stack(panel("Number or Roman numeral", source), error),
96
95
  stack(panel("Result", kv))
97
96
  ),
98
- foot: actions(copyButton(() => text, "Copy result", "fill")),
99
- });
97
+ foot: actions(copyButton(() => text, "Copy result", "fill"))});
100
98
  slot.append(card.node);
101
99
  run();
102
100
 
@@ -16,14 +16,14 @@ export function mount(slot) {
16
16
  const rate = numberInput({ value: "5", min: "0", "aria-label": "Rate" });
17
17
  const threshold = numberInput({ placeholder: "Threshold", min: "0", "aria-label": "Tier threshold" });
18
18
  const higher = numberInput({ placeholder: "Higher rate", min: "0", "aria-label": "Higher rate" });
19
- const result = el("div", { class: "mvb-scroll" });
20
- const stats = el("div", { class: "mvb-stats" });
19
+ const result = el("div", { class: "max-h-80 overflow-auto" });
20
+ const stats = el("div", { class: "grid gap-2.5 [grid-template-columns:repeat(auto-fit,minmax(120px,1fr))]" });
21
21
  const error = notice("error");
22
22
  let text = "";
23
23
 
24
- const tile = (key, value) => el("div", { class: "mvb-stat" },
25
- el("span", { class: "mvb-stat__v" }, String(value)),
26
- el("span", { class: "mvb-stat__k" }, key));
24
+ const tile = (key, value) => el("div", { class: "grid gap-0.5 rounded-r1 border border-orbit bg-deck-2 px-3.5 py-3" },
25
+ el("span", { class: "wrap-anywhere text-xl font-bold tracking-[-0.02em] tabular-nums" }, String(value)),
26
+ el("span", { class: "text-2xs font-semibold text-ink-3" }, key));
27
27
 
28
28
  const tiered = () => threshold.value.trim() !== "" && higher.value.trim() !== "";
29
29
 
@@ -43,7 +43,7 @@ export function mount(slot) {
43
43
  const { nums, invalid } = parseNumbers(sales.value);
44
44
  const r = Number(rate.value);
45
45
  if (!sales.value.trim()) {
46
- result.replaceChildren(el("p", { class: "mvb-note" }, "Add one sale amount per line."));
46
+ result.replaceChildren(el("p", { class: "border-s-[3px] border-transparent ps-2 text-sm text-ink-3" }, "Add one sale amount per line."));
47
47
  stats.replaceChildren();
48
48
  return;
49
49
  }
@@ -53,7 +53,7 @@ export function mount(slot) {
53
53
  stats.replaceChildren();
54
54
  return;
55
55
  }
56
- result.replaceChildren(el("table", { class: "mvb-ttable" },
56
+ result.replaceChildren(el("table", { class: "w-full border-collapse font-mono text-sm [&_th]:wrap-anywhere [&_td]:wrap-anywhere [&_th]:border-b [&_td]:border-b [&_th]:border-orbit [&_td]:border-orbit [&_th]:px-2.5 [&_td]:px-2.5 [&_th]:py-2 [&_td]:py-2 [&_th]:text-start [&_td]:text-start [&_th]:font-sans [&_th]:text-2xs [&_th]:font-semibold [&_th]:text-ink-2 [&_tbody>tr:last-child>th]:border-b-0 [&_tbody>tr:last-child>td]:border-b-0" },
57
57
  el("thead", {}, el("tr", {}, el("th", {}, "Sale"), el("th", {}, "Commission"))),
58
58
  el("tbody", {}, ...nums.map((amount) => el("tr", {},
59
59
  el("th", {}, fmt(amount)),
@@ -85,8 +85,7 @@ export function mount(slot) {
85
85
  foot: actions(
86
86
  downloadButton(() => csv(), "commission.csv", "Save CSV", "text/csv"),
87
87
  copyButton(() => text, "Copy commission", "fill")
88
- ),
89
- });
88
+ )});
90
89
  slot.append(card.node);
91
90
  run();
92
91
 
@@ -51,8 +51,7 @@ const FUNCTIONS = {
51
51
  ln: (x) => Math.log(x),
52
52
  sqrt: (x) => Math.sqrt(x),
53
53
  abs: (x) => Math.abs(x),
54
- exp: (x) => Math.exp(x),
55
- };
54
+ exp: (x) => Math.exp(x)};
56
55
 
57
56
  function evaluate(src, degrees) {
58
57
  const tokens = tokenize(src);
@@ -146,20 +145,18 @@ export function mount(slot) {
146
145
  const input = textInput({ value: "sin(30) + 2^3", "aria-label": "Expression", placeholder: "sin(30) + 2^3" });
147
146
  const display = output({ rows: 2 });
148
147
  const error = notice("error");
149
- const history = el("div", { class: "mvb-kv" });
148
+ const history = el("div", { class: "grid gap-px overflow-hidden rounded-r1 border border-orbit bg-orbit" });
150
149
  const chips = chipRow(
151
150
  [
152
151
  { value: "deg", label: "Degrees" },
153
- { value: "rad", label: "Radians" },
154
- ],
152
+ { value: "rad", label: "Radians" }],
155
153
  {
156
154
  value: "deg",
157
155
  label: "Angle unit",
158
156
  onChange: (value) => {
159
157
  degrees = value === "deg";
160
158
  run();
161
- },
162
- }
159
+ }}
163
160
  );
164
161
  const recent = [];
165
162
  let degrees = true;
@@ -169,9 +166,9 @@ export function mount(slot) {
169
166
  history.replaceChildren();
170
167
  for (const entry of recent) {
171
168
  history.append(
172
- el("div", { class: "mvb-kv__row" },
173
- el("span", { class: "mvb-kv__k" }, entry.expression),
174
- el("span", { class: "mvb-kv__v" }, entry.result))
169
+ el("div", { class: "grid gap-3 bg-deck px-3 py-[9px] [grid-template-columns:minmax(90px,34%)_minmax(0,1fr)]" },
170
+ el("span", { class: "wrap-anywhere text-2xs font-semibold text-ink-2" }, entry.expression),
171
+ el("span", { class: "wrap-anywhere font-mono text-2xs" }, entry.result))
175
172
  );
176
173
  }
177
174
  }
@@ -219,9 +216,9 @@ export function mount(slot) {
219
216
  run();
220
217
  }
221
218
 
222
- const keypad = el("div", { class: "mvb-chips" });
219
+ const keypad = el("div", { class: "flex flex-wrap gap-1.5" });
223
220
  for (const key of KEYS) {
224
- keypad.append(el("button", { class: "mvb-chip", type: "button", onclick: () => insert(key) }, key));
221
+ keypad.append(el("button", { class: "min-h-[var(--ctl)] cursor-pointer rounded-r1 border border-orbit bg-deck px-[13px] text-sm font-medium text-ink-2 transition-colors duration-150 hover:border-orbit-hard hover:text-ink data-[on]:border-jade data-[on]:bg-jade-soft data-[on]:text-ink", type: "button", onclick: () => insert(key) }, key));
225
222
  }
226
223
 
227
224
  input.addEventListener("input", run);
@@ -236,8 +233,7 @@ export function mount(slot) {
236
233
  ),
237
234
  stack(display, error, panel("History", history))
238
235
  ),
239
- foot: actions(copyButton(() => current, "Copy result"), evaluateButton),
240
- });
236
+ foot: actions(copyButton(() => current, "Copy result"), evaluateButton)});
241
237
  slot.append(card.node);
242
238
  run();
243
239
 
@@ -17,18 +17,18 @@ function decimalForm(n) {
17
17
  }
18
18
 
19
19
  const kvRow = (key, value) =>
20
- el("div", { class: "mvb-kv__row" }, el("span", { class: "mvb-kv__k" }, key), el("span", { class: "mvb-kv__v" }, value));
20
+ el("div", { class: "grid gap-3 bg-deck px-3 py-[9px] [grid-template-columns:minmax(90px,34%)_minmax(0,1fr)]" }, el("span", { class: "wrap-anywhere text-2xs font-semibold text-ink-2" }, key), el("span", { class: "wrap-anywhere font-mono text-2xs" }, value));
21
21
 
22
22
  export function mount(slot) {
23
23
  const source = textInput({ value: "3.2e8", "aria-label": "Number", placeholder: "3.2e8 or 320000000" });
24
- const scientific = el("span", { class: "mvb-kv__v" }, "-");
25
- const eForm = el("span", { class: "mvb-kv__v" }, "-");
26
- const decimal = el("span", { class: "mvb-kv__v" }, "-");
27
- const coefficient = el("span", { class: "mvb-kv__v" }, "-");
28
- const exponent = el("span", { class: "mvb-kv__v" }, "-");
24
+ const scientific = el("span", { class: "wrap-anywhere font-mono text-2xs" }, "-");
25
+ const eForm = el("span", { class: "wrap-anywhere font-mono text-2xs" }, "-");
26
+ const decimal = el("span", { class: "wrap-anywhere font-mono text-2xs" }, "-");
27
+ const coefficient = el("span", { class: "wrap-anywhere font-mono text-2xs" }, "-");
28
+ const exponent = el("span", { class: "wrap-anywhere font-mono text-2xs" }, "-");
29
29
  const kv = el(
30
30
  "div",
31
- { class: "mvb-kv" },
31
+ { class: "grid gap-px overflow-hidden rounded-r1 border border-orbit bg-orbit" },
32
32
  kvRow("Scientific", scientific),
33
33
  kvRow("E notation", eForm),
34
34
  kvRow("Decimal", decimal),
@@ -72,8 +72,7 @@ export function mount(slot) {
72
72
  stack(panel("Number", source), error),
73
73
  stack(panel("Forms", kv))
74
74
  ),
75
- foot: actions(copyButton(() => text, "Copy scientific", "fill")),
76
- });
75
+ foot: actions(copyButton(() => text, "Copy scientific", "fill"))});
77
76
  slot.append(card.node);
78
77
  run();
79
78
 
@@ -5,8 +5,7 @@ const SECTIONS = [
5
5
  ["hook", "Hook"],
6
6
  ["intro", "Intro"],
7
7
  ["body", "Body"],
8
- ["outro", "Outro"],
9
- ];
8
+ ["outro", "Outro"]];
10
9
 
11
10
  const clock = (seconds) => {
12
11
  const total = Math.max(0, Math.round(seconds));
@@ -15,9 +14,9 @@ const clock = (seconds) => {
15
14
 
16
15
  const countWords = (text) => (text.trim() ? text.trim().split(/\s+/).length : 0);
17
16
 
18
- const kvRow = (key, value) => el("div", { class: "mvb-kv__row" },
19
- el("span", { class: "mvb-kv__k" }, key),
20
- el("span", { class: "mvb-kv__v" }, value));
17
+ const kvRow = (key, value) => el("div", { class: "grid gap-3 bg-deck px-3 py-[9px] [grid-template-columns:minmax(90px,34%)_minmax(0,1fr)]" },
18
+ el("span", { class: "wrap-anywhere text-2xs font-semibold text-ink-2" }, key),
19
+ el("span", { class: "wrap-anywhere font-mono text-2xs" }, value));
21
20
 
22
21
  export function mount(slot) {
23
22
  const inputs = {};
@@ -30,13 +29,13 @@ export function mount(slot) {
30
29
  const rate = numberInput({ min: "60", max: "400", value: "150", "aria-label": "Speaking rate in words per minute" });
31
30
 
32
31
  const rows = {};
33
- const list = el("div", { class: "mvb-kv" });
32
+ const list = el("div", { class: "grid gap-px overflow-hidden rounded-r1 border border-orbit bg-orbit" });
34
33
  for (const [id, label] of SECTIONS) {
35
- const value = el("span", { class: "mvb-kv__v" }, "0 words");
34
+ const value = el("span", { class: "wrap-anywhere font-mono text-2xs" }, "0 words");
36
35
  rows[id] = value;
37
36
  list.append(kvRow(label, value));
38
37
  }
39
- const total = el("span", { class: "mvb-kv__v" }, "0 words");
38
+ const total = el("span", { class: "wrap-anywhere font-mono text-2xs" }, "0 words");
40
39
  list.append(kvRow("Total", total));
41
40
 
42
41
  let fullScript = "";
@@ -61,8 +60,7 @@ export function mount(slot) {
61
60
  stack(...fields),
62
61
  stack(panel("Speaking rate", rate, "Words per minute"), list)
63
62
  ),
64
- foot: actions(copyButton(() => fullScript, "Copy script", "fill")),
65
- });
63
+ foot: actions(copyButton(() => fullScript, "Copy script", "fill"))});
66
64
  slot.append(card.node);
67
65
  run();
68
66
 
@@ -6,8 +6,8 @@ function fmt(n) {
6
6
  }
7
7
 
8
8
  function tile(label) {
9
- const value = el("span", { class: "mvb-stat__v" }, "-");
10
- const node = el("div", { class: "mvb-stat" }, value, el("span", { class: "mvb-stat__k" }, label));
9
+ const value = el("span", { class: "wrap-anywhere text-xl font-bold tracking-[-0.02em] tabular-nums" }, "-");
10
+ const node = el("div", { class: "grid gap-0.5 rounded-r1 border border-orbit bg-deck-2 px-3.5 py-3" }, value, el("span", { class: "text-2xs font-semibold text-ink-3" }, label));
11
11
  node.set = (text) => { value.textContent = text; };
12
12
  return node;
13
13
  }
@@ -22,7 +22,7 @@ export function mount(slot) {
22
22
  );
23
23
  const price = tile("Selling price");
24
24
  const profit = tile("Profit");
25
- const stats = el("div", { class: "mvb-stats" }, price, profit);
25
+ const stats = el("div", { class: "grid gap-2.5 [grid-template-columns:repeat(auto-fit,minmax(120px,1fr))]" }, price, profit);
26
26
  const error = notice("error");
27
27
  let text = "";
28
28
 
@@ -63,8 +63,7 @@ export function mount(slot) {
63
63
  stack(panel("Cost per unit", cost), panel("Target", chips), panel("Percent", percent), error),
64
64
  stack(stats)
65
65
  ),
66
- foot: actions(copyButton(() => text, "Copy result", "fill")),
67
- });
66
+ foot: actions(copyButton(() => text, "Copy result", "fill"))});
68
67
  slot.append(card.node);
69
68
  run();
70
69
 
@@ -4,11 +4,10 @@ import { bench, stack, panel, textInput, chipRow, output, notice, copyButton, ac
4
4
  const BUMPS = [
5
5
  { value: "major", label: "Major" },
6
6
  { value: "minor", label: "Minor" },
7
- { value: "patch", label: "Patch" },
8
- ];
7
+ { value: "patch", label: "Patch" }];
9
8
 
10
9
  export function mount(slot) {
11
- const version = textInput({ value: "1.2.3", class: "mvb-in mvb-in--mono", "aria-label": "Current version" });
10
+ const version = textInput({ value: "1.2.3", mono: true, "aria-label": "Current version" });
12
11
  const prerelease = textInput({ value: "", placeholder: "rc.1", "aria-label": "Prerelease tag" });
13
12
  const error = notice("error");
14
13
  const out = output({ rows: 1 });
@@ -43,8 +42,7 @@ export function mount(slot) {
43
42
  stack(panel("Current version", version), panel("Bump", chips), panel("Prerelease", prerelease), error),
44
43
  stack(panel("New version", out))
45
44
  ),
46
- foot: actions(copyButton(() => text, "Copy version", "fill")),
47
- });
45
+ foot: actions(copyButton(() => text, "Copy version", "fill"))});
48
46
  slot.append(card.node);
49
47
  run();
50
48