mevebu 1.8.1 → 1.10.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.
package/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  # mevebu
4
4
 
5
- **187 free browser tools, one page each. No sign up. No uploads. Everything runs in your tab.**
5
+ **188 free browser tools, one page each. No sign up. No uploads. Everything runs in your tab.**
6
6
 
7
7
  A private toolbox for the small jobs that do not deserve a whole app: format JSON, decode a JWT, make a password, build a cron line, pick a color, scan a QR code, and a lot more.
8
8
 
@@ -10,7 +10,7 @@ A private toolbox for the small jobs that do not deserve a whole app: format JSO
10
10
  [![npm downloads](https://img.shields.io/npm/dm/mevebu?color=2ea44f)](https://www.npmjs.com/package/mevebu)
11
11
  [![License: MIT](https://img.shields.io/github/license/mevebu/mevebu?color=blue)](./LICENSE)
12
12
  [![GitHub stars](https://img.shields.io/github/stars/mevebu/mevebu?style=flat&color=yellow)](https://github.com/mevebu/mevebu/stargazers)
13
- ![Tools](https://img.shields.io/badge/tools-187-brightgreen)
13
+ ![Tools](https://img.shields.io/badge/tools-188-brightgreen)
14
14
  ![Privacy](https://img.shields.io/badge/privacy-100%25%20in--browser-blue)
15
15
 
16
16
  [Quick start](#quick-start) · [What's inside](#whats-inside) · [Privacy](#privacy-by-design) · [Host it yourself](#host-it-yourself) · [Development](#development) · [FAQ](#faq)
@@ -23,7 +23,7 @@ A private toolbox for the small jobs that do not deserve a whole app: format JSO
23
23
 
24
24
  ## What is mevebu?
25
25
 
26
- mevebu is a collection of **187 small online tools** that all run **inside your browser**. Each tool lives on its own page, does one job, and does it fast. Most of them update as you type, so there is no submit button and no waiting.
26
+ mevebu is a collection of **188 small online tools** that all run **inside your browser**. Each tool lives on its own page, does one job, and does it fast. Most of them update as you type, so there is no submit button and no waiting.
27
27
 
28
28
  Think of it as a clean, private alternative to the usual "free online tools" websites. There are no accounts, no ads in your way, no uploads, and no tracking. Your text, passwords, tokens, and files stay on your device.
29
29
 
@@ -65,14 +65,14 @@ mevebu tries port `5555` first, then `5678`, then `5432`, and finally any free p
65
65
 
66
66
  ## What's inside
67
67
 
68
- mevebu has **187 tools in 20 categories**. Here is the full breakdown:
68
+ mevebu has **188 tools in 20 categories**. Here is the full breakdown:
69
69
 
70
70
  | Category | Tools |
71
71
  | ------------------ | ----: |
72
72
  | Random | 3 |
73
73
  | Passwords and keys | 10 |
74
74
  | Developer | 21 |
75
- | Convert | 4 |
75
+ | Convert | 5 |
76
76
  | Text and data | 14 |
77
77
  | Daily use | 8 |
78
78
  | Math | 17 |
@@ -89,7 +89,7 @@ mevebu has **187 tools in 20 categories**. Here is the full breakdown:
89
89
  | GitHub | 8 |
90
90
  | Units | 8 |
91
91
  | QR codes | 2 |
92
- | **Total** | **187** |
92
+ | **Total** | **188** |
93
93
 
94
94
  The counts come straight from the tool registry, so this table and the app never drift apart.
95
95
 
@@ -109,7 +109,7 @@ Browse everything from the home page or by category, or just press `Ctrl+K` and
109
109
 
110
110
  ## Privacy by design
111
111
 
112
- mevebu is built so that your data has nowhere to go. Every tool is a static HTML file, a tiny JavaScript module, and a Lucide icon. There is no server side code, no analytics, and no API key.
112
+ mevebu is built so that your data has nowhere to go. Every tool is a static HTML file and a small JavaScript module. Icons are Lucide, brand marks are Simple Icons, and the libraries that do real work (mathjs, pdf-lib, pdf.js, jsQR) are vendored into the folder rather than fetched from a CDN. There is no server side code, no analytics, and no API key.
113
113
 
114
114
  When you paste a password, a token, or a CSV into a tool:
115
115
 
@@ -148,6 +148,7 @@ cd mevebu
148
148
  npm install
149
149
  npm run css # build the stylesheet from tailwind.src.css
150
150
  npm run icons # regenerate the vendored Lucide icon set
151
+ npm run social # regenerate the vendored Simple Icons brand marks
151
152
  npm start # serve the static folder on http://localhost:5555
152
153
  ```
153
154
 
@@ -179,7 +180,7 @@ That is all. The catalog, search, breadcrumbs, and category pages pick it up aut
179
180
  ## FAQ
180
181
 
181
182
  **What is mevebu?**
182
- mevebu is a free, open source collection of 187 browser based tools for developers, students, creators, and everyday use. Every tool runs locally in your browser.
183
+ mevebu is a free, open source collection of 188 browser based tools for developers, students, creators, and everyday use. Every tool runs locally in your browser.
183
184
 
184
185
  **Is mevebu really free?**
185
186
  Yes. It is MIT licensed, with no paid tier, no account, and no usage limits.
@@ -2,6 +2,7 @@
2
2
  // wiring, the home page, the tool index, and the bench a tool mounts into.
3
3
 
4
4
  import { CATEGORIES, TOOLS, getTool, getCategory, toolsInCategory, toolHref } from "../libs/js/registry.js";
5
+ import { socialIcon } from "../libs/js/social-icons.js";
5
6
  import { route, start, match, currentPath, go } from "../libs/js/router.js";
6
7
  import {
7
8
  $, $$, el, icon, getFavorites, isFavorite, toggleFavorite, setTheme,
@@ -11,6 +12,28 @@ import {
11
12
  } from "../libs/js/core.js";
12
13
 
13
14
  const REPO_URL = "https://github.com/mevebu/mevebu";
15
+ const WAITSEC_URL = "https://github.com/mevebu/waitsec";
16
+ const ORG_URL = "https://github.com/mevebu";
17
+ const CREATOR = {
18
+ name: "Ilyas Mukhlisin",
19
+ instagram: "https://www.instagram.com/ilyas.mukhlisin",
20
+ threads: "https://www.threads.com/@ilyas.mukhlisin",
21
+ };
22
+
23
+ /* One list drives the footer modal and the about page, so an account is added
24
+ in one place and both surfaces follow. */
25
+ const MEVEBU_SOCIALS = [
26
+ { name: "GitHub", handle: "@mevebu", href: ORG_URL, icon: "github" },
27
+ { name: "Instagram", handle: "@mevebu01", href: "https://www.instagram.com/mevebu01", icon: "instagram" },
28
+ { name: "Threads", handle: "@mevebu01", href: "https://www.threads.net/@mevebu01", icon: "threads" },
29
+ { name: "TikTok", handle: "@mevebu01", href: "https://www.tiktok.com/@mevebu01", icon: "tiktok" },
30
+ { name: "Facebook", handle: "mevebu", href: "https://www.facebook.com/mevebu", icon: "facebook" },
31
+ { name: "YouTube", handle: "@mevebu", href: "https://www.youtube.com/@mevebu", icon: "youtube" },
32
+ ];
33
+ const CREATOR_SOCIALS = [
34
+ { name: "Instagram", handle: "@ilyas.mukhlisin", href: CREATOR.instagram, icon: "instagram" },
35
+ { name: "Threads", handle: "@ilyas.mukhlisin", href: CREATOR.threads, icon: "threads" },
36
+ ];
14
37
 
15
38
  const NAV = [
16
39
  { path: "/", label: "Home" },
@@ -276,6 +299,46 @@ async function startVersionChip() {
276
299
  });
277
300
  }
278
301
 
302
+ function followRow(item) {
303
+ return el(
304
+ "a",
305
+ {
306
+ class:
307
+ "flex items-center gap-3 rounded-r1 border border-orbit bg-deck-2 p-2.5 text-ink no-underline transition-colors duration-150 hover:border-orbit-hard hover:bg-deck",
308
+ href: item.href,
309
+ target: "_blank",
310
+ rel: "noopener",
311
+ },
312
+ el("span", { class: "grid size-9 flex-none place-items-center rounded-lg bg-jade-soft text-jade" }, socialIcon(item.icon, "size-[18px]")),
313
+ el("span", { class: "grid min-w-0 gap-0.5" },
314
+ el("span", { class: "text-sm font-semibold" }, item.name),
315
+ el("span", { class: "truncate text-2xs text-ink-3" }, item.handle)),
316
+ icon("external-link", "ms-auto size-4 flex-none text-ink-3")
317
+ );
318
+ }
319
+
320
+ function followGroup(title, items) {
321
+ return el(
322
+ "section",
323
+ { class: "grid gap-2" },
324
+ el("h3", { class: "m-0 text-2xs font-bold tracking-[0.08em] text-ink-3 uppercase" }, title),
325
+ el("div", { class: "grid gap-1.5" }, ...items.map(followRow))
326
+ );
327
+ }
328
+
329
+ function openFollow() {
330
+ modal({
331
+ label: "Follow mevebu",
332
+ body: [
333
+ modalHead("users-round", "Follow mevebu"),
334
+ el("p", { class: "m-0 text-sm leading-[1.6] text-ink-2" },
335
+ "Release notes, new tools, and the small updates in between. Pick a network."),
336
+ followGroup("mevebu", MEVEBU_SOCIALS),
337
+ followGroup(`${CREATOR.name}, creator`, CREATOR_SOCIALS),
338
+ ],
339
+ });
340
+ }
341
+
279
342
  function footer() {
280
343
  // A finger needs 44px on a phone, so the whole list is a comfortable target
281
344
  // there. The desktop row stays as it was, at text height.
@@ -322,6 +385,17 @@ function footer() {
322
385
  "div",
323
386
  { class: "mt-[clamp(26px,4vw,44px)] flex flex-wrap items-center gap-x-5 gap-y-2 border-t border-orbit pt-5 text-2xs text-ink-3" },
324
387
  el("p", { class: "m-0 flex items-center gap-2" }, "MIT licensed."),
388
+ el(
389
+ "button",
390
+ {
391
+ class:
392
+ "inline-flex min-h-7 cursor-pointer items-center gap-1.5 rounded-full border border-orbit bg-transparent px-2.5 py-[3px] font-sans text-2xs font-semibold text-ink-2 transition-colors duration-150 hover:border-jade hover:bg-jade-soft hover:text-jade max-[45rem]:min-h-11",
393
+ type: "button",
394
+ onclick: () => openFollow(),
395
+ },
396
+ icon("users-round", "size-3.5"),
397
+ "Follow us"
398
+ ),
325
399
  el(
326
400
  "p",
327
401
  { class: "m-0 flex items-center gap-2" },
@@ -872,16 +946,69 @@ async function toolPage(tool, category) {
872
946
  }
873
947
 
874
948
  function aboutPage() {
949
+ const H1 = "m-0 text-[clamp(34px,6vw,52px)] font-bold tracking-[-0.03em]";
950
+ const SUB = "mt-3 mb-0 max-w-[64ch] text-pretty text-md leading-[1.6] text-ink-2";
875
951
  const block = (title, ...nodes) =>
876
952
  el("section", { class: ABOUT_BLOCK }, el("h2", { class: "text-lg font-bold tracking-[-0.01em]" }, title), ...nodes);
877
953
 
954
+ const stat = (value, label) =>
955
+ el("div", { class: "grid gap-0.5 rounded-r2 border border-orbit bg-deck-2 px-4 py-3" },
956
+ el("span", { class: "text-2xl font-bold tracking-[-0.02em] text-ink tabular-nums" }, value),
957
+ el("span", { class: "text-2xs font-semibold tracking-[0.06em] text-ink-3 uppercase" }, label));
958
+
959
+ const repoCard = (name, body, href) =>
960
+ el("a", {
961
+ class: "grid content-start gap-1.5 rounded-r2 border border-orbit bg-deck p-4 no-underline transition-colors duration-150 hover:border-orbit-hard hover:bg-deck-2",
962
+ href,
963
+ target: "_blank",
964
+ rel: "noopener",
965
+ },
966
+ el("span", { class: "flex items-center gap-2 text-md font-bold text-ink" },
967
+ icon("git-branch", "size-4 flex-none text-jade"), name),
968
+ el("span", { class: "text-sm leading-[1.55] text-ink-2" }, body),
969
+ el("span", { class: "mt-1 inline-flex items-center gap-1.5 font-mono text-2xs font-semibold text-jade" },
970
+ href.replace("https://", ""), icon("external-link", "size-3")));
971
+
972
+ const creatorLink = (item) =>
973
+ el("a", {
974
+ class: "inline-flex min-h-11 items-center gap-2 rounded-r1 border border-orbit bg-deck px-3 text-sm font-semibold text-ink no-underline transition-colors duration-150 hover:border-orbit-hard hover:bg-deck-2",
975
+ href: item.href,
976
+ target: "_blank",
977
+ rel: "noopener",
978
+ }, socialIcon(item.icon, "size-[17px] text-jade"), item.name);
979
+
878
980
  document.title = "About · mevebu";
879
981
  return el(
880
982
  "div",
881
983
  { class: PAGE_NARROW },
882
- el("h1", { class: LEAD }, "About mevebu"),
883
- el("p", { class: LEDE },
884
- `mevebu is ${TOOLS.length} small tools that run in your browser. Each one has its own page and does a single job.`),
984
+ el("div", { class: "flex items-start gap-4" },
985
+ el("img", { class: "mt-1 block size-14 flex-none", src: "./assets/logo.png", alt: "", width: "56", height: "56" }),
986
+ el("div", { class: "min-w-0" },
987
+ el("h1", { class: H1 }, "About mevebu"),
988
+ el("p", { class: SUB },
989
+ "mevebu is a GitHub organization that builds small tools for the browser. Every tool runs on your device, with no account and nothing to upload."))),
990
+
991
+ el("div", { class: "mt-7 grid grid-cols-2 gap-2.5 sm:grid-cols-4" },
992
+ stat(String(TOOLS.length), "Tools"),
993
+ stat(String(CATEGORIES.length), "Categories"),
994
+ stat("2", "Repositories"),
995
+ stat("MIT", "License")),
996
+
997
+ block("The organization",
998
+ el("p", { class: "m-0 leading-[1.65] text-ink-2" },
999
+ "Everything sits under ", el("a", { class: TEXT_LINK, href: ORG_URL, target: "_blank", rel: "noopener" }, "github.com/mevebu"),
1000
+ ". The organization holds two repositories: Mevebu, the toolbox you are using right now, and Waitsec, a set of guardrails for coding agents.")),
1001
+
1002
+ block("The repositories",
1003
+ el("div", { class: "grid gap-2.5 sm:grid-cols-2" },
1004
+ repoCard("Mevebu", `${TOOLS.length} browser tools in one static folder. No build step on your machine, no server behind it.`, REPO_URL),
1005
+ repoCard("Waitsec", "Guardrails for coding agents: stop first, think first, and write less code.", WAITSEC_URL))),
1006
+
1007
+ block("The creator",
1008
+ el("p", { class: "m-0 leading-[1.65] text-ink-2" },
1009
+ el("strong", { class: "font-semibold text-ink" }, CREATOR.name),
1010
+ " designs, builds and maintains both repositories. Follow the work on Instagram or Threads."),
1011
+ el("div", { class: "flex flex-wrap gap-2" }, ...CREATOR_SOCIALS.map(creatorLink))),
885
1012
 
886
1013
  block("Running it",
887
1014
  el("p", {}, "Install it once from npm. The command starts a local server and opens your browser at the address it prints."),
@@ -892,7 +1019,7 @@ function aboutPage() {
892
1019
  el("p", {}, "Add one object to ", el("code", { class: CODE }, "mevebu/libs/js/registry.js"), " and one file in ", el("code", { class: CODE }, "mevebu/libs/js/tools/"), ". The home page, the index, the categories, search and the route all come from that entry.")),
893
1020
 
894
1021
  block("Built with",
895
- el("p", {}, "Hand written HTML, CSS and JavaScript, with Tailwind for the stylesheet. Icons are Lucide and the QR decoder is jsQR."),
1022
+ el("p", {}, "Hand written HTML, CSS and JavaScript, with Tailwind for the stylesheet. The scientific calculator runs on mathjs, icons are Lucide, brand marks are Simple Icons, and the QR decoder is jsQR."),
896
1023
  el("p", {}, "Source and issues: ",
897
1024
  el("a", { class: TEXT_LINK, href: REPO_URL, target: "_blank", rel: "noopener" }, "github.com/mevebu/mevebu")),
898
1025
  el("p", {}, copyButton(() => location.href, "Copy this page link")))
@@ -13,6 +13,10 @@
13
13
  --text-lg--line-height: 1.35;
14
14
  --text-xl: 22px;
15
15
  --text-xl--line-height: 1.3;
16
+ --text-2xl: 1.5rem;
17
+ --text-2xl--line-height: calc(2 / 1.5);
18
+ --text-3xl: 1.875rem;
19
+ --text-3xl--line-height: calc(2.25 / 1.875);
16
20
  --font-weight-medium: 500;
17
21
  --font-weight-semibold: 600;
18
22
  --font-weight-bold: 700;
@@ -193,6 +197,9 @@
193
197
  .collapse {
194
198
  visibility: collapse;
195
199
  }
200
+ .invisible {
201
+ visibility: hidden;
202
+ }
196
203
  .visible {
197
204
  visibility: visible;
198
205
  }
@@ -244,6 +251,9 @@
244
251
  .z-90 {
245
252
  z-index: 90;
246
253
  }
254
+ .col-span-2 {
255
+ grid-column: span 2 / span 2;
256
+ }
247
257
  .container {
248
258
  width: 100%;
249
259
  @media (width >= 40rem) {
@@ -316,6 +326,9 @@
316
326
  .mt-5 {
317
327
  margin-top: calc(var(--spacing) * 5);
318
328
  }
329
+ .mt-7 {
330
+ margin-top: calc(var(--spacing) * 7);
331
+ }
319
332
  .mt-8 {
320
333
  margin-top: calc(var(--spacing) * 8);
321
334
  }
@@ -361,6 +374,9 @@
361
374
  .block {
362
375
  display: block;
363
376
  }
377
+ .contents {
378
+ display: contents;
379
+ }
364
380
  .flex {
365
381
  display: flex;
366
382
  }
@@ -379,13 +395,28 @@
379
395
  .table {
380
396
  display: table;
381
397
  }
398
+ .table-cell {
399
+ display: table-cell;
400
+ }
382
401
  .aspect-\[4\/3\] {
383
402
  aspect-ratio: 4/3;
384
403
  }
404
+ .size-3 {
405
+ width: calc(var(--spacing) * 3);
406
+ height: calc(var(--spacing) * 3);
407
+ }
408
+ .size-3\.5 {
409
+ width: calc(var(--spacing) * 3.5);
410
+ height: calc(var(--spacing) * 3.5);
411
+ }
385
412
  .size-4 {
386
413
  width: calc(var(--spacing) * 4);
387
414
  height: calc(var(--spacing) * 4);
388
415
  }
416
+ .size-5 {
417
+ width: calc(var(--spacing) * 5);
418
+ height: calc(var(--spacing) * 5);
419
+ }
389
420
  .size-6 {
390
421
  width: calc(var(--spacing) * 6);
391
422
  height: calc(var(--spacing) * 6);
@@ -402,6 +433,14 @@
402
433
  width: calc(var(--spacing) * 11);
403
434
  height: calc(var(--spacing) * 11);
404
435
  }
436
+ .size-14 {
437
+ width: calc(var(--spacing) * 14);
438
+ height: calc(var(--spacing) * 14);
439
+ }
440
+ .size-16 {
441
+ width: calc(var(--spacing) * 16);
442
+ height: calc(var(--spacing) * 16);
443
+ }
405
444
  .size-32 {
406
445
  width: calc(var(--spacing) * 32);
407
446
  height: calc(var(--spacing) * 32);
@@ -410,6 +449,10 @@
410
449
  width: 15px;
411
450
  height: 15px;
412
451
  }
452
+ .size-\[17px\] {
453
+ width: 17px;
454
+ height: 17px;
455
+ }
413
456
  .size-\[18px\] {
414
457
  width: 18px;
415
458
  height: 18px;
@@ -476,6 +519,9 @@
476
519
  .h-full {
477
520
  height: 100%;
478
521
  }
522
+ .h-px {
523
+ height: 1px;
524
+ }
479
525
  .max-h-80 {
480
526
  max-height: calc(var(--spacing) * 80);
481
527
  }
@@ -494,6 +540,9 @@
494
540
  .min-h-7 {
495
541
  min-height: calc(var(--spacing) * 7);
496
542
  }
543
+ .min-h-8 {
544
+ min-height: calc(var(--spacing) * 8);
545
+ }
497
546
  .min-h-11 {
498
547
  min-height: calc(var(--spacing) * 11);
499
548
  }
@@ -503,9 +552,15 @@
503
552
  .min-h-40 {
504
553
  min-height: calc(var(--spacing) * 40);
505
554
  }
555
+ .min-h-\[1\.2em\] {
556
+ min-height: 1.2em;
557
+ }
506
558
  .min-h-\[22px\] {
507
559
  min-height: 22px;
508
560
  }
561
+ .min-h-\[56px\] {
562
+ min-height: 56px;
563
+ }
509
564
  .min-h-\[120px\] {
510
565
  min-height: 120px;
511
566
  }
@@ -575,6 +630,9 @@
575
630
  .max-w-\[62ch\] {
576
631
  max-width: 62ch;
577
632
  }
633
+ .max-w-\[64ch\] {
634
+ max-width: 64ch;
635
+ }
578
636
  .max-w-\[340px\] {
579
637
  max-width: 340px;
580
638
  }
@@ -641,9 +699,15 @@
641
699
  .\[grid-template-columns\:88px_minmax\(0\,1fr\)_62px\] {
642
700
  grid-template-columns: 88px minmax(0,1fr) 62px;
643
701
  }
702
+ .\[grid-template-columns\:minmax\(0\,1fr\)_auto\] {
703
+ grid-template-columns: minmax(0,1fr) auto;
704
+ }
644
705
  .\[grid-template-columns\:minmax\(90px\,34\%\)_minmax\(0\,1fr\)\] {
645
706
  grid-template-columns: minmax(90px,34%) minmax(0,1fr);
646
707
  }
708
+ .\[grid-template-columns\:repeat\(auto-fill\,minmax\(92px\,1fr\)\)\] {
709
+ grid-template-columns: repeat(auto-fill,minmax(92px,1fr));
710
+ }
647
711
  .\[grid-template-columns\:repeat\(auto-fill\,minmax\(160px\,1fr\)\)\] {
648
712
  grid-template-columns: repeat(auto-fill,minmax(160px,1fr));
649
713
  }
@@ -659,6 +723,9 @@
659
723
  .grid-cols-2 {
660
724
  grid-template-columns: repeat(2, minmax(0, 1fr));
661
725
  }
726
+ .grid-cols-4 {
727
+ grid-template-columns: repeat(4, minmax(0, 1fr));
728
+ }
662
729
  .grid-cols-\[minmax\(0\,1fr\)_auto\] {
663
730
  grid-template-columns: minmax(0,1fr) auto;
664
731
  }
@@ -957,9 +1024,15 @@
957
1024
  .p-2 {
958
1025
  padding: calc(var(--spacing) * 2);
959
1026
  }
1027
+ .p-2\.5 {
1028
+ padding: calc(var(--spacing) * 2.5);
1029
+ }
960
1030
  .p-3\.5 {
961
1031
  padding: calc(var(--spacing) * 3.5);
962
1032
  }
1033
+ .p-4 {
1034
+ padding: calc(var(--spacing) * 4);
1035
+ }
963
1036
  .p-5 {
964
1037
  padding: calc(var(--spacing) * 5);
965
1038
  }
@@ -981,6 +1054,12 @@
981
1054
  .p-\[var\(--card-pad\)\] {
982
1055
  padding: var(--card-pad);
983
1056
  }
1057
+ .px-0 {
1058
+ padding-inline: 0px;
1059
+ }
1060
+ .px-1 {
1061
+ padding-inline: var(--spacing);
1062
+ }
984
1063
  .px-2 {
985
1064
  padding-inline: calc(var(--spacing) * 2);
986
1065
  }
@@ -1149,10 +1228,18 @@
1149
1228
  .font-sans {
1150
1229
  font-family: var(--sans);
1151
1230
  }
1231
+ .text-2xl {
1232
+ font-size: var(--text-2xl);
1233
+ line-height: var(--tw-leading, var(--text-2xl--line-height));
1234
+ }
1152
1235
  .text-2xs {
1153
1236
  font-size: var(--text-2xs);
1154
1237
  line-height: var(--tw-leading, var(--text-2xs--line-height));
1155
1238
  }
1239
+ .text-3xl {
1240
+ font-size: var(--text-3xl);
1241
+ line-height: var(--tw-leading, var(--text-3xl--line-height));
1242
+ }
1156
1243
  .text-base {
1157
1244
  font-size: var(--text-base);
1158
1245
  line-height: var(--tw-leading, var(--text-base--line-height));
@@ -1192,14 +1279,29 @@
1192
1279
  .text-\[0\.92em\] {
1193
1280
  font-size: 0.92em;
1194
1281
  }
1282
+ .text-\[clamp\(34px\,6vw\,52px\)\] {
1283
+ font-size: clamp(34px, 6vw, 52px);
1284
+ }
1195
1285
  .leading-\[1\.5\] {
1196
1286
  --tw-leading: 1.5;
1197
1287
  line-height: 1.5;
1198
1288
  }
1289
+ .leading-\[1\.6\] {
1290
+ --tw-leading: 1.6;
1291
+ line-height: 1.6;
1292
+ }
1199
1293
  .leading-\[1\.45\] {
1200
1294
  --tw-leading: 1.45;
1201
1295
  line-height: 1.45;
1202
1296
  }
1297
+ .leading-\[1\.55\] {
1298
+ --tw-leading: 1.55;
1299
+ line-height: 1.55;
1300
+ }
1301
+ .leading-\[1\.65\] {
1302
+ --tw-leading: 1.65;
1303
+ line-height: 1.65;
1304
+ }
1203
1305
  .leading-normal {
1204
1306
  --tw-leading: var(--leading-normal);
1205
1307
  line-height: var(--leading-normal);
@@ -1224,6 +1326,10 @@
1224
1326
  --tw-tracking: -0.02em;
1225
1327
  letter-spacing: -0.02em;
1226
1328
  }
1329
+ .tracking-\[-0\.03em\] {
1330
+ --tw-tracking: -0.03em;
1331
+ letter-spacing: -0.03em;
1332
+ }
1227
1333
  .tracking-\[-0\.025em\] {
1228
1334
  --tw-tracking: -0.025em;
1229
1335
  letter-spacing: -0.025em;
@@ -1232,6 +1338,10 @@
1232
1338
  --tw-tracking: -0.035em;
1233
1339
  letter-spacing: -0.035em;
1234
1340
  }
1341
+ .tracking-\[0\.06em\] {
1342
+ --tw-tracking: 0.06em;
1343
+ letter-spacing: 0.06em;
1344
+ }
1235
1345
  .tracking-\[0\.08em\] {
1236
1346
  --tw-tracking: 0.08em;
1237
1347
  letter-spacing: 0.08em;
@@ -1290,13 +1400,25 @@
1290
1400
  .uppercase {
1291
1401
  text-transform: uppercase;
1292
1402
  }
1403
+ .italic {
1404
+ font-style: italic;
1405
+ }
1293
1406
  .tabular-nums {
1294
1407
  --tw-numeric-spacing: tabular-nums;
1295
1408
  font-variant-numeric: var(--tw-ordinal,) var(--tw-slashed-zero,) var(--tw-numeric-figure,) var(--tw-numeric-spacing,) var(--tw-numeric-fraction,);
1296
1409
  }
1410
+ .line-through {
1411
+ text-decoration-line: line-through;
1412
+ }
1297
1413
  .no-underline {
1298
1414
  text-decoration-line: none;
1299
1415
  }
1416
+ .overline {
1417
+ text-decoration-line: overline;
1418
+ }
1419
+ .underline {
1420
+ text-decoration-line: underline;
1421
+ }
1300
1422
  .underline-offset-\[3px\] {
1301
1423
  text-underline-offset: 3px;
1302
1424
  }
@@ -1353,6 +1475,10 @@
1353
1475
  --tw-blur: blur(8px);
1354
1476
  filter: var(--tw-blur,) var(--tw-brightness,) var(--tw-contrast,) var(--tw-grayscale,) var(--tw-hue-rotate,) var(--tw-invert,) var(--tw-saturate,) var(--tw-sepia,) var(--tw-drop-shadow,);
1355
1477
  }
1478
+ .grayscale {
1479
+ --tw-grayscale: grayscale(100%);
1480
+ filter: var(--tw-blur,) var(--tw-brightness,) var(--tw-contrast,) var(--tw-grayscale,) var(--tw-hue-rotate,) var(--tw-invert,) var(--tw-saturate,) var(--tw-sepia,) var(--tw-drop-shadow,);
1481
+ }
1356
1482
  .invert {
1357
1483
  --tw-invert: invert(100%);
1358
1484
  filter: var(--tw-blur,) var(--tw-brightness,) var(--tw-contrast,) var(--tw-grayscale,) var(--tw-hue-rotate,) var(--tw-invert,) var(--tw-saturate,) var(--tw-sepia,) var(--tw-drop-shadow,);
@@ -1431,6 +1557,9 @@
1431
1557
  .\[image-rendering\:pixelated\] {
1432
1558
  image-rendering: pixelated;
1433
1559
  }
1560
+ .\[start\:end\] {
1561
+ start: end;
1562
+ }
1434
1563
  .group-data-\[on\]\:text-ink:is(:where(.group)[data-on] *) {
1435
1564
  color: var(--ink);
1436
1565
  }
@@ -1467,6 +1596,13 @@
1467
1596
  .focus-within\:border-jade:focus-within {
1468
1597
  border-color: var(--jade);
1469
1598
  }
1599
+ .focus-within\:ring-3:focus-within {
1600
+ --tw-ring-shadow: var(--tw-ring-inset,) 0 0 0 calc(3px + var(--tw-ring-offset-width)) var(--tw-ring-color, currentcolor);
1601
+ box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);
1602
+ }
1603
+ .focus-within\:ring-jade-soft:focus-within {
1604
+ --tw-ring-color: var(--jade-soft);
1605
+ }
1470
1606
  @media (hover: hover) {
1471
1607
  .hover\:border-danger:hover {
1472
1608
  border-color: var(--danger);
@@ -1525,6 +1661,10 @@
1525
1661
  .focus\:border-jade:focus {
1526
1662
  border-color: var(--jade);
1527
1663
  }
1664
+ .focus\:ring-0:focus {
1665
+ --tw-ring-shadow: var(--tw-ring-inset,) 0 0 0 calc(0px + var(--tw-ring-offset-width)) var(--tw-ring-color, currentcolor);
1666
+ box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);
1667
+ }
1528
1668
  .focus\:ring-3:focus {
1529
1669
  --tw-ring-shadow: var(--tw-ring-inset,) 0 0 0 calc(3px + var(--tw-ring-offset-width)) var(--tw-ring-color, currentcolor);
1530
1670
  box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);
@@ -1696,6 +1836,9 @@
1696
1836
  .sm\:grid-cols-2 {
1697
1837
  grid-template-columns: repeat(2, minmax(0, 1fr));
1698
1838
  }
1839
+ .sm\:grid-cols-4 {
1840
+ grid-template-columns: repeat(4, minmax(0, 1fr));
1841
+ }
1699
1842
  }
1700
1843
  @media (width >= 45rem) {
1701
1844
  .min-\[45rem\]\:flex {
@@ -750,7 +750,7 @@ export function blank(iconName, text) {
750
750
  // ---------- version ----------
751
751
 
752
752
  // Kept in one place. The CLI reads the same value from package.json.
753
- export const VERSION = "1.8.1";
753
+ export const VERSION = "1.10.0";
754
754
  export const PACKAGE_NAME = "mevebu";
755
755
  export const REPO_SLUG = "mevebu/mevebu";
756
756
 
@@ -1,5 +1,5 @@
1
1
  // GENERATED FILE, DO NOT EDIT.
2
- // Source: lucide v1.59.0 (ISC), icons/174 names from scripts/vendor-icons.mjs
2
+ // Source: lucide v1.57.0 (ISC), icons/174 names from scripts/vendor-icons.mjs
3
3
  // Regenerate with: npm run icons
4
4
 
5
5
  const D = {
@@ -44,6 +44,7 @@ const D = {
44
44
  "rotate-cw": [ ["path", { d: "M21 12a9 9 0 1 1-9-9c2.52 0 4.93 1 6.74 2.74L21 8" }], ["path", { d: "M21 3v5h-5" }] ],
45
45
  "download": [ ["path", { d: "M12 15V3" }], ["path", { d: "M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4" }], ["path", { d: "m7 10 5 5 5-5" }] ],
46
46
  "upload": [ ["path", { d: "M12 3v12" }], ["path", { d: "m17 8-5-5-5 5" }], ["path", { d: "M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4" }] ],
47
+ "delete": [ [ "path", { d: "M10 5a2 2 0 0 0-1.344.519l-6.328 5.74a1 1 0 0 0 0 1.481l6.328 5.741A2 2 0 0 0 10 19h10a2 2 0 0 0 2-2V7a2 2 0 0 0-2-2z" } ], ["path", { d: "m12 9 6 6" }], ["path", { d: "m18 9-6 6" }] ],
47
48
  "arrow-left-right": [ ["path", { d: "M8 3 4 7l4 4" }], ["path", { d: "M4 7h16" }], ["path", { d: "m16 21 4-4-4-4" }], ["path", { d: "M20 17H4" }] ],
48
49
  "trash": [ ["path", { d: "M10 11v6" }], ["path", { d: "M14 11v6" }], ["path", { d: "M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6" }], ["path", { d: "M3 6h18" }], ["path", { d: "M8 6V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2" }] ],
49
50
  "plus": [ ["path", { d: "M5 12h14" }], ["path", { d: "M12 5v14" }] ],
@@ -166,7 +167,6 @@ const D = {
166
167
  "receipt": [ ["path", { d: "M12 17V7" }], ["path", { d: "M16 8h-6a2 2 0 0 0 0 4h4a2 2 0 0 1 0 4H8" }], [ "path", { d: "M4 3a1 1 0 0 1 1-1 1.3 1.3 0 0 1 .7.2l.933.6a1.3 1.3 0 0 0 1.4 0l.934-.6a1.3 1.3 0 0 1 1.4 0l.933.6a1.3 1.3 0 0 0 1.4 0l.933-.6a1.3 1.3 0 0 1 1.4 0l.934.6a1.3 1.3 0 0 0 1.4 0l.933-.6A1.3 1.3 0 0 1 19 2a1 1 0 0 1 1 1v18a1 1 0 0 1-1 1 1.3 1.3 0 0 1-.7-.2l-.933-.6a1.3 1.3 0 0 0-1.4 0l-.934.6a1.3 1.3 0 0 1-1.4 0l-.933-.6a1.3 1.3 0 0 0-1.4 0l-.933.6a1.3 1.3 0 0 1-1.4 0l-.934-.6a1.3 1.3 0 0 0-1.4 0l-.933.6a1.3 1.3 0 0 1-.7.2 1 1 0 0 1-1-1z" } ] ],
167
168
  "banknote": [ ["rect", { width: "20", height: "12", x: "2", y: "6", rx: "2" }], ["circle", { cx: "12", cy: "12", r: "2" }], ["path", { d: "M6 12h.01M18 12h.01" }] ],
168
169
  "package": [ [ "path", { d: "M11 21.73a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16V8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73z" } ], ["path", { d: "M12 22V12" }], ["polyline", { points: "3.29 7 12 12 20.71 7" }], ["path", { d: "m7.5 4.27 9 5.15" }] ],
169
- "film": [ ["rect", { width: "18", height: "18", x: "3", y: "3", rx: "2" }], ["path", { d: "M7 3v18" }], ["path", { d: "M3 7.5h4" }], ["path", { d: "M3 12h18" }], ["path", { d: "M3 16.5h4" }], ["path", { d: "M17 3v18" }], ["path", { d: "M17 7.5h4" }], ["path", { d: "M17 16.5h4" }] ],
170
170
  "video": [ ["path", { d: "m16 13 5.223 3.482a.5.5 0 0 0 .777-.416V7.87a.5.5 0 0 0-.752-.432L16 10.5" }], ["rect", { x: "2", y: "6", width: "14", height: "12", rx: "2" }] ],
171
171
  "git-pull-request": [ ["circle", { cx: "18", cy: "18", r: "3" }], ["circle", { cx: "6", cy: "6", r: "3" }], ["path", { d: "M13 6h3a2 2 0 0 1 2 2v7" }], ["line", { x1: "6", x2: "6", y1: "9", y2: "21" }] ],
172
172
  "weight": [ ["circle", { cx: "12", cy: "5", r: "3" }], [ "path", { d: "M6.5 8a2 2 0 0 0-1.905 1.46L2.1 18.5A2 2 0 0 0 4 21h16a2 2 0 0 0 1.925-2.54L19.4 9.5A2 2 0 0 0 17.48 8Z" } ] ],