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.
- package/mevebu/app/mevebu.js +260 -208
- package/mevebu/app/tailwind.css +1639 -2077
- package/mevebu/app/tailwind.src.css +155 -1120
- package/mevebu/index.html +2 -2
- package/mevebu/libs/js/core.js +236 -96
- package/mevebu/libs/js/registry.js +11 -11
- package/mevebu/libs/js/tools/abstract-checklist.js +5 -7
- package/mevebu/libs/js/tools/add-subtract-days.js +9 -11
- package/mevebu/libs/js/tools/age-calculator.js +7 -8
- package/mevebu/libs/js/tools/api-request-builder.js +3 -4
- package/mevebu/libs/js/tools/area-converter.js +7 -9
- package/mevebu/libs/js/tools/aspect-ratio.js +8 -9
- package/mevebu/libs/js/tools/average-calculator.js +4 -5
- package/mevebu/libs/js/tools/base64.js +31 -11
- package/mevebu/libs/js/tools/binary-calculator.js +6 -7
- package/mevebu/libs/js/tools/border-radius.js +7 -9
- package/mevebu/libs/js/tools/box-shadow.js +6 -7
- package/mevebu/libs/js/tools/break-even.js +4 -5
- package/mevebu/libs/js/tools/business-days.js +7 -8
- package/mevebu/libs/js/tools/canonical-tag.js +5 -6
- package/mevebu/libs/js/tools/caption-counter.js +5 -7
- package/mevebu/libs/js/tools/case-converter.js +11 -12
- package/mevebu/libs/js/tools/case-inspector.js +14 -16
- package/mevebu/libs/js/tools/cash-denomination.js +7 -8
- package/mevebu/libs/js/tools/cash-flow.js +7 -8
- package/mevebu/libs/js/tools/cert-expiry.js +6 -10
- package/mevebu/libs/js/tools/changelog-generator.js +4 -6
- package/mevebu/libs/js/tools/character-counter.js +10 -13
- package/mevebu/libs/js/tools/checklist.js +6 -7
- package/mevebu/libs/js/tools/citation-number-check.js +10 -13
- package/mevebu/libs/js/tools/coin-flip.js +9 -11
- package/mevebu/libs/js/tools/color-converter.js +23 -17
- package/mevebu/libs/js/tools/color-palette.js +6 -8
- package/mevebu/libs/js/tools/color-picker.js +4 -5
- package/mevebu/libs/js/tools/content-calendar.js +3 -4
- package/mevebu/libs/js/tools/contrast-checker.js +5 -6
- package/mevebu/libs/js/tools/cron-builder.js +4 -6
- package/mevebu/libs/js/tools/css-clamp.js +5 -6
- package/mevebu/libs/js/tools/css-formatter.js +4 -7
- package/mevebu/libs/js/tools/css-grid.js +6 -7
- package/mevebu/libs/js/tools/css-minifier.js +5 -8
- package/mevebu/libs/js/tools/csv-to-json.js +2 -3
- package/mevebu/libs/js/tools/csv-viewer.js +9 -11
- package/mevebu/libs/js/tools/currency-format.js +5 -7
- package/mevebu/libs/js/tools/daily-planner.js +9 -10
- package/mevebu/libs/js/tools/data-masker.js +7 -9
- package/mevebu/libs/js/tools/data-storage.js +7 -9
- package/mevebu/libs/js/tools/data-validator.js +9 -11
- package/mevebu/libs/js/tools/date-difference.js +6 -7
- package/mevebu/libs/js/tools/date-format.js +11 -13
- package/mevebu/libs/js/tools/delimiter-converter.js +3 -5
- package/mevebu/libs/js/tools/discount-calculator.js +4 -5
- package/mevebu/libs/js/tools/doi-resolver.js +4 -5
- package/mevebu/libs/js/tools/env-formatter.js +3 -6
- package/mevebu/libs/js/tools/equation-formatter.js +5 -9
- package/mevebu/libs/js/tools/expense-split.js +6 -7
- package/mevebu/libs/js/tools/fake-data.js +20 -13
- package/mevebu/libs/js/tools/find-replace.js +3 -5
- package/mevebu/libs/js/tools/flashcard-creator.js +9 -10
- package/mevebu/libs/js/tools/font-pairing.js +6 -8
- package/mevebu/libs/js/tools/fraction-calculator.js +10 -13
- package/mevebu/libs/js/tools/git-command-builder.js +11 -22
- package/mevebu/libs/js/tools/gpa-calculator.js +8 -10
- package/mevebu/libs/js/tools/grade-calculator.js +7 -8
- package/mevebu/libs/js/tools/gradient-generator.js +10 -12
- package/mevebu/libs/js/tools/habit-tracker.js +8 -9
- package/mevebu/libs/js/tools/hash-generator.js +3 -5
- package/mevebu/libs/js/tools/hashtag-formatter.js +6 -8
- package/mevebu/libs/js/tools/hmac-generator.js +3 -5
- package/mevebu/libs/js/tools/hpp-calculator.js +4 -5
- package/mevebu/libs/js/tools/html-entity.js +2 -3
- package/mevebu/libs/js/tools/html-formatter.js +3 -6
- package/mevebu/libs/js/tools/http-status.js +5 -7
- package/mevebu/libs/js/tools/inventory-quantity.js +7 -8
- package/mevebu/libs/js/tools/json-formatter.js +3 -6
- package/mevebu/libs/js/tools/json-minifier.js +5 -8
- package/mevebu/libs/js/tools/json-to-csv.js +3 -5
- package/mevebu/libs/js/tools/json-to-typescript.js +2 -5
- package/mevebu/libs/js/tools/json-validator.js +2 -3
- package/mevebu/libs/js/tools/jwt-decoder.js +6 -7
- package/mevebu/libs/js/tools/jwt-expiry.js +5 -6
- package/mevebu/libs/js/tools/jwt-generator.js +4 -6
- package/mevebu/libs/js/tools/length-converter.js +7 -9
- package/mevebu/libs/js/tools/license-reference.js +10 -13
- package/mevebu/libs/js/tools/line-counter.js +5 -7
- package/mevebu/libs/js/tools/list-difference.js +5 -7
- package/mevebu/libs/js/tools/list-merger.js +4 -5
- package/mevebu/libs/js/tools/locale-number.js +5 -8
- package/mevebu/libs/js/tools/lorem-ipsum.js +4 -2
- package/mevebu/libs/js/tools/markdown-preview.js +5 -8
- package/mevebu/libs/js/tools/markdown-table.js +5 -7
- package/mevebu/libs/js/tools/markup-calculator.js +4 -5
- package/mevebu/libs/js/tools/meeting-agenda.js +8 -9
- package/mevebu/libs/js/tools/meta-preview.js +12 -13
- package/mevebu/libs/js/tools/meta-tags.js +6 -7
- package/mevebu/libs/js/tools/mime-types.js +5 -7
- package/mevebu/libs/js/tools/name-picker.js +2 -3
- package/mevebu/libs/js/tools/number-base-converter.js +9 -12
- package/mevebu/libs/js/tools/password-generator.js +9 -12
- package/mevebu/libs/js/tools/password-strength.js +21 -25
- package/mevebu/libs/js/tools/percent-to-fraction.js +6 -7
- package/mevebu/libs/js/tools/percentage-calculator.js +6 -9
- package/mevebu/libs/js/tools/percentage-change.js +4 -5
- package/mevebu/libs/js/tools/permutation-combination.js +9 -12
- package/mevebu/libs/js/tools/prefix-suffix.js +2 -3
- package/mevebu/libs/js/tools/priority-matrix.js +6 -10
- package/mevebu/libs/js/tools/profit-margin.js +4 -5
- package/mevebu/libs/js/tools/qr-generator.js +3 -4
- package/mevebu/libs/js/tools/qr-scanner.js +11 -12
- package/mevebu/libs/js/tools/quadratic-solver.js +7 -8
- package/mevebu/libs/js/tools/query-builder.js +2 -3
- package/mevebu/libs/js/tools/quiz-formatter.js +4 -6
- package/mevebu/libs/js/tools/ratio-calculator.js +7 -8
- package/mevebu/libs/js/tools/readability.js +12 -15
- package/mevebu/libs/js/tools/reading-time.js +5 -7
- package/mevebu/libs/js/tools/reference-completeness.js +6 -8
- package/mevebu/libs/js/tools/regex-tester.js +7 -10
- package/mevebu/libs/js/tools/remove-duplicate-lines.js +2 -3
- package/mevebu/libs/js/tools/remove-extra-spaces.js +3 -5
- package/mevebu/libs/js/tools/robots-txt.js +3 -4
- package/mevebu/libs/js/tools/roman-numeral-converter.js +6 -8
- package/mevebu/libs/js/tools/sales-commission.js +8 -9
- package/mevebu/libs/js/tools/scientific-calculator.js +10 -14
- package/mevebu/libs/js/tools/scientific-notation.js +8 -9
- package/mevebu/libs/js/tools/script-planner.js +8 -10
- package/mevebu/libs/js/tools/selling-price.js +4 -5
- package/mevebu/libs/js/tools/semver-helper.js +3 -5
- package/mevebu/libs/js/tools/sentence-length.js +9 -10
- package/mevebu/libs/js/tools/sequence-analyzer.js +7 -8
- package/mevebu/libs/js/tools/sitemap-xml.js +4 -7
- package/mevebu/libs/js/tools/slug-converter.js +3 -5
- package/mevebu/libs/js/tools/slug-preview.js +6 -7
- package/mevebu/libs/js/tools/sort-lines.js +3 -5
- package/mevebu/libs/js/tools/speed-converter.js +7 -9
- package/mevebu/libs/js/tools/spin-wheel.js +19 -17
- package/mevebu/libs/js/tools/sql-formatter.js +5 -9
- package/mevebu/libs/js/tools/sql-minifier.js +5 -8
- package/mevebu/libs/js/tools/standard-deviation.js +6 -9
- package/mevebu/libs/js/tools/stopwatch.js +4 -6
- package/mevebu/libs/js/tools/study-schedule.js +8 -9
- package/mevebu/libs/js/tools/subtitle-formatter.js +10 -11
- package/mevebu/libs/js/tools/table-to-markdown.js +8 -12
- package/mevebu/libs/js/tools/tax-calculator.js +4 -5
- package/mevebu/libs/js/tools/temperature-converter.js +8 -11
- package/mevebu/libs/js/tools/text-diff.js +11 -7
- package/mevebu/libs/js/tools/text-direction.js +3 -5
- package/mevebu/libs/js/tools/text-reverser.js +3 -5
- package/mevebu/libs/js/tools/time-duration.js +8 -9
- package/mevebu/libs/js/tools/timestamp-converter.js +4 -6
- package/mevebu/libs/js/tools/timezone-converter.js +9 -13
- package/mevebu/libs/js/tools/title-length.js +6 -7
- package/mevebu/libs/js/tools/unicode-inspector.js +4 -5
- package/mevebu/libs/js/tools/url-encoder.js +4 -2
- package/mevebu/libs/js/tools/url-inspector.js +9 -11
- package/mevebu/libs/js/tools/url-parser.js +12 -13
- package/mevebu/libs/js/tools/utf8-bytes.js +6 -9
- package/mevebu/libs/js/tools/uuid-generator.js +107 -15
- package/mevebu/libs/js/tools/version-compare.js +3 -4
- package/mevebu/libs/js/tools/video-duration.js +5 -7
- package/mevebu/libs/js/tools/volume-converter.js +7 -9
- package/mevebu/libs/js/tools/weekly-planner.js +8 -10
- package/mevebu/libs/js/tools/weight-converter.js +7 -9
- package/mevebu/libs/js/tools/weighted-average.js +4 -5
- package/mevebu/libs/js/tools/word-counter.js +10 -13
- package/mevebu/libs/js/tools/word-limit.js +4 -5
- package/mevebu/libs/js/tools/yaml-formatter.js +6 -7
- package/package.json +1 -1
|
@@ -1,162 +1,201 @@
|
|
|
1
|
-
/* mevebu styles
|
|
1
|
+
/* mevebu styles.
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
3
|
+
Everything you see is a Tailwind utility written where the element is built:
|
|
4
|
+
either in mevebu/app/mevebu.js for the shell, in mevebu/libs/js/core.js for the
|
|
5
|
+
controls every tool shares, or in a tool file for a one-off. This file holds
|
|
6
|
+
only what a utility cannot express: the tokens, the type scale, and four
|
|
7
|
+
element level rules (see "base" below). There is no component layer and no
|
|
8
|
+
class of our own, so a control is styled in exactly one place in the markup.
|
|
6
9
|
|
|
7
10
|
Source of truth: this file.
|
|
8
11
|
Built output: mevebu/app/tailwind.css (committed, never edit by hand)
|
|
9
12
|
Rebuild: npm run css
|
|
13
|
+
Pinned values: DESIGN.md section 3, so this file and the doc never disagree.
|
|
10
14
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
3. Phone first. Two columns arrive at 60rem, never before.
|
|
20
|
-
4. Dark mode is a real theme, not the light theme inverted.
|
|
21
|
-
5. You type into a raised surface and read results on a recessed one. */
|
|
15
|
+
The four rules this design is opinionated about:
|
|
16
|
+
1. One control height. Every button, field, select, chip and switch is
|
|
17
|
+
--ctl tall, so a row of them lines up on the pixel.
|
|
18
|
+
2. Six text sizes and three display sizes. Nothing in between.
|
|
19
|
+
3. Green is the only accent, and it carries exactly one meaning: the thing to
|
|
20
|
+
press next. Everything else is a surface, a line or ink.
|
|
21
|
+
4. Results are never the same surface as inputs. You type on deck, you read on
|
|
22
|
+
deck-2. */
|
|
22
23
|
|
|
23
24
|
@import "tailwindcss" source(none);
|
|
24
25
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
@source "
|
|
26
|
+
/* Paths are relative to this file, and every class in the app lives in one of
|
|
27
|
+
these three places. Nothing scans a file that is not listed here. */
|
|
28
|
+
@source "../index.html";
|
|
29
|
+
@source "./";
|
|
30
|
+
@source "../libs/js";
|
|
28
31
|
|
|
29
32
|
/* The app switches theme with <html data-theme>, so dark: follows that attribute. */
|
|
30
33
|
@custom-variant dark (&:where([data-theme="dark"], [data-theme="dark"] *));
|
|
31
34
|
|
|
32
|
-
/* ---------- tokens ----------
|
|
35
|
+
/* ---------- tokens ----------
|
|
36
|
+
Three scales, one meaning each. Nothing below this block hardcodes a value. */
|
|
33
37
|
|
|
38
|
+
/* Light is the same jade seen in daylight: white deck, ink text, the mark still there. */
|
|
34
39
|
:root {
|
|
35
|
-
--
|
|
36
|
-
--
|
|
37
|
-
--
|
|
38
|
-
--
|
|
39
|
-
--
|
|
40
|
-
--
|
|
41
|
-
--
|
|
42
|
-
--
|
|
43
|
-
--
|
|
44
|
-
--
|
|
45
|
-
--
|
|
46
|
-
--
|
|
47
|
-
--
|
|
48
|
-
--
|
|
49
|
-
--
|
|
50
|
-
--
|
|
51
|
-
--
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
--
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
--
|
|
59
|
-
--
|
|
60
|
-
--
|
|
61
|
-
|
|
62
|
-
--
|
|
63
|
-
--
|
|
64
|
-
|
|
65
|
-
--
|
|
66
|
-
|
|
40
|
+
--void: #eef1ed;
|
|
41
|
+
--deck: #ffffff;
|
|
42
|
+
--deck-2: #f2f5f1;
|
|
43
|
+
--ink: #101a15;
|
|
44
|
+
--ink-2: #46574d;
|
|
45
|
+
--ink-3: #5c6d61;
|
|
46
|
+
--orbit: #dce2dc;
|
|
47
|
+
--orbit-hard: #bfcac1;
|
|
48
|
+
--jade: #0f6b4a;
|
|
49
|
+
--jade-deep: #0a5138;
|
|
50
|
+
--on-jade: #ffffff;
|
|
51
|
+
--jade-soft: #e0f0e7;
|
|
52
|
+
--danger: #b0231d;
|
|
53
|
+
--star: #b37700;
|
|
54
|
+
--track: #bfcac1;
|
|
55
|
+
--scrim: rgb(8 14 11 / 0.5);
|
|
56
|
+
--shadow: 0 18px 44px -18px rgb(9 22 15 / 0.35);
|
|
57
|
+
|
|
58
|
+
/* Line tints for the diff tool. Derived here, so the dark theme gets its own
|
|
59
|
+
by re-declaring --jade, --danger and --deck, with no second rule. */
|
|
60
|
+
--add: color-mix(in srgb, var(--jade) 14%, var(--deck));
|
|
61
|
+
--del: color-mix(in srgb, var(--danger) 12%, var(--deck));
|
|
62
|
+
|
|
63
|
+
--r1: 10px;
|
|
64
|
+
--r2: 16px;
|
|
65
|
+
--r3: 24px;
|
|
66
|
+
|
|
67
|
+
--margin: clamp(20px, 5vw, 44px);
|
|
68
|
+
--gutter: clamp(14px, 2vw, 24px);
|
|
69
|
+
--bench: 1120px;
|
|
70
|
+
--bar: 60px;
|
|
71
|
+
|
|
72
|
+
/* One control height for the whole app, raised to 44px on a phone at the
|
|
73
|
+
bottom of this file, so nothing repeats the number. */
|
|
74
|
+
--ctl: 40px;
|
|
75
|
+
--card-pad: clamp(20px, 3vw, 32px);
|
|
76
|
+
--band-pad: clamp(12px, 2vw, 16px);
|
|
77
|
+
|
|
78
|
+
--sans: ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
|
|
79
|
+
--mono: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;
|
|
80
|
+
|
|
81
|
+
--t: 150ms;
|
|
82
|
+
--ease: cubic-bezier(0.22, 0.9, 0.28, 1);
|
|
67
83
|
|
|
68
84
|
/* native controls and the select caret follow the theme through these */
|
|
69
|
-
--
|
|
85
|
+
--caret: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%235c6d61' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><polyline points='6 9 12 15 18 9'/></svg>");
|
|
70
86
|
color-scheme: light;
|
|
71
87
|
}
|
|
72
88
|
|
|
73
89
|
:root[data-theme="dark"] {
|
|
74
|
-
--
|
|
75
|
-
--
|
|
76
|
-
--
|
|
77
|
-
--
|
|
78
|
-
--
|
|
79
|
-
--
|
|
80
|
-
--
|
|
81
|
-
--
|
|
82
|
-
--
|
|
83
|
-
--
|
|
84
|
-
--
|
|
85
|
-
--
|
|
86
|
-
--
|
|
87
|
-
--
|
|
88
|
-
--
|
|
89
|
-
--
|
|
90
|
-
--
|
|
91
|
-
--
|
|
90
|
+
--void: #060d0a;
|
|
91
|
+
--deck: #0c1610;
|
|
92
|
+
--deck-2: #122019;
|
|
93
|
+
--ink: #e7f0ea;
|
|
94
|
+
--ink-2: #a7bbae;
|
|
95
|
+
--ink-3: #85978a;
|
|
96
|
+
--orbit: #1d2c23;
|
|
97
|
+
--orbit-hard: #2b4033;
|
|
98
|
+
--jade: #4ad69a;
|
|
99
|
+
--jade-deep: #6ee6b0;
|
|
100
|
+
--on-jade: #04120b;
|
|
101
|
+
--jade-soft: #10291f;
|
|
102
|
+
--danger: #ff8a80;
|
|
103
|
+
--star: #ffcf4d;
|
|
104
|
+
--track: #2b4033;
|
|
105
|
+
--scrim: rgb(2 6 4 / 0.68);
|
|
106
|
+
--shadow: 0 22px 50px -20px rgb(0 0 0 / 0.7);
|
|
107
|
+
--caret: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%2385978a' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><polyline points='6 9 12 15 18 9'/></svg>");
|
|
92
108
|
color-scheme: dark;
|
|
93
109
|
}
|
|
94
110
|
|
|
95
|
-
/*
|
|
96
|
-
|
|
97
|
-
|
|
111
|
+
/* A finger needs 44px. One override, not twelve. */
|
|
112
|
+
@media (max-width: 45rem) {
|
|
113
|
+
:root { --ctl: 44px; }
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/* The tokens above become utilities: bg-deck, text-ink-2, border-orbit, rounded-r2,
|
|
117
|
+
ring-jade-soft. `inline` keeps them as var() references, so every utility follows
|
|
118
|
+
the theme switch without a second class. */
|
|
98
119
|
@theme inline {
|
|
99
|
-
--color-void: var(--
|
|
100
|
-
--color-deck: var(--
|
|
101
|
-
--color-deck-2: var(--
|
|
102
|
-
--color-ink: var(--
|
|
103
|
-
--color-ink-2: var(--
|
|
104
|
-
--color-ink-3: var(--
|
|
105
|
-
--color-orbit: var(--
|
|
106
|
-
--color-orbit-hard: var(--
|
|
107
|
-
--color-
|
|
108
|
-
--color-
|
|
109
|
-
--color-on-
|
|
110
|
-
--color-
|
|
111
|
-
--color-
|
|
112
|
-
--color-
|
|
113
|
-
--color-
|
|
120
|
+
--color-void: var(--void);
|
|
121
|
+
--color-deck: var(--deck);
|
|
122
|
+
--color-deck-2: var(--deck-2);
|
|
123
|
+
--color-ink: var(--ink);
|
|
124
|
+
--color-ink-2: var(--ink-2);
|
|
125
|
+
--color-ink-3: var(--ink-3);
|
|
126
|
+
--color-orbit: var(--orbit);
|
|
127
|
+
--color-orbit-hard: var(--orbit-hard);
|
|
128
|
+
--color-jade: var(--jade);
|
|
129
|
+
--color-jade-deep: var(--jade-deep);
|
|
130
|
+
--color-on-jade: var(--on-jade);
|
|
131
|
+
--color-jade-soft: var(--jade-soft);
|
|
132
|
+
--color-danger: var(--danger);
|
|
133
|
+
--color-star: var(--star);
|
|
134
|
+
--color-track: var(--track);
|
|
135
|
+
|
|
136
|
+
--radius-r1: var(--r1);
|
|
137
|
+
--radius-r2: var(--r2);
|
|
138
|
+
--radius-r3: var(--r3);
|
|
139
|
+
|
|
140
|
+
--font-sans: var(--sans);
|
|
141
|
+
--font-mono: var(--mono);
|
|
142
|
+
}
|
|
114
143
|
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
144
|
+
/* The type scale. Six text sizes, three display sizes, four weights. A size that
|
|
145
|
+
is not on this list does not exist in the product. */
|
|
146
|
+
@theme {
|
|
147
|
+
--text-2xs: 13px;
|
|
148
|
+
--text-2xs--line-height: 1.45;
|
|
149
|
+
--text-sm: 14px;
|
|
150
|
+
--text-sm--line-height: 1.5;
|
|
151
|
+
--text-base: 16px;
|
|
152
|
+
--text-base--line-height: 1.55;
|
|
153
|
+
--text-md: 17px;
|
|
154
|
+
--text-md--line-height: 1.5;
|
|
155
|
+
--text-lg: 20px;
|
|
156
|
+
--text-lg--line-height: 1.35;
|
|
157
|
+
--text-xl: 22px;
|
|
158
|
+
--text-xl--line-height: 1.3;
|
|
159
|
+
--text-title: clamp(26px, 4vw, 36px);
|
|
160
|
+
--text-title--line-height: 1.1;
|
|
161
|
+
--text-lead: clamp(28px, 5vw, 44px);
|
|
162
|
+
--text-lead--line-height: 1.06;
|
|
163
|
+
--text-hero: clamp(34px, 6vw, 58px);
|
|
164
|
+
--text-hero--line-height: 1.03;
|
|
165
|
+
/* One oversized glyph size, for a single character that fills a shape
|
|
166
|
+
(the coin face). Not for text. */
|
|
167
|
+
--text-display: 44px;
|
|
168
|
+
--text-display--line-height: 1;
|
|
169
|
+
|
|
170
|
+
--animate-toss: toss 450ms ease;
|
|
171
|
+
}
|
|
118
172
|
|
|
119
|
-
|
|
120
|
-
|
|
173
|
+
@keyframes toss {
|
|
174
|
+
0% { transform: scale(1) rotate(0deg); }
|
|
175
|
+
50% { transform: scale(1.12) rotate(180deg); }
|
|
176
|
+
100% { transform: scale(1) rotate(360deg); }
|
|
121
177
|
}
|
|
122
178
|
|
|
123
|
-
/* ---------- base ----------
|
|
179
|
+
/* ---------- base ----------
|
|
180
|
+
Four element rules, and no more. Preflight already resets type, lists, controls
|
|
181
|
+
and media, so everything here is a decision preflight cannot make. */
|
|
124
182
|
|
|
125
183
|
@layer base {
|
|
126
184
|
html {
|
|
127
185
|
-webkit-text-size-adjust: 100%;
|
|
128
186
|
}
|
|
129
187
|
|
|
130
|
-
body {
|
|
131
|
-
margin: 0;
|
|
132
|
-
min-height: 100dvh;
|
|
133
|
-
display: flex;
|
|
134
|
-
flex-direction: column;
|
|
135
|
-
background: var(--mvb-void);
|
|
136
|
-
color: var(--mvb-ink);
|
|
137
|
-
font-family: var(--mvb-sans);
|
|
138
|
-
font-size: 16px;
|
|
139
|
-
line-height: 1.55;
|
|
140
|
-
-webkit-font-smoothing: antialiased;
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
h1, h2, h3, h4, h5, h6, p, ul, ol, pre, figure { margin: 0; }
|
|
144
|
-
ul, ol { list-style: none; padding: 0; }
|
|
145
|
-
button, input, textarea, select { font: inherit; color: inherit; }
|
|
146
|
-
a { color: inherit; }
|
|
147
|
-
img, svg, canvas, video { display: block; max-width: 100%; }
|
|
148
|
-
|
|
149
188
|
/* The card head and foot are rendered with a hidden attribute rather than removed,
|
|
150
|
-
and
|
|
189
|
+
and a flex utility would otherwise win over the browser default. */
|
|
151
190
|
[hidden] { display: none !important; }
|
|
152
191
|
|
|
153
192
|
:focus-visible {
|
|
154
|
-
outline: 2px solid var(--
|
|
193
|
+
outline: 2px solid var(--jade);
|
|
155
194
|
outline-offset: 2px;
|
|
156
195
|
border-radius: 6px;
|
|
157
196
|
}
|
|
158
197
|
|
|
159
|
-
::selection { background: var(--
|
|
198
|
+
::selection { background: var(--jade-soft); }
|
|
160
199
|
|
|
161
200
|
@media (prefers-reduced-motion: reduce) {
|
|
162
201
|
*, *::before, *::after {
|
|
@@ -166,1007 +205,3 @@
|
|
|
166
205
|
}
|
|
167
206
|
}
|
|
168
207
|
}
|
|
169
|
-
|
|
170
|
-
@layer components {
|
|
171
|
-
/* ---------- icons ---------- */
|
|
172
|
-
|
|
173
|
-
.mvb-ico { @apply block size-[18px] flex-none; }
|
|
174
|
-
.mvb-ico--lg { @apply size-[26px]; }
|
|
175
|
-
.mvb-ico--sm { @apply size-[15px]; }
|
|
176
|
-
|
|
177
|
-
/* ---------- masthead ---------- */
|
|
178
|
-
|
|
179
|
-
.mvb-bar {
|
|
180
|
-
@apply sticky top-0 z-30 border-b border-orbit;
|
|
181
|
-
background: color-mix(in srgb, var(--mvb-deck) 88%, transparent);
|
|
182
|
-
backdrop-filter: saturate(140%) blur(10px);
|
|
183
|
-
-webkit-backdrop-filter: saturate(140%) blur(10px);
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
.mvb-bar__in {
|
|
187
|
-
height: var(--mvb-bar);
|
|
188
|
-
margin-inline: var(--mvb-margin);
|
|
189
|
-
@apply flex items-center gap-[clamp(14px,3vw,32px)];
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
.mvb-mark {
|
|
193
|
-
@apply inline-flex flex-none items-center gap-2.5 text-lg font-bold tracking-[-0.01em] text-ink no-underline;
|
|
194
|
-
}
|
|
195
|
-
|
|
196
|
-
.mvb-mark img {
|
|
197
|
-
@apply block size-[30px] rounded-[9px];
|
|
198
|
-
box-shadow: 0 0 0 1px var(--mvb-orbit);
|
|
199
|
-
}
|
|
200
|
-
|
|
201
|
-
.mvb-nav {
|
|
202
|
-
@apply ms-auto flex flex-none gap-1 rounded-r2 border border-orbit bg-deck-2 p-1;
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
.mvb-nav__link {
|
|
206
|
-
@apply whitespace-nowrap rounded-lg px-3 py-[7px] text-[0.90625rem] font-semibold text-ink-2 no-underline transition-colors duration-150;
|
|
207
|
-
}
|
|
208
|
-
|
|
209
|
-
.mvb-nav__link:hover {
|
|
210
|
-
@apply bg-ink/6 text-ink;
|
|
211
|
-
}
|
|
212
|
-
|
|
213
|
-
.mvb-nav__link.mvb-on {
|
|
214
|
-
@apply bg-deck text-ink;
|
|
215
|
-
box-shadow: 0 0 0 1px var(--mvb-orbit);
|
|
216
|
-
}
|
|
217
|
-
|
|
218
|
-
.mvb-bar__end { @apply flex items-center gap-0.5; }
|
|
219
|
-
|
|
220
|
-
.mvb-icobtn {
|
|
221
|
-
@apply inline-flex size-10 cursor-pointer items-center justify-center rounded-r1 border border-transparent bg-transparent text-ink-2 transition-colors duration-150;
|
|
222
|
-
}
|
|
223
|
-
|
|
224
|
-
.mvb-icobtn:hover { @apply bg-deck-2 text-ink; }
|
|
225
|
-
.mvb-icobtn:focus-visible { @apply border-comet; }
|
|
226
|
-
|
|
227
|
-
.mvb-bar__menu { @apply hidden; }
|
|
228
|
-
|
|
229
|
-
/* search button that opens the palette */
|
|
230
|
-
|
|
231
|
-
.mvb-searchbtn {
|
|
232
|
-
@apply me-1 inline-flex h-10 min-w-[180px] cursor-pointer items-center gap-2 rounded-r1 border border-orbit bg-deck-2 ps-3 pe-2.5 text-sm font-medium text-ink-2 transition-colors duration-150;
|
|
233
|
-
}
|
|
234
|
-
|
|
235
|
-
.mvb-searchbtn:hover { @apply border-orbit-hard bg-deck text-ink; }
|
|
236
|
-
.mvb-searchbtn:focus-visible { @apply border-comet; }
|
|
237
|
-
.mvb-searchbtn .mvb-ico { @apply size-[15px] text-ink-3; }
|
|
238
|
-
|
|
239
|
-
.mvb-searchbtn__txt { @apply flex-1 text-start text-sm; }
|
|
240
|
-
|
|
241
|
-
/* nav sheet on a phone */
|
|
242
|
-
|
|
243
|
-
.mvb-sheet {
|
|
244
|
-
@apply grid border-t border-orbit bg-deck px-[var(--mvb-margin)] pt-1.5 pb-3.5;
|
|
245
|
-
}
|
|
246
|
-
|
|
247
|
-
.mvb-sheet__nav { @apply grid; }
|
|
248
|
-
|
|
249
|
-
.mvb-sheet__link {
|
|
250
|
-
@apply flex items-center gap-2 border-b border-orbit bg-transparent py-[13px] text-start text-[1.0625rem] font-medium text-ink no-underline;
|
|
251
|
-
}
|
|
252
|
-
|
|
253
|
-
.mvb-sheet__link:last-child { @apply border-b-0; }
|
|
254
|
-
.mvb-sheet__link .mvb-ico { @apply text-ink-3; }
|
|
255
|
-
.mvb-sheet__action { @apply text-comet; }
|
|
256
|
-
|
|
257
|
-
/* ---------- frame ---------- */
|
|
258
|
-
|
|
259
|
-
.mvb-main { @apply flex-1 outline-none; }
|
|
260
|
-
|
|
261
|
-
.mvb-page { @apply px-[var(--mvb-margin)]; }
|
|
262
|
-
|
|
263
|
-
.mvb-page--tool,
|
|
264
|
-
.mvb-page--narrow {
|
|
265
|
-
max-width: var(--mvb-bench);
|
|
266
|
-
@apply mx-auto;
|
|
267
|
-
}
|
|
268
|
-
|
|
269
|
-
.mvb-link { @apply text-comet underline-offset-[3px]; }
|
|
270
|
-
|
|
271
|
-
/* One key chip for the whole app: the search button, the filter, the palette
|
|
272
|
-
footer and the help modal all point at the same key. It sits on a raised and a
|
|
273
|
-
recessed surface in turn, so it carries its own border instead of a fill. */
|
|
274
|
-
.mvb-kbd {
|
|
275
|
-
@apply rounded-[5px] border border-orbit-hard px-[7px] py-px font-sans text-[0.8125rem] leading-[1.45] text-ink-3;
|
|
276
|
-
}
|
|
277
|
-
|
|
278
|
-
/* hero, only on the home page */
|
|
279
|
-
|
|
280
|
-
.mvb-hero {
|
|
281
|
-
@apply relative border-b border-orbit;
|
|
282
|
-
overflow: clip;
|
|
283
|
-
background:
|
|
284
|
-
radial-gradient(560px 300px at 12% -40px, var(--mvb-nebula), transparent 70%),
|
|
285
|
-
var(--mvb-deck);
|
|
286
|
-
}
|
|
287
|
-
|
|
288
|
-
.mvb-hero__in {
|
|
289
|
-
max-width: var(--mvb-bench);
|
|
290
|
-
@apply mx-auto grid items-center gap-[clamp(24px,5vw,72px)] px-[var(--mvb-margin)] pt-[clamp(48px,8vw,104px)] pb-[clamp(40px,6vw,80px)];
|
|
291
|
-
grid-template-columns: minmax(0, 1.2fr) minmax(0, 0.8fr);
|
|
292
|
-
}
|
|
293
|
-
|
|
294
|
-
.mvb-hero__title {
|
|
295
|
-
@apply text-balance text-[clamp(34px,6vw,60px)] font-bold leading-[1.02] tracking-[-0.03em];
|
|
296
|
-
}
|
|
297
|
-
|
|
298
|
-
.mvb-hero__cta { @apply mt-6 flex flex-wrap gap-2.5; }
|
|
299
|
-
|
|
300
|
-
.mvb-hero__orbit { @apply w-[min(300px,70vw)] justify-self-center; }
|
|
301
|
-
.mvb-hero__orbit img { @apply block h-auto w-full rounded-r3; }
|
|
302
|
-
|
|
303
|
-
/* index sections */
|
|
304
|
-
|
|
305
|
-
.mvb-section { @apply pt-[clamp(32px,5vw,60px)]; }
|
|
306
|
-
|
|
307
|
-
.mvb-section__head { @apply mb-4 flex items-baseline gap-3; }
|
|
308
|
-
|
|
309
|
-
.mvb-section__title {
|
|
310
|
-
@apply flex items-center gap-2.5 text-[clamp(21px,3vw,27px)] font-bold tracking-[-0.02em];
|
|
311
|
-
}
|
|
312
|
-
|
|
313
|
-
.mvb-section__title .mvb-ico { @apply size-[22px] text-comet; }
|
|
314
|
-
|
|
315
|
-
.mvb-section__count {
|
|
316
|
-
@apply ms-1.5 rounded-full bg-deck-2 px-2 py-px text-[0.8125rem] font-semibold tabular-nums text-ink-3;
|
|
317
|
-
}
|
|
318
|
-
|
|
319
|
-
.mvb-section__more {
|
|
320
|
-
@apply ms-auto whitespace-nowrap text-[0.90625rem] font-semibold text-comet no-underline;
|
|
321
|
-
}
|
|
322
|
-
|
|
323
|
-
.mvb-section__more:hover { @apply underline; }
|
|
324
|
-
|
|
325
|
-
/* ---------- column system ----------
|
|
326
|
-
Every grid climbs through three states, so a tablet gets a layout of its own
|
|
327
|
-
instead of a stretched stack or four crammed columns. */
|
|
328
|
-
|
|
329
|
-
.mvb-cols { @apply grid gap-[var(--mvb-gutter)]; }
|
|
330
|
-
.mvb-cols--2 { @apply grid-cols-1 sm:grid-cols-2; }
|
|
331
|
-
.mvb-cols--3 { @apply grid-cols-1 sm:grid-cols-2 lg:grid-cols-3; }
|
|
332
|
-
.mvb-cols--4 { @apply grid-cols-1 sm:grid-cols-2 lg:grid-cols-4; }
|
|
333
|
-
.mvb-cols--auto { grid-template-columns: repeat(auto-fit, minmax(min(260px, 100%), 1fr)); }
|
|
334
|
-
.mvb-cols--side { @apply grid-cols-1 min-[60rem]:grid-cols-[minmax(0,20rem)_minmax(0,1fr)]; }
|
|
335
|
-
|
|
336
|
-
.mvb-row { @apply flex min-w-0 flex-wrap items-center gap-2; }
|
|
337
|
-
.mvb-col { @apply min-w-0; }
|
|
338
|
-
.mvb-col--grow { @apply flex-1; }
|
|
339
|
-
.mvb-col--shrink { @apply flex-none; }
|
|
340
|
-
|
|
341
|
-
.mvb-grid { @apply grid grid-cols-1 gap-[var(--mvb-gutter)] sm:grid-cols-2 lg:grid-cols-3; }
|
|
342
|
-
|
|
343
|
-
.mvb-card {
|
|
344
|
-
@apply relative grid gap-1.5 rounded-r2 border border-orbit bg-deck p-5 no-underline transition-colors duration-150;
|
|
345
|
-
}
|
|
346
|
-
|
|
347
|
-
.mvb-card:hover { @apply border-comet; }
|
|
348
|
-
|
|
349
|
-
.mvb-card__top { @apply flex items-center gap-3; }
|
|
350
|
-
|
|
351
|
-
.mvb-card__sigil {
|
|
352
|
-
@apply grid size-[42px] flex-none place-items-center rounded-[13px] bg-nebula text-comet;
|
|
353
|
-
}
|
|
354
|
-
|
|
355
|
-
.mvb-card__sigil .mvb-ico { @apply size-[21px]; }
|
|
356
|
-
|
|
357
|
-
.mvb-card__name { @apply text-[1.0625rem] font-semibold tracking-[-0.01em]; }
|
|
358
|
-
|
|
359
|
-
.mvb-card__note { @apply min-h-11 text-pretty text-[0.90625rem] text-ink-2; }
|
|
360
|
-
|
|
361
|
-
.mvb-card__foot {
|
|
362
|
-
@apply mt-1.5 flex items-center gap-2 text-[0.84375rem] font-semibold text-ink-3;
|
|
363
|
-
}
|
|
364
|
-
|
|
365
|
-
/* ---------- tool list (category and favorites pages) ---------- */
|
|
366
|
-
|
|
367
|
-
.mvb-list {
|
|
368
|
-
@apply grid overflow-clip rounded-r2 border border-orbit bg-deck;
|
|
369
|
-
}
|
|
370
|
-
|
|
371
|
-
.mvb-listrow {
|
|
372
|
-
@apply flex items-center border-b border-orbit;
|
|
373
|
-
}
|
|
374
|
-
|
|
375
|
-
.mvb-listrow:last-child { @apply border-b-0; }
|
|
376
|
-
|
|
377
|
-
.mvb-listrow__link {
|
|
378
|
-
@apply grid min-w-0 flex-1 gap-px py-[13px] pe-1.5 ps-[18px] no-underline;
|
|
379
|
-
}
|
|
380
|
-
|
|
381
|
-
.mvb-listrow__link:hover .mvb-listrow__name { @apply text-comet; }
|
|
382
|
-
|
|
383
|
-
.mvb-listrow__name { @apply text-[1.03125rem] font-semibold tracking-[-0.01em]; }
|
|
384
|
-
.mvb-listrow__note { @apply text-sm text-ink-2; }
|
|
385
|
-
|
|
386
|
-
.mvb-star {
|
|
387
|
-
@apply me-2 inline-flex size-11 flex-none cursor-pointer items-center justify-center rounded-r1 border-0 bg-transparent text-orbit-hard transition-[color,transform] duration-150;
|
|
388
|
-
}
|
|
389
|
-
|
|
390
|
-
.mvb-star:hover { @apply text-ink-2; }
|
|
391
|
-
.mvb-star.mvb-on { @apply text-star; }
|
|
392
|
-
.mvb-star.mvb-on .mvb-ico { fill: var(--mvb-star); }
|
|
393
|
-
.mvb-star:active { @apply scale-[0.88]; }
|
|
394
|
-
|
|
395
|
-
/* ---------- filter ---------- */
|
|
396
|
-
|
|
397
|
-
.mvb-filter {
|
|
398
|
-
@apply mt-[clamp(22px,4vw,36px)] flex items-center gap-2.5 rounded-r2 border border-orbit bg-deck px-3.5 transition-colors duration-150;
|
|
399
|
-
}
|
|
400
|
-
|
|
401
|
-
.mvb-filter:focus-within { @apply border-comet; }
|
|
402
|
-
|
|
403
|
-
.mvb-filter__icon { @apply flex text-ink-3; }
|
|
404
|
-
|
|
405
|
-
.mvb-filter__in {
|
|
406
|
-
@apply min-w-0 flex-1 border-0 bg-transparent text-[1.0625rem];
|
|
407
|
-
height: 52px;
|
|
408
|
-
}
|
|
409
|
-
|
|
410
|
-
.mvb-filter__in:focus { @apply outline-none; }
|
|
411
|
-
.mvb-filter__in::placeholder { @apply text-ink-3; }
|
|
412
|
-
|
|
413
|
-
.mvb-filter__meta {
|
|
414
|
-
@apply mt-2.5 flex min-h-[22px] items-baseline gap-3.5 text-sm text-ink-3;
|
|
415
|
-
}
|
|
416
|
-
|
|
417
|
-
/* ---------- page headings ---------- */
|
|
418
|
-
|
|
419
|
-
.mvb-lead {
|
|
420
|
-
@apply mt-[clamp(28px,5vw,56px)] max-w-[20ch] text-balance text-[clamp(28px,5vw,44px)] font-bold leading-[1.06] tracking-[-0.025em];
|
|
421
|
-
}
|
|
422
|
-
|
|
423
|
-
.mvb-lede { @apply mt-3 max-w-[60ch] text-pretty text-[1.0625rem] text-ink-2; }
|
|
424
|
-
|
|
425
|
-
/* ---------- tool page ---------- */
|
|
426
|
-
|
|
427
|
-
.mvb-head { @apply my-[clamp(24px,4vw,44px)] mb-[clamp(22px,3vw,32px)]; }
|
|
428
|
-
|
|
429
|
-
.mvb-head__back {
|
|
430
|
-
@apply mb-4 inline-flex items-center gap-[7px] text-[0.9375rem] font-medium text-ink-2 no-underline;
|
|
431
|
-
}
|
|
432
|
-
|
|
433
|
-
.mvb-head__back:hover { @apply text-ink; }
|
|
434
|
-
|
|
435
|
-
.mvb-head__row { @apply flex items-start gap-2; }
|
|
436
|
-
|
|
437
|
-
.mvb-head__title {
|
|
438
|
-
@apply flex-1 text-balance text-[clamp(26px,4vw,36px)] font-bold leading-[1.1] tracking-[-0.025em];
|
|
439
|
-
}
|
|
440
|
-
|
|
441
|
-
.mvb-head__actions { @apply flex items-center gap-0.5 pt-1; }
|
|
442
|
-
|
|
443
|
-
.mvb-head__about { @apply mt-2 max-w-[58ch] text-pretty text-[1.0625rem] text-ink-2; }
|
|
444
|
-
|
|
445
|
-
.mvb-helpbtn {
|
|
446
|
-
@apply inline-flex size-[38px] cursor-pointer items-center justify-center rounded-full border border-orbit bg-deck-2 font-sans text-base font-bold text-ink-2 transition-colors duration-150;
|
|
447
|
-
}
|
|
448
|
-
|
|
449
|
-
.mvb-helpbtn:hover { @apply border-orbit-hard bg-deck text-ink; }
|
|
450
|
-
.mvb-helpbtn:focus-visible { @apply border-comet; }
|
|
451
|
-
|
|
452
|
-
.mvb-more { @apply mt-[clamp(40px,6vw,72px)]; }
|
|
453
|
-
.mvb-more__title { @apply mb-2.5 text-[0.9375rem] font-bold text-ink-3; }
|
|
454
|
-
|
|
455
|
-
/* ---------- tool card ----------
|
|
456
|
-
Head and foot are the only places a tool may put an action row, so the buttons
|
|
457
|
-
always land on a card edge. The body is the working surface. */
|
|
458
|
-
|
|
459
|
-
.mvb-toolcard {
|
|
460
|
-
@apply flex flex-col overflow-clip rounded-r2 border border-orbit bg-deck;
|
|
461
|
-
}
|
|
462
|
-
|
|
463
|
-
.mvb-toolcard__head {
|
|
464
|
-
@apply flex flex-wrap items-center gap-2 border-b border-orbit bg-deck-2 px-[clamp(20px,3vw,32px)] py-[clamp(12px,2vw,16px)];
|
|
465
|
-
}
|
|
466
|
-
|
|
467
|
-
.mvb-toolcard__body {
|
|
468
|
-
@apply flex-1 p-[clamp(20px,3vw,32px)];
|
|
469
|
-
}
|
|
470
|
-
|
|
471
|
-
.mvb-toolcard__foot {
|
|
472
|
-
@apply flex flex-wrap items-center justify-end gap-2 border-t border-orbit bg-deck-2 px-[clamp(20px,3vw,32px)] py-[clamp(12px,2vw,16px)];
|
|
473
|
-
}
|
|
474
|
-
|
|
475
|
-
/* ---------- bench ----------
|
|
476
|
-
One column until there is real room for two, so the phone reads top to bottom
|
|
477
|
-
and a tablet is not a stretched stack. */
|
|
478
|
-
|
|
479
|
-
.mvb-bench { @apply grid items-start gap-5; }
|
|
480
|
-
|
|
481
|
-
.mvb-bench__side,
|
|
482
|
-
.mvb-bench__main { @apply min-w-0; }
|
|
483
|
-
|
|
484
|
-
@media (min-width: 60rem) {
|
|
485
|
-
.mvb-bench {
|
|
486
|
-
@apply gap-6;
|
|
487
|
-
grid-template-columns: minmax(0, 21rem) minmax(0, 1fr);
|
|
488
|
-
}
|
|
489
|
-
}
|
|
490
|
-
|
|
491
|
-
.mvb-stage {
|
|
492
|
-
@apply mx-auto grid max-w-[560px] justify-items-center gap-4 text-center;
|
|
493
|
-
}
|
|
494
|
-
|
|
495
|
-
.mvb-stack { @apply grid content-start gap-4; }
|
|
496
|
-
|
|
497
|
-
/* ---------- field ---------- */
|
|
498
|
-
|
|
499
|
-
.mvb-field { @apply grid min-w-0 content-start gap-1.5; }
|
|
500
|
-
.mvb-field__label { @apply text-[0.875rem] font-semibold text-ink-2; }
|
|
501
|
-
.mvb-field__hint { @apply text-[0.8125rem] text-ink-3; }
|
|
502
|
-
|
|
503
|
-
.mvb-field--error .mvb-in,
|
|
504
|
-
.mvb-field--error .mvb-pick {
|
|
505
|
-
border-color: var(--mvb-danger);
|
|
506
|
-
box-shadow: 0 0 0 3px color-mix(in srgb, var(--mvb-danger) 14%, transparent);
|
|
507
|
-
}
|
|
508
|
-
|
|
509
|
-
.mvb-field--error .mvb-field__hint { @apply text-danger; }
|
|
510
|
-
|
|
511
|
-
.mvb-field--good .mvb-in,
|
|
512
|
-
.mvb-field--good .mvb-pick {
|
|
513
|
-
border-color: var(--mvb-aurora);
|
|
514
|
-
box-shadow: 0 0 0 3px color-mix(in srgb, var(--mvb-aurora) 14%, transparent);
|
|
515
|
-
}
|
|
516
|
-
|
|
517
|
-
.mvb-field--good .mvb-field__hint { @apply text-aurora; }
|
|
518
|
-
|
|
519
|
-
/* ---------- inputs ----------
|
|
520
|
-
You type into a raised surface. Results live in .mvb-out on a recessed one. */
|
|
521
|
-
|
|
522
|
-
.mvb-in {
|
|
523
|
-
@apply w-full min-w-0 rounded-r1 border border-orbit bg-deck px-3 py-2.5 text-ink transition-[border-color,box-shadow] duration-150;
|
|
524
|
-
}
|
|
525
|
-
|
|
526
|
-
.mvb-in:hover { @apply border-orbit-hard; }
|
|
527
|
-
.mvb-in:focus { @apply border-comet outline-none ring-3 ring-nebula; }
|
|
528
|
-
.mvb-in::placeholder { @apply text-ink-3; }
|
|
529
|
-
|
|
530
|
-
.mvb-in[disabled],
|
|
531
|
-
.mvb-in[readonly] { @apply cursor-default bg-deck-2 text-ink-3; }
|
|
532
|
-
|
|
533
|
-
.mvb-in[disabled] { @apply cursor-not-allowed opacity-70; }
|
|
534
|
-
|
|
535
|
-
.mvb-in--area {
|
|
536
|
-
@apply min-h-24 resize-y py-2.5 font-mono text-[0.875rem] leading-normal;
|
|
537
|
-
}
|
|
538
|
-
|
|
539
|
-
.mvb-in--num { width: 96px; }
|
|
540
|
-
.mvb-in--mono { @apply font-mono text-[0.875rem]; }
|
|
541
|
-
|
|
542
|
-
.mvb-in--select {
|
|
543
|
-
@apply cursor-pointer py-2.5 pe-9;
|
|
544
|
-
appearance: none;
|
|
545
|
-
-webkit-appearance: none;
|
|
546
|
-
background-image: var(--mvb-caret);
|
|
547
|
-
background-repeat: no-repeat;
|
|
548
|
-
background-position: right 12px center;
|
|
549
|
-
background-size: 14px;
|
|
550
|
-
}
|
|
551
|
-
|
|
552
|
-
.mvb-in--file { @apply p-1.5; }
|
|
553
|
-
|
|
554
|
-
.mvb-in--file::file-selector-button {
|
|
555
|
-
@apply me-2.5 cursor-pointer rounded-r1 border border-orbit-hard bg-deck-2 px-2.5 py-1 text-[0.8125rem] font-semibold text-ink;
|
|
556
|
-
}
|
|
557
|
-
|
|
558
|
-
.mvb-check {
|
|
559
|
-
@apply inline-flex cursor-pointer items-center gap-2 rounded-r1 border border-orbit bg-deck py-2 ps-2.5 pe-3 text-[0.9375rem] transition-[border-color,background-color] duration-150;
|
|
560
|
-
}
|
|
561
|
-
|
|
562
|
-
.mvb-check:has(.mvb-check__box:checked) { @apply border-comet bg-nebula; }
|
|
563
|
-
|
|
564
|
-
.mvb-check__box {
|
|
565
|
-
@apply m-0 size-4;
|
|
566
|
-
accent-color: var(--mvb-comet);
|
|
567
|
-
}
|
|
568
|
-
|
|
569
|
-
/* switch */
|
|
570
|
-
|
|
571
|
-
.mvb-switch {
|
|
572
|
-
@apply inline-flex cursor-pointer select-none items-center gap-2.5 text-[0.9375rem];
|
|
573
|
-
}
|
|
574
|
-
|
|
575
|
-
.mvb-switch__box { @apply pointer-events-none absolute opacity-0; }
|
|
576
|
-
|
|
577
|
-
.mvb-switch__track {
|
|
578
|
-
@apply relative h-[22px] w-[38px] rounded-full transition-colors duration-150;
|
|
579
|
-
background: var(--mvb-track);
|
|
580
|
-
}
|
|
581
|
-
|
|
582
|
-
.mvb-switch__thumb {
|
|
583
|
-
@apply absolute top-0.5 left-0.5 size-[18px] rounded-full bg-deck transition-transform duration-150;
|
|
584
|
-
box-shadow: 0 1px 2px rgb(0 0 0 / 0.18);
|
|
585
|
-
}
|
|
586
|
-
|
|
587
|
-
.mvb-switch__box:checked + .mvb-switch__track { background: var(--mvb-comet); }
|
|
588
|
-
.mvb-switch__box:checked + .mvb-switch__track .mvb-switch__thumb { @apply translate-x-4; }
|
|
589
|
-
.mvb-switch__box:focus-visible + .mvb-switch__track { box-shadow: 0 0 0 3px var(--mvb-nebula); }
|
|
590
|
-
|
|
591
|
-
.mvb-range {
|
|
592
|
-
@apply w-full;
|
|
593
|
-
accent-color: var(--mvb-comet);
|
|
594
|
-
}
|
|
595
|
-
|
|
596
|
-
.mvb-pick {
|
|
597
|
-
@apply h-10 w-[52px] flex-none cursor-pointer rounded-r1 border border-orbit bg-deck p-0.5;
|
|
598
|
-
}
|
|
599
|
-
|
|
600
|
-
.mvb-pick:hover { @apply border-orbit-hard; }
|
|
601
|
-
.mvb-pick:focus { @apply border-comet outline-none ring-3 ring-nebula; }
|
|
602
|
-
|
|
603
|
-
/* chips */
|
|
604
|
-
|
|
605
|
-
.mvb-chips { @apply flex flex-wrap gap-1.5; }
|
|
606
|
-
|
|
607
|
-
.mvb-chip {
|
|
608
|
-
@apply min-h-[38px] cursor-pointer rounded-r1 border border-orbit bg-deck px-[13px] text-sm font-medium text-ink-2 transition-colors duration-150;
|
|
609
|
-
}
|
|
610
|
-
|
|
611
|
-
.mvb-chip:hover { @apply border-orbit-hard text-ink; }
|
|
612
|
-
.mvb-chip.mvb-on { @apply border-comet bg-nebula text-ink; }
|
|
613
|
-
|
|
614
|
-
/* ---------- actions ----------
|
|
615
|
-
One row, one alignment, one gap. Third position is not an option: a tool's
|
|
616
|
-
actions belong on a card edge. */
|
|
617
|
-
|
|
618
|
-
.mvb-actions { @apply flex flex-wrap items-center justify-end gap-2; }
|
|
619
|
-
|
|
620
|
-
.mvb-toolcard__head .mvb-actions,
|
|
621
|
-
.mvb-toolcard__foot .mvb-actions { @apply w-full; }
|
|
622
|
-
|
|
623
|
-
/* An action row that ends a column keeps a small top gap; a card edge owns its own
|
|
624
|
-
padding instead. */
|
|
625
|
-
.mvb-stack > .mvb-actions { @apply mt-1; }
|
|
626
|
-
|
|
627
|
-
/* buttons */
|
|
628
|
-
|
|
629
|
-
.mvb-btn {
|
|
630
|
-
@apply inline-flex min-h-10 cursor-pointer items-center justify-center gap-[7px] rounded-r1 border border-transparent px-4 text-[0.9375rem] font-semibold no-underline transition-[background-color,border-color,color,transform] duration-150;
|
|
631
|
-
}
|
|
632
|
-
|
|
633
|
-
.mvb-btn:active { @apply scale-[0.97]; }
|
|
634
|
-
|
|
635
|
-
.mvb-btn--fill { @apply border-comet bg-comet text-on-comet; }
|
|
636
|
-
.mvb-btn--fill:hover { @apply border-comet-deep bg-comet-deep; }
|
|
637
|
-
|
|
638
|
-
.mvb-btn--plain { @apply border-orbit bg-deck text-ink; }
|
|
639
|
-
.mvb-btn--plain:hover { @apply border-orbit-hard; }
|
|
640
|
-
|
|
641
|
-
.mvb-btn--quiet { @apply bg-transparent px-2 text-ink-2; }
|
|
642
|
-
.mvb-btn--quiet:hover { @apply bg-deck-2 text-ink; }
|
|
643
|
-
|
|
644
|
-
.mvb-btn:disabled { @apply cursor-not-allowed opacity-45; }
|
|
645
|
-
|
|
646
|
-
/* readouts: the recessed half of the pair, so a result never reads as an input */
|
|
647
|
-
|
|
648
|
-
.mvb-out {
|
|
649
|
-
@apply m-0 max-h-[340px] w-full overflow-auto rounded-r1 border border-orbit bg-deck-2 px-3.5 py-3 font-mono text-[0.875rem] leading-normal;
|
|
650
|
-
white-space: pre-wrap;
|
|
651
|
-
overflow-wrap: anywhere;
|
|
652
|
-
}
|
|
653
|
-
|
|
654
|
-
textarea.mvb-out { @apply resize-y; }
|
|
655
|
-
|
|
656
|
-
/* An empty readout is a waiting slot, not data. Dashed already means "nothing yet"
|
|
657
|
-
in this system (.mvb-blank, .mvb-drop), so an empty one says the same thing
|
|
658
|
-
instead of reading as a mysterious grey bar. Only <pre> can be matched safely:
|
|
659
|
-
a textarea holds its text in a property, so :empty would lie about it. */
|
|
660
|
-
pre.mvb-out:empty { @apply border-dashed bg-transparent; }
|
|
661
|
-
|
|
662
|
-
/* notices. A state is never colour alone: the rule marks it as well. */
|
|
663
|
-
|
|
664
|
-
.mvb-note { @apply border-s-[3px] border-transparent ps-2 text-sm text-ink-3; }
|
|
665
|
-
|
|
666
|
-
.mvb-note--error {
|
|
667
|
-
@apply border-s-danger text-danger;
|
|
668
|
-
}
|
|
669
|
-
|
|
670
|
-
.mvb-note--good {
|
|
671
|
-
@apply border-s-aurora text-aurora;
|
|
672
|
-
}
|
|
673
|
-
|
|
674
|
-
.mvb-blank {
|
|
675
|
-
@apply grid justify-items-center gap-2.5 rounded-r2 border border-dashed border-orbit-hard bg-deck-2 px-4 py-[clamp(28px,6vw,56px)] text-center text-ink-3;
|
|
676
|
-
}
|
|
677
|
-
|
|
678
|
-
.mvb-blank p { @apply max-w-[34ch]; }
|
|
679
|
-
|
|
680
|
-
.mvb-code {
|
|
681
|
-
@apply overflow-x-auto whitespace-pre-wrap rounded-r1 border border-orbit bg-deck-2 px-3.5 py-3 font-mono text-[0.875rem];
|
|
682
|
-
}
|
|
683
|
-
|
|
684
|
-
:not(pre) > code {
|
|
685
|
-
@apply rounded-[4px] bg-deck-2 px-[5px] py-px font-mono text-[0.92em];
|
|
686
|
-
}
|
|
687
|
-
|
|
688
|
-
/* about blocks */
|
|
689
|
-
|
|
690
|
-
.mvb-about {
|
|
691
|
-
@apply mt-8 grid max-w-[62ch] gap-2.5 border-t border-orbit pt-6;
|
|
692
|
-
}
|
|
693
|
-
|
|
694
|
-
.mvb-about__title { @apply text-lg font-bold tracking-[-0.01em]; }
|
|
695
|
-
.mvb-about p { @apply text-pretty text-ink-2; }
|
|
696
|
-
|
|
697
|
-
/* ---------- modal ---------- */
|
|
698
|
-
|
|
699
|
-
.mvb-veil {
|
|
700
|
-
@apply fixed inset-0 z-80 grid items-start justify-items-center px-5 pt-[clamp(60px,10vh,120px)] pb-5;
|
|
701
|
-
background: var(--mvb-scrim);
|
|
702
|
-
opacity: 0;
|
|
703
|
-
transition: opacity 180ms ease;
|
|
704
|
-
}
|
|
705
|
-
|
|
706
|
-
.mvb-veil.mvb-open { opacity: 1; }
|
|
707
|
-
.mvb-veil.mvb-off { opacity: 0; }
|
|
708
|
-
|
|
709
|
-
.mvb-modal {
|
|
710
|
-
@apply w-[min(440px,100%)] rounded-r3 border border-orbit bg-deck p-7 text-center;
|
|
711
|
-
transform: translateY(14px) scale(0.96);
|
|
712
|
-
transition: transform 220ms var(--mvb-ease);
|
|
713
|
-
}
|
|
714
|
-
|
|
715
|
-
.mvb-veil.mvb-open .mvb-modal { transform: none; }
|
|
716
|
-
.mvb-veil.mvb-off .mvb-modal { transform: translateY(10px) scale(0.97); }
|
|
717
|
-
|
|
718
|
-
.mvb-modal__art img { @apply mx-auto block size-[88px] rounded-[22px]; }
|
|
719
|
-
|
|
720
|
-
.mvb-modal__title { @apply mt-3.5 text-[1.375rem] font-bold tracking-[-0.02em]; }
|
|
721
|
-
.mvb-modal__body p { @apply mt-2 text-pretty text-[0.96875rem] text-ink-2; }
|
|
722
|
-
.mvb-modal__actions { @apply mt-5 grid gap-2; }
|
|
723
|
-
|
|
724
|
-
/* version readout inside the update modal */
|
|
725
|
-
.mvb-vers { @apply mt-[18px] overflow-hidden rounded-r2 border border-orbit; }
|
|
726
|
-
.mvb-vers__row { @apply flex items-center justify-between gap-3 px-4 py-3; }
|
|
727
|
-
.mvb-vers__row + .mvb-vers__row { @apply border-t border-orbit; }
|
|
728
|
-
.mvb-vers__label { @apply text-sm text-ink-3; }
|
|
729
|
-
.mvb-vers__val { @apply font-mono text-[0.9375rem] font-semibold; }
|
|
730
|
-
.mvb-vers__row--new .mvb-vers__val { @apply text-comet; }
|
|
731
|
-
.mvb-vers__hint { @apply mt-3.5 text-sm; }
|
|
732
|
-
|
|
733
|
-
.mvb-cmd {
|
|
734
|
-
@apply mt-2.5 flex flex-wrap items-center gap-2 rounded-r2 border border-orbit bg-deck-2 py-2.5 pe-2.5 ps-4;
|
|
735
|
-
}
|
|
736
|
-
|
|
737
|
-
.mvb-cmd__text {
|
|
738
|
-
@apply min-w-0 flex-1 wrap-anywhere font-mono text-sm;
|
|
739
|
-
}
|
|
740
|
-
|
|
741
|
-
/* ---------- command palette ---------- */
|
|
742
|
-
|
|
743
|
-
.mvb-veil--pal { @apply pt-[clamp(60px,12vh,140px)]; }
|
|
744
|
-
|
|
745
|
-
.mvb-veil--pal .mvb-modal {
|
|
746
|
-
@apply w-[min(640px,100%)] overflow-hidden p-0 text-start;
|
|
747
|
-
}
|
|
748
|
-
|
|
749
|
-
.mvb-pal__head {
|
|
750
|
-
@apply flex items-center gap-3 border-b border-orbit px-[18px] py-4;
|
|
751
|
-
}
|
|
752
|
-
|
|
753
|
-
.mvb-pal__icon { @apply text-ink-3; }
|
|
754
|
-
|
|
755
|
-
.mvb-pal__in {
|
|
756
|
-
@apply h-10 min-w-0 flex-1 border-0 bg-transparent text-[1.0625rem];
|
|
757
|
-
}
|
|
758
|
-
|
|
759
|
-
.mvb-pal__in:focus { @apply outline-none; }
|
|
760
|
-
.mvb-pal__in::placeholder { @apply text-ink-3; }
|
|
761
|
-
|
|
762
|
-
.mvb-pal__count { @apply m-0 px-[18px] pt-2 text-[0.8125rem] text-ink-3; }
|
|
763
|
-
|
|
764
|
-
.mvb-pal__list {
|
|
765
|
-
@apply m-0 mt-1.5 max-h-[min(60vh,360px)] overflow-y-auto px-2 pb-2;
|
|
766
|
-
}
|
|
767
|
-
|
|
768
|
-
.mvb-pal__item {
|
|
769
|
-
@apply flex w-full cursor-pointer items-center gap-3 rounded-r1 border-0 bg-transparent px-3 py-2.5 text-start text-ink transition-colors duration-150;
|
|
770
|
-
}
|
|
771
|
-
|
|
772
|
-
.mvb-pal__item.mvb-on { @apply bg-nebula; }
|
|
773
|
-
.mvb-pal__item.mvb-on .mvb-pal__name { @apply text-comet; }
|
|
774
|
-
|
|
775
|
-
.mvb-pal__sigil {
|
|
776
|
-
@apply grid size-8 flex-none place-items-center rounded-lg bg-deck-2 text-comet;
|
|
777
|
-
}
|
|
778
|
-
|
|
779
|
-
.mvb-pal__sigil .mvb-ico { @apply size-4; }
|
|
780
|
-
.mvb-pal__text { @apply grid min-w-0 flex-1 gap-px; }
|
|
781
|
-
.mvb-pal__name { @apply text-[0.9375rem] font-semibold tracking-[-0.01em]; }
|
|
782
|
-
.mvb-pal__note { @apply overflow-hidden text-[0.84375rem] text-ellipsis whitespace-nowrap text-ink-2; }
|
|
783
|
-
.mvb-pal__cat { @apply whitespace-nowrap text-[0.8125rem] text-ink-3; }
|
|
784
|
-
|
|
785
|
-
.mvb-pal__empty { @apply p-[18px] text-sm text-ink-3; }
|
|
786
|
-
|
|
787
|
-
.mvb-pal__foot {
|
|
788
|
-
@apply m-0 flex flex-wrap items-center gap-2.5 border-t border-orbit px-[18px] py-2.5 text-[0.8125rem] text-ink-3;
|
|
789
|
-
}
|
|
790
|
-
|
|
791
|
-
/* ---------- help modal ---------- */
|
|
792
|
-
|
|
793
|
-
.mvb-veil--help { @apply pt-[clamp(60px,10vh,120px)]; }
|
|
794
|
-
|
|
795
|
-
.mvb-veil--help .mvb-modal {
|
|
796
|
-
@apply w-[min(560px,100%)] overflow-hidden p-7 text-start;
|
|
797
|
-
}
|
|
798
|
-
|
|
799
|
-
.mvb-help__head { @apply mb-3 flex items-center gap-3.5; }
|
|
800
|
-
|
|
801
|
-
.mvb-help__sigil {
|
|
802
|
-
@apply grid size-11 place-items-center rounded-xl bg-nebula text-comet;
|
|
803
|
-
}
|
|
804
|
-
|
|
805
|
-
.mvb-help__sigil .mvb-ico { @apply size-[22px]; }
|
|
806
|
-
|
|
807
|
-
.mvb-help__title { @apply text-xl font-bold tracking-[-0.02em]; }
|
|
808
|
-
.mvb-help__note { @apply mb-3.5 text-pretty text-[0.96875rem] leading-normal text-ink-2; }
|
|
809
|
-
|
|
810
|
-
.mvb-help__steps {
|
|
811
|
-
@apply m-0 grid list-none gap-2.5 p-0;
|
|
812
|
-
counter-reset: mvb-step;
|
|
813
|
-
}
|
|
814
|
-
|
|
815
|
-
.mvb-help__steps li {
|
|
816
|
-
@apply grid grid-cols-[22px_1fr] items-start gap-2 text-[0.90625rem] leading-normal text-ink;
|
|
817
|
-
}
|
|
818
|
-
|
|
819
|
-
.mvb-help__steps li::before {
|
|
820
|
-
content: counter(mvb-step);
|
|
821
|
-
counter-increment: mvb-step;
|
|
822
|
-
@apply grid size-[22px] place-items-center rounded-full bg-nebula text-[0.8125rem] font-bold tabular-nums text-comet;
|
|
823
|
-
}
|
|
824
|
-
|
|
825
|
-
/* ---------- footer ---------- */
|
|
826
|
-
|
|
827
|
-
.mvb-foot {
|
|
828
|
-
@apply mt-[clamp(56px,8vw,96px)] border-t border-orbit bg-deck-2;
|
|
829
|
-
}
|
|
830
|
-
|
|
831
|
-
.mvb-foot__in {
|
|
832
|
-
max-width: var(--mvb-bench);
|
|
833
|
-
@apply mx-auto px-[var(--mvb-margin)] pt-[clamp(36px,5vw,56px)] pb-[clamp(24px,3vw,36px)];
|
|
834
|
-
}
|
|
835
|
-
|
|
836
|
-
.mvb-foot__top {
|
|
837
|
-
@apply grid items-start gap-[clamp(20px,4vw,56px)] min-[60rem]:grid-cols-[minmax(0,1.4fr)_minmax(0,1fr)];
|
|
838
|
-
}
|
|
839
|
-
|
|
840
|
-
.mvb-foot__brand { @apply grid gap-2.5; }
|
|
841
|
-
|
|
842
|
-
.mvb-foot__mark {
|
|
843
|
-
@apply inline-flex items-center gap-2.5 text-[1.375rem] font-bold tracking-[-0.02em] text-ink no-underline;
|
|
844
|
-
}
|
|
845
|
-
|
|
846
|
-
.mvb-foot__mark img {
|
|
847
|
-
@apply size-[34px] rounded-[10px];
|
|
848
|
-
box-shadow: 0 0 0 1px var(--mvb-orbit);
|
|
849
|
-
}
|
|
850
|
-
|
|
851
|
-
.mvb-foot__tag { @apply max-w-[38ch] text-pretty text-sm text-ink-2; }
|
|
852
|
-
|
|
853
|
-
.mvb-foot__nav {
|
|
854
|
-
@apply grid grid-cols-2 gap-x-[clamp(20px,4vw,40px)] gap-y-1.5;
|
|
855
|
-
}
|
|
856
|
-
|
|
857
|
-
.mvb-foot__nav h4 { @apply m-0 mb-2 text-[0.8125rem] font-bold tracking-normal text-ink-3 normal-case; }
|
|
858
|
-
.mvb-foot__nav ul { @apply grid gap-1.5; }
|
|
859
|
-
.mvb-foot__nav a { @apply text-[0.90625rem] text-ink-2 no-underline; }
|
|
860
|
-
.mvb-foot__nav a:hover { @apply text-comet; }
|
|
861
|
-
|
|
862
|
-
.mvb-foot__bottom {
|
|
863
|
-
@apply mt-[clamp(24px,4vw,36px)] flex flex-wrap items-center gap-x-[clamp(14px,3vw,28px)] gap-y-1.5 border-t border-orbit pt-[18px];
|
|
864
|
-
}
|
|
865
|
-
|
|
866
|
-
.mvb-foot__legal { @apply flex items-center gap-[7px] text-[0.84375rem] text-ink-3; }
|
|
867
|
-
.mvb-foot__count { @apply tabular-nums; }
|
|
868
|
-
.mvb-foot__count:empty { @apply hidden; }
|
|
869
|
-
|
|
870
|
-
/* version chip in the footer; turns into an update button when npm has a newer one */
|
|
871
|
-
.mvb-version {
|
|
872
|
-
@apply 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-[0.8125rem] tabular-nums text-ink-3 transition-colors duration-150;
|
|
873
|
-
}
|
|
874
|
-
|
|
875
|
-
.mvb-version:hover { @apply border-orbit-hard text-ink; }
|
|
876
|
-
.mvb-version:focus-visible { @apply outline-2 outline-comet outline-offset-2; }
|
|
877
|
-
|
|
878
|
-
.mvb-version--new {
|
|
879
|
-
@apply border-comet bg-nebula font-semibold text-comet;
|
|
880
|
-
}
|
|
881
|
-
|
|
882
|
-
.mvb-version--new:hover { @apply bg-comet text-on-comet; }
|
|
883
|
-
|
|
884
|
-
.mvb-version .mvb-ico { @apply size-[15px]; }
|
|
885
|
-
|
|
886
|
-
/* ---------- toast ---------- */
|
|
887
|
-
|
|
888
|
-
.mvb-toast {
|
|
889
|
-
@apply pointer-events-none fixed bottom-6 left-1/2 z-90 rounded-r1 bg-ink px-4 py-2.5 text-sm font-semibold text-void;
|
|
890
|
-
transform: translate(-50%, 12px);
|
|
891
|
-
opacity: 0;
|
|
892
|
-
transition: opacity 150ms ease, transform 150ms ease;
|
|
893
|
-
}
|
|
894
|
-
|
|
895
|
-
.mvb-toast.mvb-on { opacity: 1; transform: translate(-50%, 0); }
|
|
896
|
-
|
|
897
|
-
/* ==========================================================================
|
|
898
|
-
Objects a tool renders itself
|
|
899
|
-
========================================================================== */
|
|
900
|
-
|
|
901
|
-
/* ---------- wheel ---------- */
|
|
902
|
-
|
|
903
|
-
.mvb-wheel { @apply h-auto w-[min(320px,100%)]; }
|
|
904
|
-
|
|
905
|
-
.mvb-wheel__status {
|
|
906
|
-
@apply text-balance text-xl font-bold tracking-[-0.01em];
|
|
907
|
-
}
|
|
908
|
-
|
|
909
|
-
.mvb-wheel__history {
|
|
910
|
-
@apply flex max-w-[340px] flex-wrap justify-center gap-1.5;
|
|
911
|
-
}
|
|
912
|
-
|
|
913
|
-
.mvb-wheel__chip {
|
|
914
|
-
@apply rounded-full border border-orbit bg-deck-2 px-2.5 py-1 text-[0.8125rem] font-semibold;
|
|
915
|
-
}
|
|
916
|
-
|
|
917
|
-
/* ---------- coin ---------- */
|
|
918
|
-
|
|
919
|
-
.mvb-coin {
|
|
920
|
-
@apply grid size-32 select-none place-items-center rounded-full bg-comet text-[44px] font-bold text-on-comet;
|
|
921
|
-
}
|
|
922
|
-
|
|
923
|
-
.mvb-coin.mvb-toss { animation: mvb-toss 450ms ease; }
|
|
924
|
-
|
|
925
|
-
@keyframes mvb-toss {
|
|
926
|
-
0% { transform: scale(1) rotate(0deg); }
|
|
927
|
-
50% { transform: scale(1.12) rotate(180deg); }
|
|
928
|
-
100% { transform: scale(1) rotate(360deg); }
|
|
929
|
-
}
|
|
930
|
-
|
|
931
|
-
.mvb-flip__result { @apply text-[1.1875rem] font-bold tracking-[-0.01em]; }
|
|
932
|
-
|
|
933
|
-
/* ---------- meter ---------- */
|
|
934
|
-
|
|
935
|
-
.mvb-meter { @apply h-2 overflow-hidden rounded-full bg-deck-2; }
|
|
936
|
-
|
|
937
|
-
.mvb-meter__fill {
|
|
938
|
-
@apply h-full w-0 rounded-full transition-[width,background-color] duration-150;
|
|
939
|
-
background: var(--mvb-orbit-hard);
|
|
940
|
-
}
|
|
941
|
-
|
|
942
|
-
.mvb-meter__fill.mvb-weak { background: var(--mvb-danger); }
|
|
943
|
-
.mvb-meter__fill.mvb-ok { background: var(--mvb-comet); }
|
|
944
|
-
.mvb-meter__fill.mvb-strong { background: var(--mvb-aurora); }
|
|
945
|
-
|
|
946
|
-
/* ---------- swatch and picker ---------- */
|
|
947
|
-
|
|
948
|
-
.mvb-swatch {
|
|
949
|
-
@apply h-14 rounded-r1 border border-orbit-hard bg-deck-2;
|
|
950
|
-
}
|
|
951
|
-
|
|
952
|
-
/* ---------- case list ---------- */
|
|
953
|
-
|
|
954
|
-
.mvb-cases { @apply grid gap-1; }
|
|
955
|
-
|
|
956
|
-
.mvb-case {
|
|
957
|
-
@apply flex w-full cursor-pointer items-baseline justify-between gap-3 rounded-r1 border border-transparent bg-transparent px-3 py-[9px] text-start transition-colors duration-150;
|
|
958
|
-
}
|
|
959
|
-
|
|
960
|
-
.mvb-case:hover { @apply bg-deck-2; }
|
|
961
|
-
.mvb-case.mvb-on { @apply border-comet bg-nebula; }
|
|
962
|
-
|
|
963
|
-
.mvb-case__name { @apply flex-none text-[0.8125rem] font-semibold text-ink-2; }
|
|
964
|
-
.mvb-case.mvb-on .mvb-case__name { @apply text-ink; }
|
|
965
|
-
.mvb-case__value { @apply wrap-anywhere text-end font-mono text-sm; }
|
|
966
|
-
|
|
967
|
-
/* ---------- dropzone and camera ---------- */
|
|
968
|
-
|
|
969
|
-
.mvb-drop {
|
|
970
|
-
@apply grid cursor-pointer justify-items-center gap-2 rounded-r2 border border-dashed border-orbit-hard px-4 py-7 text-[0.9375rem] text-ink-3 transition-colors duration-150;
|
|
971
|
-
}
|
|
972
|
-
|
|
973
|
-
.mvb-drop:hover,
|
|
974
|
-
.mvb-drop.mvb-drag { @apply border-comet bg-nebula; }
|
|
975
|
-
|
|
976
|
-
.mvb-qrview {
|
|
977
|
-
@apply w-[min(420px,100%)] rounded-r2 border border-orbit-hard bg-black;
|
|
978
|
-
}
|
|
979
|
-
|
|
980
|
-
.mvb-qrcode {
|
|
981
|
-
@apply h-auto w-[min(300px,100%)];
|
|
982
|
-
image-rendering: pixelated;
|
|
983
|
-
}
|
|
984
|
-
|
|
985
|
-
/* ---------- tables ---------- */
|
|
986
|
-
|
|
987
|
-
.mvb-scroll { @apply max-h-80 overflow-auto; }
|
|
988
|
-
|
|
989
|
-
.mvb-ttable {
|
|
990
|
-
@apply w-full border-collapse font-mono text-sm;
|
|
991
|
-
}
|
|
992
|
-
|
|
993
|
-
.mvb-ttable th,
|
|
994
|
-
.mvb-ttable td { @apply wrap-anywhere border-b border-orbit px-2.5 py-2 text-start; }
|
|
995
|
-
|
|
996
|
-
.mvb-ttable th { @apply font-sans text-[0.8125rem] font-semibold text-ink-2; }
|
|
997
|
-
|
|
998
|
-
.mvb-ttable tbody tr:last-child th,
|
|
999
|
-
.mvb-ttable tbody tr:last-child td { @apply border-b-0; }
|
|
1000
|
-
|
|
1001
|
-
/* ---------- secrets ---------- */
|
|
1002
|
-
|
|
1003
|
-
.mvb-secret { @apply grid grid-cols-[minmax(0,1fr)_auto] items-center gap-2; }
|
|
1004
|
-
|
|
1005
|
-
/* ---------- stat tiles ---------- */
|
|
1006
|
-
|
|
1007
|
-
.mvb-stats {
|
|
1008
|
-
@apply grid gap-2.5;
|
|
1009
|
-
grid-template-columns: repeat(auto-fit, minmax(120px, 1fr));
|
|
1010
|
-
}
|
|
1011
|
-
|
|
1012
|
-
.mvb-stat {
|
|
1013
|
-
@apply grid gap-0.5 rounded-r1 border border-orbit bg-deck-2 px-3.5 py-3;
|
|
1014
|
-
}
|
|
1015
|
-
|
|
1016
|
-
.mvb-stat__v { @apply wrap-anywhere text-[1.375rem] font-bold tracking-[-0.02em] tabular-nums; }
|
|
1017
|
-
.mvb-stat__k { @apply text-[0.8125rem] font-semibold text-ink-3; }
|
|
1018
|
-
|
|
1019
|
-
/* ---------- diff view ---------- */
|
|
1020
|
-
|
|
1021
|
-
.mvb-diff {
|
|
1022
|
-
@apply grid gap-px overflow-hidden rounded-r1 border border-orbit bg-orbit;
|
|
1023
|
-
}
|
|
1024
|
-
|
|
1025
|
-
.mvb-diff__row {
|
|
1026
|
-
@apply grid bg-deck font-mono text-[0.84375rem];
|
|
1027
|
-
grid-template-columns: 34px minmax(0, 1fr);
|
|
1028
|
-
}
|
|
1029
|
-
|
|
1030
|
-
.mvb-diff__row > span { @apply wrap-anywhere px-2.5 py-[3px] whitespace-pre-wrap; }
|
|
1031
|
-
|
|
1032
|
-
.mvb-diff__sign {
|
|
1033
|
-
@apply border-e border-orbit text-center text-ink-3 select-none;
|
|
1034
|
-
}
|
|
1035
|
-
|
|
1036
|
-
.mvb-diff__row--add { background: color-mix(in srgb, var(--mvb-aurora) 14%, var(--mvb-deck)); }
|
|
1037
|
-
.mvb-diff__row--del { background: color-mix(in srgb, var(--mvb-danger) 12%, var(--mvb-deck)); }
|
|
1038
|
-
.mvb-diff__row--add .mvb-diff__sign { @apply text-aurora; }
|
|
1039
|
-
.mvb-diff__row--del .mvb-diff__sign { @apply text-danger; }
|
|
1040
|
-
|
|
1041
|
-
/* ---------- key/value list ---------- */
|
|
1042
|
-
|
|
1043
|
-
.mvb-kv {
|
|
1044
|
-
@apply grid gap-px overflow-hidden rounded-r1 border border-orbit bg-orbit;
|
|
1045
|
-
}
|
|
1046
|
-
|
|
1047
|
-
.mvb-kv__row {
|
|
1048
|
-
@apply grid gap-3 bg-deck px-3 py-[9px];
|
|
1049
|
-
grid-template-columns: minmax(90px, 34%) minmax(0, 1fr);
|
|
1050
|
-
}
|
|
1051
|
-
|
|
1052
|
-
.mvb-kv__k { @apply wrap-anywhere text-[0.84375rem] font-semibold text-ink-2; }
|
|
1053
|
-
.mvb-kv__v { @apply wrap-anywhere font-mono text-[0.84375rem]; }
|
|
1054
|
-
|
|
1055
|
-
/* ---------- preview pane and highlights ---------- */
|
|
1056
|
-
|
|
1057
|
-
.mvb-pane {
|
|
1058
|
-
@apply 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;
|
|
1059
|
-
}
|
|
1060
|
-
|
|
1061
|
-
.mvb-pane > :first-child { @apply mt-0; }
|
|
1062
|
-
.mvb-pane > :last-child { @apply mb-0; }
|
|
1063
|
-
.mvb-pane h1, .mvb-pane h2, .mvb-pane h3 { @apply my-4 tracking-[-0.01em]; }
|
|
1064
|
-
.mvb-pane p, .mvb-pane ul, .mvb-pane ol, .mvb-pane pre { @apply mb-2.5; }
|
|
1065
|
-
.mvb-pane ul, .mvb-pane ol { @apply ps-[22px]; }
|
|
1066
|
-
.mvb-pane code { @apply rounded-[5px] bg-deck px-[5px] py-px font-mono text-[0.8125rem]; }
|
|
1067
|
-
.mvb-pane pre { @apply overflow-auto rounded-r1 bg-deck px-3 py-2.5; }
|
|
1068
|
-
.mvb-pane pre code { @apply bg-transparent p-0; }
|
|
1069
|
-
.mvb-pane a { @apply text-comet; }
|
|
1070
|
-
.mvb-pane table { @apply border-collapse; }
|
|
1071
|
-
.mvb-pane th, .mvb-pane td { @apply border border-orbit px-[9px] py-1.5; }
|
|
1072
|
-
|
|
1073
|
-
.mvb-hl { background: color-mix(in srgb, var(--mvb-star) 40%, transparent); @apply rounded-[3px]; }
|
|
1074
|
-
.mvb-hl--on { @apply rounded-[3px] bg-comet text-on-comet; }
|
|
1075
|
-
|
|
1076
|
-
/* ---------- design previews ---------- */
|
|
1077
|
-
|
|
1078
|
-
.mvb-swatches {
|
|
1079
|
-
@apply grid gap-2;
|
|
1080
|
-
grid-template-columns: repeat(auto-fit, minmax(96px, 1fr));
|
|
1081
|
-
}
|
|
1082
|
-
|
|
1083
|
-
.mvb-swatchcard {
|
|
1084
|
-
@apply grid cursor-pointer gap-1.5 rounded-r1 border border-orbit bg-deck p-2 text-start transition-colors duration-150;
|
|
1085
|
-
}
|
|
1086
|
-
|
|
1087
|
-
.mvb-swatchcard:hover { @apply border-comet; }
|
|
1088
|
-
.mvb-swatchcard__chip { @apply h-[52px] rounded-lg border border-orbit-hard; }
|
|
1089
|
-
.mvb-swatchcard__code { @apply font-mono text-[0.8125rem] text-ink-2; }
|
|
1090
|
-
|
|
1091
|
-
.mvb-preview {
|
|
1092
|
-
@apply grid min-h-40 place-items-center overflow-hidden rounded-r1 border border-orbit bg-deck-2 p-[22px];
|
|
1093
|
-
}
|
|
1094
|
-
|
|
1095
|
-
.mvb-preview__box {
|
|
1096
|
-
@apply grid h-[120px] w-[min(200px,100%)] place-items-center bg-comet text-[0.8125rem] text-on-comet;
|
|
1097
|
-
}
|
|
1098
|
-
|
|
1099
|
-
.mvb-preview__sample {
|
|
1100
|
-
@apply w-full rounded-lg border border-orbit bg-deck px-[18px] py-4;
|
|
1101
|
-
}
|
|
1102
|
-
|
|
1103
|
-
.mvb-slider {
|
|
1104
|
-
@apply grid items-center gap-2.5;
|
|
1105
|
-
grid-template-columns: 88px minmax(0, 1fr) 62px;
|
|
1106
|
-
}
|
|
1107
|
-
|
|
1108
|
-
.mvb-slider__label { @apply text-[0.84375rem] font-semibold text-ink-2; }
|
|
1109
|
-
.mvb-slider__val { @apply text-end font-mono text-[0.8125rem] text-ink-2; }
|
|
1110
|
-
|
|
1111
|
-
/* ---------- narrow states ----------
|
|
1112
|
-
A phone is its own layout, not a narrowed desktop: one column, calmer gaps,
|
|
1113
|
-
full-width actions, and 16px inputs so the browser keyboard does not zoom. */
|
|
1114
|
-
|
|
1115
|
-
@media (max-width: 60rem) {
|
|
1116
|
-
.mvb-toolcard__head,
|
|
1117
|
-
.mvb-toolcard__foot { @apply px-[18px]; }
|
|
1118
|
-
.mvb-toolcard__body { @apply p-[18px]; }
|
|
1119
|
-
|
|
1120
|
-
/* The header is the tightest row in the app: mark, four links, the search pill
|
|
1121
|
-
and two buttons. Drop the search pill first, because the sheet still offers
|
|
1122
|
-
Search and the tools page has its own filter. Only below 45rem, when the
|
|
1123
|
-
links no longer fit either, do they move into the sheet. */
|
|
1124
|
-
.mvb-searchbtn { @apply hidden; }
|
|
1125
|
-
}
|
|
1126
|
-
|
|
1127
|
-
@media (max-width: 45rem) {
|
|
1128
|
-
.mvb-nav { @apply hidden; }
|
|
1129
|
-
.mvb-bar__menu { @apply inline-flex; }
|
|
1130
|
-
.mvb-bar__end { @apply ms-auto; }
|
|
1131
|
-
|
|
1132
|
-
.mvb-hero__in { grid-template-columns: minmax(0, 1fr); }
|
|
1133
|
-
.mvb-hero__orbit { @apply hidden; }
|
|
1134
|
-
|
|
1135
|
-
.mvb-card { @apply p-4; }
|
|
1136
|
-
.mvb-card__note { @apply min-h-0; }
|
|
1137
|
-
|
|
1138
|
-
.mvb-filter__in { height: 48px; }
|
|
1139
|
-
|
|
1140
|
-
.mvb-stage { @apply justify-items-stretch text-start; }
|
|
1141
|
-
|
|
1142
|
-
.mvb-btn { @apply min-h-11; }
|
|
1143
|
-
.mvb-chip { @apply min-h-11; }
|
|
1144
|
-
|
|
1145
|
-
/* The action row keeps the same right alignment as every wider width. Stretching
|
|
1146
|
-
every button to fill the bar instead would wrap a longer label such as
|
|
1147
|
-
"Copy Base64" onto two lines and make the footer taller than the buttons need. */
|
|
1148
|
-
.mvb-toolcard__foot .mvb-actions,
|
|
1149
|
-
.mvb-toolcard__head .mvb-actions { @apply gap-2; }
|
|
1150
|
-
|
|
1151
|
-
.mvb-slider { grid-template-columns: minmax(0, 1fr) 62px; }
|
|
1152
|
-
.mvb-slider__label { @apply col-span-2; }
|
|
1153
|
-
|
|
1154
|
-
/* 16px on every field and readout: below that the browser zooms the page when a
|
|
1155
|
-
field takes focus, and a table cell or a panel can otherwise shrink a control
|
|
1156
|
-
below its own scale. Inline text stays where it is; this is about controls. */
|
|
1157
|
-
.mvb-in,
|
|
1158
|
-
.mvb-out,
|
|
1159
|
-
.mvb-filter__in,
|
|
1160
|
-
select { @apply text-base; }
|
|
1161
|
-
|
|
1162
|
-
/* A colour swatch and a bare icon button are still tap targets. */
|
|
1163
|
-
.mvb-pick { @apply h-11; }
|
|
1164
|
-
.mvb-icobtn { @apply size-11; }
|
|
1165
|
-
|
|
1166
|
-
/* And so are a slider, a checkbox chip and a switch: on a phone they are the
|
|
1167
|
-
control, not a decoration beside a larger one. */
|
|
1168
|
-
.mvb-range { @apply min-h-11; }
|
|
1169
|
-
.mvb-check { @apply min-h-11; }
|
|
1170
|
-
.mvb-switch { @apply min-h-11; }
|
|
1171
|
-
}
|
|
1172
|
-
}
|