@nice2dev/icons 1.3.3 → 1.3.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (39) hide show
  1. package/CHANGELOG.md +39 -0
  2. package/README.md +12 -4
  3. package/dist/cjs/createIcon.js +4 -1
  4. package/dist/cjs/figmaExport.js +1 -0
  5. package/dist/cjs/iconParts.js +6 -5
  6. package/dist/cjs/icons/actions.js +11 -3
  7. package/dist/cjs/icons/business.js +8 -7
  8. package/dist/cjs/icons/education.js +18 -14
  9. package/dist/cjs/icons/files.js +10 -8
  10. package/dist/cjs/icons/index.js +1 -0
  11. package/dist/cjs/icons/media.js +41 -15
  12. package/dist/cjs/icons/navigation.js +8 -6
  13. package/dist/cjs/icons/realestate.js +5 -2
  14. package/dist/cjs/icons/shapes.js +16 -4
  15. package/dist/cjs/icons/travel.js +15 -14
  16. package/dist/cjs/icons/ui.js +41 -6
  17. package/dist/cjs/index.js +1 -0
  18. package/dist/cjs/nicetodev-icons.css +1 -1
  19. package/dist/esm/createIcon.js +4 -1
  20. package/dist/esm/figmaExport.js +1 -0
  21. package/dist/esm/iconParts.js +6 -5
  22. package/dist/esm/icons/actions.js +11 -3
  23. package/dist/esm/icons/business.js +9 -8
  24. package/dist/esm/icons/education.js +18 -14
  25. package/dist/esm/icons/files.js +10 -8
  26. package/dist/esm/icons/index.js +1 -1
  27. package/dist/esm/icons/media.js +41 -15
  28. package/dist/esm/icons/navigation.js +8 -6
  29. package/dist/esm/icons/realestate.js +5 -2
  30. package/dist/esm/icons/shapes.js +16 -4
  31. package/dist/esm/icons/travel.js +15 -14
  32. package/dist/esm/icons/ui.js +41 -7
  33. package/dist/esm/index.js +1 -1
  34. package/dist/esm/nicetodev-icons.css +1 -1
  35. package/dist/types/iconParts.d.ts +2 -1
  36. package/dist/types/icons/index.d.ts +1 -1
  37. package/dist/types/icons/ui.d.ts +1 -0
  38. package/dist/types/types.d.ts +8 -3
  39. package/package.json +2 -2
package/CHANGELOG.md CHANGED
@@ -1,5 +1,44 @@
1
1
  # @nice2dev/icons — Changelog
2
2
 
3
+ ## 1.3.4
4
+
5
+ ### Patch Changes
6
+
7
+ - 15f3a18: Icon browser feedback, round 34:
8
+
9
+ - Twice the stroke width in every variant but `outline`:
10
+ - `NtdMusic`: the stems move left so they still end flush with the note heads.
11
+ - `NtdClock`: the hands.
12
+ - `NtdShare`: the links.
13
+ - `NtdRepeat`: shafts and heads, redrawn tighter so they stay in the box; the shafts stop
14
+ short of the heads' points, so nothing sticks out in `sharp`.
15
+ - `NtdRefresh`: smaller heads, each pointing at the start of the other arrow's tail with a
16
+ clear gap.
17
+ - `NtdWifi`: the inner arc sits further from the dot, the arcs closer together.
18
+ - `NtdList`: dots a quarter smaller.
19
+ - Colours:
20
+ - `NtdHeart`: vivid outlines the split heart in the accent colour instead of an accent seam.
21
+ - `NtdBellRing`: the ring marks are primary when filled, accent in vivid.
22
+ - `NtdBriefcase`: the clasp is in the accent colour with a primary lock square.
23
+ - `NtdSmartphone`: filled, a primary frame round an accent screen with a primary button.
24
+ - Shapes:
25
+ - `NtdBook`: a notch in the right edge beside the pages, leaving a narrow strip of cover.
26
+ - `NtdNotebook`: a wider, shorter cover.
27
+ - `NtdAward`: the ribbon's inside between the two earlier sizes.
28
+ - `NtdApartment`: a thin primary sill under the door when filled.
29
+ - `NtdBus`: a front view with a big windscreen, the driver, headlights and rectangular wheels.
30
+ - `NtdBrush`: redrawn as a paintbrush — handle, ferrule and pointed bristles.
31
+ - Hardcoded colours (`#3B82F6`, white) are gone from `NtdShare` and `NtdRepeat`.
32
+
33
+ - 4fae5a4: `NtdHourglass` and the `turn` animation:
34
+
35
+ - `NtdHourglass`: two plates and a curved glass, the sand running from the top bulb through a
36
+ thread onto a pile in the bottom one. `NiceIcon` resolves it as `hourglass`.
37
+ - `animation="turn"` works on every icon: it turns the icon upside down, holds, turns it back
38
+ and holds again. On `NtdHourglass` the sand pours during the holds, in step with the turns.
39
+ - `animationDuration` now also sets the `--ntd-anim-duration` CSS variable, so parts an icon
40
+ animates inside itself (the hourglass sand) keep the same duration.
41
+
3
42
  ## 1.3.3
4
43
 
5
44
  ### Patch Changes
package/README.md CHANGED
@@ -193,6 +193,14 @@ Apply an animation by name:
193
193
 
194
194
  Each animation maps to a CSS class `.ntd-anim-{name}` defined in `animations.css` (auto-imported).
195
195
 
196
+ `turn` turns any icon upside down, holds, turns it back and holds again. On `NtdHourglass` the
197
+ sand pours while it holds, in step with the turns at any `animationDuration`:
198
+
199
+ ```tsx
200
+ <NtdHourglass animation="turn" />
201
+ <NtdHourglass animation="turn" animationDuration="6s" />
202
+ ```
203
+
196
204
  See [Full Animation Catalog](#full-animation-catalog) for the complete list.
197
205
 
198
206
  ---
@@ -406,9 +414,9 @@ Properties passed to every path renderer (pre-resolved from user props):
406
414
 
407
415
  `NtdSearch` · `NtdEdit` · `NtdTrash` · `NtdSave` · `NtdDownload` · `NtdUpload` · `NtdShare` · `NtdCopy` · `NtdClipboard` · `NtdPlus` · `NtdMinus` · `NtdCheck` · `NtdFilter` · `NtdSort` · `NtdPrint` · `NtdZoomIn` · `NtdZoomOut` · `NtdUndo` · `NtdRedo` · `NtdLink` · `NtdSettings` · `NtdLogIn` · `NtdLogOut` · `NtdLock` · `NtdUnlock`
408
416
 
409
- ### UI & Status (26 icons)
417
+ ### UI & Status (27 icons)
410
418
 
411
- `NtdHome` · `NtdUser` · `NtdUsers` · `NtdHeart` · `NtdStar` · `NtdBell` · `NtdEye` · `NtdEyeOff` · `NtdInfo` · `NtdWarning` · `NtdError` · `NtdSuccess` · `NtdHelp` · `NtdClock` · `NtdCalendar` · `NtdTag` · `NtdBookmark` · `NtdFlag` · `NtdThumbUp` · `NtdThumbDown` · `NtdShield` · `NtdGlobe` · `NtdMap` · `NtdPin` · `NtdSun` · `NtdMoon`
419
+ `NtdHome` · `NtdUser` · `NtdUsers` · `NtdHeart` · `NtdStar` · `NtdBell` · `NtdEye` · `NtdEyeOff` · `NtdInfo` · `NtdWarning` · `NtdError` · `NtdSuccess` · `NtdHelp` · `NtdClock` · `NtdHourglass` · `NtdCalendar` · `NtdTag` · `NtdBookmark` · `NtdFlag` · `NtdThumbUp` · `NtdThumbDown` · `NtdShield` · `NtdGlobe` · `NtdMap` · `NtdPin` · `NtdSun` · `NtdMoon`
412
420
 
413
421
  ### Media & Communication (19 icons)
414
422
 
@@ -466,9 +474,9 @@ Properties passed to every path renderer (pre-resolved from user props):
466
474
 
467
475
  ## Full Animation Catalog
468
476
 
469
- ### Core Transforms (13)
477
+ ### Core Transforms (14)
470
478
 
471
- `spin` · `spin-reverse` · `pulse` · `bounce` · `shake` · `float` · `flip` · `glow` · `wiggle` · `rubber` · `swing` · `tada` · `heartbeat`
479
+ `spin` · `spin-reverse` · `pulse` · `bounce` · `shake` · `float` · `flip` · `glow` · `wiggle` · `rubber` · `swing` · `tada` · `heartbeat` · `turn`
472
480
 
473
481
  ### Entrance Animations (22)
474
482
 
@@ -189,7 +189,10 @@ function createIcon(options) {
189
189
  ? `transform ${transition}`
190
190
  : undefined;
191
191
  const animStyle = {
192
- ...(animationDuration ? { animationDuration } : {}),
192
+ // the variable carries the duration to the parts an icon animates inside itself
193
+ ...(animationDuration
194
+ ? { animationDuration, '--ntd-anim-duration': animationDuration }
195
+ : {}),
193
196
  ...(transformString ? { transform: transformString } : {}),
194
197
  ...(transformString ? { transformOrigin } : {}),
195
198
  ...(transitionValue ? { transition: transitionValue } : {}),
@@ -106,6 +106,7 @@ function exportIconToSvgString(svgElement, options = {}) {
106
106
  clone.style.animation = '';
107
107
  clone.style.animationName = '';
108
108
  clone.style.animationDuration = '';
109
+ clone.style.removeProperty('--ntd-anim-duration');
109
110
  // Remove SMIL animation elements
110
111
  clone.querySelectorAll('animate, animateTransform, animateMotion').forEach((el) => el.remove());
111
112
  }
@@ -35,17 +35,18 @@ const BELL_CLAPPER_LINE = 'M9 19a3 3 0 006 0';
35
35
  const BELL_RINGS = 'M2 4l1.5 1.5M22 4l-1.5 1.5';
36
36
  /**
37
37
  * NtdBell and NtdBellRing, so the two share one bell; `ringing` adds the ring marks. Duotone and
38
- * vivid are fills only: the bell primary, the clapper (and the marks) secondary.
38
+ * vivid are fills only: the bell primary, the clapper secondary. The marks are primary on the solid
39
+ * bell, secondary in duotone and in the accent colour in vivid.
39
40
  */
40
41
  function bellIcon(displayName, ringing) {
41
- const parts = ({ primaryColor, secondaryColor, strokeWidth }, detail) => (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx("path", { d: BELL, fill: primaryColor }), jsxRuntime.jsx("path", { d: BELL_CLAPPER, fill: detail }), ringing && jsxRuntime.jsx("path", { d: BELL_RINGS, stroke: secondaryColor, strokeWidth: strokeWidth })] }));
42
+ const parts = ({ primaryColor, strokeWidth }, detail, rings, ringsOpacity = 1) => (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx("path", { d: BELL, fill: primaryColor }), jsxRuntime.jsx("path", { d: BELL_CLAPPER, fill: detail }), ringing && (jsxRuntime.jsx("path", { d: BELL_RINGS, stroke: rings, strokeWidth: strokeWidth, opacity: ringsOpacity }))] }));
42
43
  return createIcon.createIcon({
43
44
  displayName,
44
45
  paths: {
45
- solid: (props) => parts(props, props.primaryColor),
46
+ solid: (props) => parts(props, props.primaryColor, props.primaryColor),
46
47
  outline: ({ primaryColor, strokeWidth }) => (jsxRuntime.jsx("path", { d: `${BELL}${BELL_CLAPPER_LINE}${ringing ? BELL_RINGS : ''}`, stroke: primaryColor, strokeWidth: strokeWidth, fill: "none" })),
47
- duotone: (props) => parts(props, props.secondaryColor),
48
- vivid: (props) => parts(props, props.secondaryColor),
48
+ duotone: (props) => parts(props, props.secondaryColor, props.secondaryColor),
49
+ vivid: (props) => parts(props, props.secondaryColor, props.accentColor, props.accentOpacity),
49
50
  },
50
51
  });
51
52
  }
@@ -104,13 +104,21 @@ const NtdUpload = /* @__PURE__ */ createIcon.createIcon({
104
104
  vivid: ({ primaryColor, secondaryColor, strokeWidth }) => (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx("path", { d: TRAY, stroke: secondaryColor, strokeWidth: strokeWidth * 2 }), jsxRuntime.jsx("path", { d: "M17 8l-5-5-5 5M12 5v10", stroke: primaryColor, strokeWidth: strokeWidth * 2 })] })),
105
105
  },
106
106
  });
107
+ // NtdShare: three nodes joined by two links, the links twice the stroke width in every variant but
108
+ // `outline`. Duotone and vivid, fills only: the nodes primary, the links secondary (vivid had a
109
+ // fixed #3B82F6 node and white links that vanished on a light page).
110
+ const SHARE_NODES = 'M18 2a3 3 0 110 6 3 3 0 110-6zM6 9a3 3 0 110 6 3 3 0 110-6zM18 16a3 3 0 110 6 3 3 0 110-6z';
111
+ const SHARE_LINKS = 'M8.59 13.51L15.42 17.49M15.41 6.51L8.59 10.49';
112
+ function shareFilled(nodes, links, strokeWidth) {
113
+ return (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx("path", { d: SHARE_LINKS, stroke: links, strokeWidth: strokeWidth * 2 }), jsxRuntime.jsx("path", { d: SHARE_NODES, fill: nodes })] }));
114
+ }
107
115
  const NtdShare = /* @__PURE__ */ createIcon.createIcon({
108
116
  displayName: 'NtdShare',
109
117
  paths: {
110
- solid: ({ primaryColor, strokeWidth }) => (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx("circle", { cx: "18", cy: "5", r: "3", fill: primaryColor }), jsxRuntime.jsx("circle", { cx: "6", cy: "12", r: "3", fill: primaryColor }), jsxRuntime.jsx("circle", { cx: "18", cy: "19", r: "3", fill: primaryColor }), jsxRuntime.jsx("line", { x1: "8.59", y1: "13.51", x2: "15.42", y2: "17.49", stroke: primaryColor, strokeWidth: strokeWidth }), jsxRuntime.jsx("line", { x1: "15.41", y1: "6.51", x2: "8.59", y2: "10.49", stroke: primaryColor, strokeWidth: strokeWidth })] })),
118
+ solid: ({ primaryColor, strokeWidth }) => shareFilled(primaryColor, primaryColor, strokeWidth),
111
119
  outline: ({ primaryColor, strokeWidth }) => (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx("circle", { cx: "18", cy: "5", r: "2.5", stroke: primaryColor, strokeWidth: strokeWidth * 0.75, fill: "none" }), jsxRuntime.jsx("circle", { cx: "6", cy: "12", r: "2.5", stroke: primaryColor, strokeWidth: strokeWidth * 0.75, fill: "none" }), jsxRuntime.jsx("circle", { cx: "18", cy: "19", r: "2.5", stroke: primaryColor, strokeWidth: strokeWidth * 0.75, fill: "none" }), jsxRuntime.jsx("line", { x1: "8.59", y1: "13.51", x2: "15.42", y2: "17.49", stroke: primaryColor, strokeWidth: strokeWidth * 0.75 }), jsxRuntime.jsx("line", { x1: "15.41", y1: "6.51", x2: "8.59", y2: "10.49", stroke: primaryColor, strokeWidth: strokeWidth * 0.75 })] })),
112
- duotone: ({ primaryColor, secondaryColor, secondaryOpacity, strokeWidth }) => (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx("circle", { cx: "18", cy: "5", r: "3", fill: secondaryColor, opacity: secondaryOpacity }), jsxRuntime.jsx("circle", { cx: "6", cy: "12", r: "3", fill: secondaryColor, opacity: secondaryOpacity }), jsxRuntime.jsx("circle", { cx: "18", cy: "19", r: "3", fill: secondaryColor, opacity: secondaryOpacity }), jsxRuntime.jsx("circle", { cx: "18", cy: "5", r: "2.5", stroke: primaryColor, strokeWidth: strokeWidth * 0.75, fill: "none" }), jsxRuntime.jsx("circle", { cx: "6", cy: "12", r: "2.5", stroke: primaryColor, strokeWidth: strokeWidth * 0.75, fill: "none" }), jsxRuntime.jsx("circle", { cx: "18", cy: "19", r: "2.5", stroke: primaryColor, strokeWidth: strokeWidth * 0.75, fill: "none" }), jsxRuntime.jsx("line", { x1: "8.59", y1: "13.51", x2: "15.42", y2: "17.49", stroke: primaryColor, strokeWidth: strokeWidth * 0.75 }), jsxRuntime.jsx("line", { x1: "15.41", y1: "6.51", x2: "8.59", y2: "10.49", stroke: primaryColor, strokeWidth: strokeWidth * 0.75 })] })),
113
- vivid: ({ primaryColor, secondaryColor }) => (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx("circle", { cx: "18", cy: "5", r: "3", fill: primaryColor }), jsxRuntime.jsx("circle", { cx: "18", cy: "5", r: "3", fill: "white", opacity: "0.08" }), jsxRuntime.jsx("circle", { cx: "6", cy: "12", r: "3", fill: secondaryColor }), jsxRuntime.jsx("circle", { cx: "18", cy: "19", r: "3", fill: "#3B82F6" }), jsxRuntime.jsx("line", { x1: "8.59", y1: "13.51", x2: "15.42", y2: "17.49", stroke: "white", strokeWidth: "1" }), jsxRuntime.jsx("line", { x1: "15.41", y1: "6.51", x2: "8.59", y2: "10.49", stroke: "white", strokeWidth: "1" })] })),
120
+ duotone: ({ primaryColor, secondaryColor, strokeWidth }) => shareFilled(primaryColor, secondaryColor, strokeWidth),
121
+ vivid: ({ primaryColor, secondaryColor, strokeWidth }) => shareFilled(primaryColor, secondaryColor, strokeWidth),
114
122
  },
115
123
  });
116
124
  const NtdCopy = /* @__PURE__ */ createIcon.createIcon({
@@ -5,21 +5,22 @@ var createIcon = require('../createIcon.js');
5
5
  var iconParts = require('../iconParts.js');
6
6
 
7
7
  // The band sits halfway down the case and is a cut through it: kept inside the case it meets the
8
- // sides flush (its round caps stuck out of both). A clasp hangs from its middle: low and wide,
9
- // secondary on the filled case (the accent colour in vivid, its third colour).
8
+ // sides flush (its round caps stuck out of both). A clasp hangs from its middle: low and wide, in
9
+ // the accent colour like the band on the filled case (secondary in duotone), with a primary lock
10
+ // square in it where it had a slot showing the band through.
10
11
  const BRIEFCASE_CASE = { x: 2, y: 7, width: 20, height: 14, rx: 2 };
11
12
  const BRIEFCASE_HANDLE = 'M16 7V5a2 2 0 00-2-2h-4a2 2 0 00-2 2v2';
12
- /** The clasp over the band, hanging down from it, with its slot (even-odd). */
13
+ /** The clasp over the band, hanging down from it. */
13
14
  const BRIEFCASE_CLASP = 'M10.6 11.3h2.8a.8.8 0 01.8.8v2.6a.8.8 0 01-.8.8h-2.8a.8.8 0 01-.8-.8v-2.6a.8.8 0 01.8-.8z';
14
- const BRIEFCASE_SLOT = 'M11.2 13.2h1.6v.9h-1.6z';
15
+ const BRIEFCASE_LOCK = { x: 11.2, y: 12.6, width: 1.6, height: 1.6 };
15
16
  const NtdBriefcase = /* @__PURE__ */ createIcon.createIcon({
16
17
  displayName: 'NtdBriefcase',
17
18
  paths: {
18
- solid: (props) => (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx("rect", { ...BRIEFCASE_CASE, fill: props.primaryColor }), jsxRuntime.jsx("path", { d: BRIEFCASE_HANDLE, stroke: props.primaryColor, strokeWidth: props.strokeWidth, fill: "none" }), iconParts.within(props.uid, 'band', jsxRuntime.jsx("rect", { ...BRIEFCASE_CASE }), jsxRuntime.jsx("line", { x1: "2", y1: "12.5", x2: "22", y2: "12.5", stroke: props.accentColor, strokeWidth: "1.5", opacity: props.accentOpacity })), jsxRuntime.jsx("path", { d: `${BRIEFCASE_CLASP}${BRIEFCASE_SLOT}`, fillRule: "evenodd", fill: iconParts.detailColor(props) })] })),
19
+ solid: (props) => (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx("rect", { ...BRIEFCASE_CASE, fill: props.primaryColor }), jsxRuntime.jsx("path", { d: BRIEFCASE_HANDLE, stroke: props.primaryColor, strokeWidth: props.strokeWidth, fill: "none" }), iconParts.within(props.uid, 'band', jsxRuntime.jsx("rect", { ...BRIEFCASE_CASE }), jsxRuntime.jsx("line", { x1: "2", y1: "12.5", x2: "22", y2: "12.5", stroke: props.accentColor, strokeWidth: "1.5", opacity: props.accentOpacity })), jsxRuntime.jsx("path", { d: BRIEFCASE_CLASP, fill: props.accentColor, opacity: props.accentOpacity }), jsxRuntime.jsx("rect", { ...BRIEFCASE_LOCK, fill: props.primaryColor })] })),
19
20
  outline: ({ primaryColor, strokeWidth }) => (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx("rect", { ...BRIEFCASE_CASE, stroke: primaryColor, strokeWidth: strokeWidth, fill: "none" }), jsxRuntime.jsx("path", { d: BRIEFCASE_HANDLE, stroke: primaryColor, strokeWidth: strokeWidth, fill: "none" }), jsxRuntime.jsx("line", { x1: "2", y1: "12.5", x2: "22", y2: "12.5", stroke: primaryColor, strokeWidth: "1.5" }), jsxRuntime.jsx("path", { d: BRIEFCASE_CLASP, fill: primaryColor })] })),
20
21
  // fills only: the case and the handle primary, the band and the clasp secondary
21
- duotone: ({ primaryColor, secondaryColor, strokeWidth, uid }) => (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx("rect", { ...BRIEFCASE_CASE, fill: primaryColor }), jsxRuntime.jsx("path", { d: BRIEFCASE_HANDLE, stroke: primaryColor, strokeWidth: strokeWidth, fill: "none" }), iconParts.within(uid, 'band', jsxRuntime.jsx("rect", { ...BRIEFCASE_CASE }), jsxRuntime.jsx("line", { x1: "2", y1: "12.5", x2: "22", y2: "12.5", stroke: secondaryColor, strokeWidth: "1.5" })), jsxRuntime.jsx("path", { d: `${BRIEFCASE_CLASP}${BRIEFCASE_SLOT}`, fillRule: "evenodd", fill: secondaryColor })] })),
22
- vivid: ({ primaryColor, secondaryColor, accentColor, accentOpacity, strokeWidth, uid }) => (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx("rect", { ...BRIEFCASE_CASE, fill: primaryColor }), jsxRuntime.jsx("path", { d: BRIEFCASE_HANDLE, stroke: secondaryColor, strokeWidth: strokeWidth, fill: "none" }), iconParts.within(uid, 'band', jsxRuntime.jsx("rect", { ...BRIEFCASE_CASE }), jsxRuntime.jsx("line", { x1: "2", y1: "12.5", x2: "22", y2: "12.5", stroke: secondaryColor, strokeWidth: "1.5" })), jsxRuntime.jsx("path", { d: `${BRIEFCASE_CLASP}${BRIEFCASE_SLOT}`, fillRule: "evenodd", fill: accentColor, opacity: accentOpacity })] })),
22
+ duotone: ({ primaryColor, secondaryColor, strokeWidth, uid }) => (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx("rect", { ...BRIEFCASE_CASE, fill: primaryColor }), jsxRuntime.jsx("path", { d: BRIEFCASE_HANDLE, stroke: primaryColor, strokeWidth: strokeWidth, fill: "none" }), iconParts.within(uid, 'band', jsxRuntime.jsx("rect", { ...BRIEFCASE_CASE }), jsxRuntime.jsx("line", { x1: "2", y1: "12.5", x2: "22", y2: "12.5", stroke: secondaryColor, strokeWidth: "1.5" })), jsxRuntime.jsx("path", { d: BRIEFCASE_CLASP, fill: secondaryColor }), jsxRuntime.jsx("rect", { ...BRIEFCASE_LOCK, fill: primaryColor })] })),
23
+ vivid: ({ primaryColor, secondaryColor, accentColor, accentOpacity, strokeWidth, uid }) => (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx("rect", { ...BRIEFCASE_CASE, fill: primaryColor }), jsxRuntime.jsx("path", { d: BRIEFCASE_HANDLE, stroke: secondaryColor, strokeWidth: strokeWidth, fill: "none" }), iconParts.within(uid, 'band', jsxRuntime.jsx("rect", { ...BRIEFCASE_CASE }), jsxRuntime.jsx("line", { x1: "2", y1: "12.5", x2: "22", y2: "12.5", stroke: secondaryColor, strokeWidth: "1.5" })), jsxRuntime.jsx("path", { d: BRIEFCASE_CLASP, fill: accentColor, opacity: accentOpacity }), jsxRuntime.jsx("rect", { ...BRIEFCASE_LOCK, fill: primaryColor })] })),
23
24
  },
24
25
  });
25
26
  // NtdDollar: a line glyph, twice the stroke width in every variant but `outline`; the stem runs
@@ -46,14 +46,17 @@ const NtdUniversity = /* @__PURE__ */ createIcon.createIcon({
46
46
  LEARNING TOOLS
47
47
  ───────────────────────────────────────────────────────────────────────────── */
48
48
  // NtdBook: a closed book, not a page — the rounded spine on the left, the block of pages showing
49
- // at the bottom between the front cover and the line of the back cover. Down the right edge it is
50
- // cover, then the pages set in 2.5 from that edge (the cover showing beside them), then cover
51
- // again; the outline marks where the pages end with a line. The cover is plain, so another glyph
52
- // can sit on it; NtdBookBookmark adds a ribbon.
53
- const BOOK_SILHOUETTE = 'M7 2h12a1 1 0 011 1v17a1 1 0 01-1 1H7a2.5 2.5 0 01-2.5-2.5v-14A2.5 2.5 0 017 2z';
54
- const BOOK_PAGES = 'M6.6 17.6h10.9v2.3H6.6a1.15 1.15 0 010-2.3z';
49
+ // at the bottom between the front cover and the back cover. Down the right edge it is cover, then
50
+ // a notch cut in 0.9 at the pages, then cover again: beside the pages only a narrow strip of cover
51
+ // is left (it was a 2.5 wide bar). The outline ends the pages with a line short of the edge, the back
52
+ // cover running on under the notch. The cover is plain, so another glyph can sit on it;
53
+ // NtdBookBookmark adds a ribbon.
54
+ const BOOK_SILHOUETTE = 'M7 2h12a1 1 0 011 1v14.2h-.9v2.1H20v.7a1 1 0 01-1 1H7a2.5 2.5 0 01-2.5-2.5v-14A2.5 2.5 0 017 2z';
55
+ const BOOK_PAGES = 'M6.6 17.2h11.4v2.1H6.6a1.05 1.05 0 010-2.1z';
55
56
  const BOOK_RIBBON = 'M9.5 2v6.5l1.75-1.3L13 8.5V2z';
56
- const BOOK_OUTLINE = 'M4.5 18.5v-14A2.5 2.5 0 017 2h12a1 1 0 011 1v17a1 1 0 01-1 1H7a2.5 2.5 0 010-5h13M17.5 16v5';
57
+ const BOOK_OUTLINE = 'M4.5 18.5v-14A2.5 2.5 0 017 2h12a1 1 0 011 1v13H7a2.5 2.5 0 000 5h13M18.7 16v5';
58
+ /** The inside of the outline, for duotone's fill under it. */
59
+ const BOOK_OUTLINE_FILL = 'M7 2h12a1 1 0 011 1v13h-1.3v5H7a2.5 2.5 0 01-2.5-2.5v-14A2.5 2.5 0 017 2z';
57
60
  /** The book, with the ribbon bookmark or without it. */
58
61
  function bookIcon(displayName, ribbon) {
59
62
  return createIcon.createIcon({
@@ -61,7 +64,7 @@ function bookIcon(displayName, ribbon) {
61
64
  paths: {
62
65
  solid: ({ primaryColor, accentColor, accentOpacity }) => (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx("path", { d: BOOK_SILHOUETTE, fill: primaryColor }), jsxRuntime.jsxs("g", { fill: accentColor, opacity: accentOpacity, children: [jsxRuntime.jsx("path", { d: BOOK_PAGES }), ribbon && jsxRuntime.jsx("path", { d: BOOK_RIBBON })] })] })),
63
66
  outline: ({ primaryColor, strokeWidth }) => (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx("path", { d: BOOK_OUTLINE, stroke: primaryColor, strokeWidth: strokeWidth, fill: "none" }), ribbon && (jsxRuntime.jsx("path", { d: "M9.5 2.5v6l1.75-1.3L13 8.5v-6", stroke: primaryColor, strokeWidth: strokeWidth * 0.75, fill: "none" }))] })),
64
- duotone: ({ primaryColor, secondaryColor, secondaryOpacity, strokeWidth }) => (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx("path", { d: BOOK_SILHOUETTE, fill: secondaryColor, opacity: secondaryOpacity }), jsxRuntime.jsx("path", { d: BOOK_OUTLINE, stroke: primaryColor, strokeWidth: strokeWidth, fill: "none" }), ribbon && jsxRuntime.jsx("path", { d: BOOK_RIBBON, fill: primaryColor })] })),
67
+ duotone: ({ primaryColor, secondaryColor, secondaryOpacity, strokeWidth }) => (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx("path", { d: BOOK_OUTLINE_FILL, fill: secondaryColor, opacity: secondaryOpacity }), jsxRuntime.jsx("path", { d: BOOK_OUTLINE, stroke: primaryColor, strokeWidth: strokeWidth, fill: "none" }), ribbon && jsxRuntime.jsx("path", { d: BOOK_RIBBON, fill: primaryColor })] })),
65
68
  vivid: ({ primaryColor, secondaryColor, accentColor, accentOpacity }) => (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx("path", { d: BOOK_SILHOUETTE, fill: primaryColor }), jsxRuntime.jsx("path", { d: BOOK_PAGES, fill: accentColor, opacity: accentOpacity }), ribbon && jsxRuntime.jsx("path", { d: BOOK_RIBBON, fill: secondaryColor })] })),
66
69
  },
67
70
  });
@@ -78,12 +81,13 @@ const NtdOpenBook = /* @__PURE__ */ createIcon.createIcon({
78
81
  },
79
82
  });
80
83
  // NtdNotebook: a cover with short binder rings across its left edge (they stuck out further) and
81
- // three lines of writing — in the accent colour when filled, as the outline draws them. Duotone,
82
- // fills only: the cover primary, the rings and the writing secondary; vivid: the rings secondary,
83
- // the writing in the accent colour.
84
- const NOTEBOOK_COVER = { x: 5, y: 2, width: 15, height: 20, rx: 2 };
85
- const NOTEBOOK_RINGS = 'M3.5 6h3M3.5 10h3M3.5 14h3M3.5 18h3';
86
- const NOTEBOOK_TEXT = 'M9 7h7M9 11h7M9 15h4';
84
+ // three lines of writing — in the accent colour when filled, as the outline draws them. The cover
85
+ // is 16.5 × 19 (it was 15 × 20, tall and slim for an exercise book). Duotone, fills only: the
86
+ // cover primary, the rings and the writing secondary; vivid: the rings secondary, the writing in
87
+ // the accent colour.
88
+ const NOTEBOOK_COVER = { x: 4.5, y: 2.5, width: 16.5, height: 19, rx: 2 };
89
+ const NOTEBOOK_RINGS = 'M3 6h3M3 10h3M3 14h3M3 18h3';
90
+ const NOTEBOOK_TEXT = 'M9 7.5h8.5M9 11.5h8.5M9 15.5h4.5';
87
91
  const NtdNotebook = /* @__PURE__ */ createIcon.createIcon({
88
92
  displayName: 'NtdNotebook',
89
93
  paths: {
@@ -153,12 +153,12 @@ const NtdGrid = /* @__PURE__ */ createIcon.createIcon({
153
153
  vivid: ({ primaryColor, secondaryColor }) => (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx("rect", { x: "3", y: "3", width: "7", height: "7", rx: "1.5", fill: primaryColor }), jsxRuntime.jsx("rect", { x: "3", y: "3", width: "7", height: "7", rx: "1.5", fill: "white", opacity: "0.08" }), jsxRuntime.jsx("rect", { x: "14", y: "3", width: "7", height: "7", rx: "1.5", fill: secondaryColor }), jsxRuntime.jsx("rect", { x: "3", y: "14", width: "7", height: "7", rx: "1.5", fill: "#3B82F6" }), jsxRuntime.jsx("rect", { x: "14", y: "14", width: "7", height: "7", rx: "1.5", fill: "#F59E0B" })] })),
154
154
  },
155
155
  });
156
- // NtdList: in every variant but `outline` the lines are 1.5 × the stroke width and the dots r 2.25
157
- // — half again as heavy as they were; the lines start at 9 to keep clear of the bigger dots.
156
+ // NtdList: in every variant but `outline` the lines are 1.5 × the stroke width and the dots r 1.7
157
+ // (r 2.25 was too big, a quarter smaller); the lines start at 9 to keep clear of the dots.
158
158
  // Duotone and vivid: the lines primary, the dots secondary.
159
159
  const LIST_LINES = 'M9 6h12M9 12h12M9 18h12';
160
160
  function listFilled(lines, dots, strokeWidth) {
161
- return (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx("path", { d: LIST_LINES, stroke: lines, strokeWidth: strokeWidth * 1.5 }), jsxRuntime.jsxs("g", { fill: dots, children: [jsxRuntime.jsx("circle", { cx: "3.75", cy: "6", r: "2.25" }), jsxRuntime.jsx("circle", { cx: "3.75", cy: "12", r: "2.25" }), jsxRuntime.jsx("circle", { cx: "3.75", cy: "18", r: "2.25" })] })] }));
161
+ return (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx("path", { d: LIST_LINES, stroke: lines, strokeWidth: strokeWidth * 1.5 }), jsxRuntime.jsxs("g", { fill: dots, children: [jsxRuntime.jsx("circle", { cx: "3.75", cy: "6", r: "1.7" }), jsxRuntime.jsx("circle", { cx: "3.75", cy: "12", r: "1.7" }), jsxRuntime.jsx("circle", { cx: "3.75", cy: "18", r: "1.7" })] })] }));
162
162
  }
163
163
  const NtdList = /* @__PURE__ */ createIcon.createIcon({
164
164
  displayName: 'NtdList',
@@ -178,10 +178,12 @@ const NtdTable = /* @__PURE__ */ createIcon.createIcon({
178
178
  vivid: ({ primaryColor, secondaryColor }) => (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx("rect", { x: "3", y: "3", width: "18", height: "18", rx: "2", fill: primaryColor, opacity: "0.15", stroke: primaryColor, strokeWidth: "2" }), jsxRuntime.jsx("rect", { x: "3", y: "3", width: "18", height: "18", rx: "2", fill: "white", opacity: "0.1" }), jsxRuntime.jsx("line", { x1: "3", y1: "9", x2: "21", y2: "9", stroke: secondaryColor, strokeWidth: "1.8" }), jsxRuntime.jsx("line", { x1: "3", y1: "15", x2: "21", y2: "15", stroke: "#3B82F6", strokeWidth: "1.5" }), jsxRuntime.jsx("line", { x1: "9", y1: "3", x2: "9", y2: "21", stroke: "#3B82F6", strokeWidth: "1.5" })] })),
179
179
  },
180
180
  });
181
+ // NtdSmartphone: filled, the case stays a primary frame round a screen in the accent colour, and
182
+ // the button is a primary dot on the screen — bigger and lower than the accent dot it was.
181
183
  const NtdSmartphone = /* @__PURE__ */ createIcon.createIcon({
182
184
  displayName: 'NtdSmartphone',
183
185
  paths: {
184
- solid: ({ primaryColor, accentColor, accentOpacity, strokeWidth }) => (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx("rect", { x: "5", y: "2", width: "14", height: "20", rx: "2", fill: primaryColor }), jsxRuntime.jsx("line", { x1: "12", y1: "18", x2: "12.01", y2: "18", stroke: accentColor, strokeWidth: strokeWidth, opacity: accentOpacity })] })),
186
+ solid: ({ primaryColor, accentColor, accentOpacity }) => (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx("rect", { x: "5", y: "2", width: "14", height: "20", rx: "2", fill: primaryColor }), jsxRuntime.jsx("rect", { x: "6.5", y: "3.5", width: "11", height: "17", rx: "0.75", fill: accentColor, opacity: accentOpacity }), jsxRuntime.jsx("circle", { cx: "12", cy: "18.4", r: "1.25", fill: primaryColor })] })),
185
187
  outline: ({ primaryColor, strokeWidth }) => (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx("rect", { x: "5", y: "2", width: "14", height: "20", rx: "2", stroke: primaryColor, strokeWidth: strokeWidth, fill: "none" }), jsxRuntime.jsx("line", { x1: "12", y1: "18", x2: "12.01", y2: "18", stroke: primaryColor, strokeWidth: strokeWidth })] })),
186
188
  duotone: ({ primaryColor, secondaryColor, secondaryOpacity, strokeWidth }) => (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx("rect", { x: "5", y: "2", width: "14", height: "20", rx: "2", fill: secondaryColor, opacity: secondaryOpacity }), jsxRuntime.jsx("rect", { x: "5", y: "2", width: "14", height: "20", rx: "2", stroke: primaryColor, strokeWidth: strokeWidth, fill: "none" }), jsxRuntime.jsx("line", { x1: "12", y1: "18", x2: "12.01", y2: "18", stroke: primaryColor, strokeWidth: strokeWidth })] })),
187
189
  vivid: ({ primaryColor, secondaryColor }) => (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx("rect", { x: "5", y: "2", width: "14", height: "20", rx: "2", fill: primaryColor }), jsxRuntime.jsx("rect", { x: "5", y: "2", width: "14", height: "20", rx: "2", fill: "white", opacity: "0.1" }), jsxRuntime.jsx("line", { x1: "12", y1: "18", x2: "12.01", y2: "18", stroke: secondaryColor, strokeWidth: "1.8" })] })),
@@ -230,11 +232,11 @@ const NtdKey = /* @__PURE__ */ createIcon.createIcon({
230
232
  },
231
233
  });
232
234
  // NtdAward: the ribbon has a secondary inside within its primary edge (it was open, so the page
233
- // showed through), and goes under the medal. The inside is the ribbon inset by 2 — it filled the
234
- // ribbon almost to its edge. Duotone is the same; vivid draws the ribbon's edge in the accent
235
- // colour.
235
+ // showed through), and goes under the medal. The inside is the ribbon inset by 1.5 — between the
236
+ // half stroke it filled to before (too full) and the 2 after (too small). Duotone is the same;
237
+ // vivid draws the ribbon's edge in the accent colour.
236
238
  const AWARD_RIBBON = 'M8.21 13.89L7 23l5-3 5 3-1.21-9.12';
237
- const AWARD_RIBBON_INNER = 'M10.17 14.3L13.83 14.3L14.47 19.15L12 17.67L9.53 19.15z';
239
+ const AWARD_RIBBON_INNER = 'M9.67 14.3L8.9 20.11L12 18.25L15.1 20.11L14.32 14.3z';
238
240
  function awardFilled({ primaryColor, secondaryColor, strokeWidth }, ribbonEdge) {
239
241
  return (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx("path", { d: AWARD_RIBBON, fill: ribbonEdge, stroke: ribbonEdge, strokeWidth: strokeWidth }), jsxRuntime.jsx("path", { d: AWARD_RIBBON_INNER, fill: secondaryColor }), jsxRuntime.jsx("circle", { cx: "12", cy: "8", r: "7", fill: primaryColor })] }));
240
242
  }
@@ -91,6 +91,7 @@ exports.NtdGlobe = ui.NtdGlobe;
91
91
  exports.NtdHeart = ui.NtdHeart;
92
92
  exports.NtdHelp = ui.NtdHelp;
93
93
  exports.NtdHome = ui.NtdHome;
94
+ exports.NtdHourglass = ui.NtdHourglass;
94
95
  exports.NtdInfo = ui.NtdInfo;
95
96
  exports.NtdMap = ui.NtdMap;
96
97
  exports.NtdMoon = ui.NtdMoon;
@@ -133,17 +133,30 @@ const NtdMicrophoneOff = /* @__PURE__ */ createIcon.createIcon({
133
133
  // NtdMusic: the note heads are tilted ellipses whose right edge is the stem's right edge, and the
134
134
  // stems end where that edge is vertical, so stem and head meet without a step (the heads stuck
135
135
  // out right of the stems). The outline heads are the filled ones moved in by half a stroke, so
136
- // their stroke meets the stem the same way.
136
+ // their stroke meets the stem the same way. Every variant but `outline` draws the stems and the
137
+ // beam twice the stroke width; the stems move left by the extra half width, so their right edge
138
+ // stays on the heads' (9.3 and 21.3), and the beam drops half a unit to keep a mitred corner in
139
+ // the box.
137
140
  const MUSIC_STEMS = 'M8.3 17.22V5l12-2v12.22';
141
+ /** The stems and the beam for a line `width` wide; `sharp` stops them half a width higher. */
142
+ function musicStems(width, sharp = false) {
143
+ const left = 9.3 - width / 2;
144
+ const right = 21.3 - width / 2;
145
+ const end = sharp ? width / 2 : 0;
146
+ return `M${left} ${17.22 - end}V5.5L${right} 3.5V${15.22 - end}`;
147
+ }
148
+ function musicFilled(stems, heads, strokeWidth, sharp = false) {
149
+ return (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx("path", { d: musicStems(strokeWidth * 2, sharp), stroke: stems, strokeWidth: strokeWidth * 2, fill: "none" }), jsxRuntime.jsx("ellipse", { cx: "5.97", cy: "18", rx: "3.5", ry: "2.3", transform: "rotate(-24 5.97 18)", fill: heads[0] }), jsxRuntime.jsx("ellipse", { cx: "17.97", cy: "16", rx: "3.5", ry: "2.3", transform: "rotate(-24 17.97 16)", fill: heads[1] })] }));
150
+ }
138
151
  const NtdMusic = /* @__PURE__ */ createIcon.createIcon({
139
152
  displayName: 'NtdMusic',
140
153
  paths: {
141
- solid: ({ primaryColor, strokeWidth }) => (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx("path", { d: MUSIC_STEMS, stroke: primaryColor, strokeWidth: strokeWidth, fill: "none" }), jsxRuntime.jsxs("g", { fill: primaryColor, children: [jsxRuntime.jsx("ellipse", { cx: "5.97", cy: "18", rx: "3.5", ry: "2.3", transform: "rotate(-24 5.97 18)" }), jsxRuntime.jsx("ellipse", { cx: "17.97", cy: "16", rx: "3.5", ry: "2.3", transform: "rotate(-24 17.97 16)" })] })] })),
142
- // the stems stop a unit higher: the square caps of `sharp` then end at the heads' edge
143
- sharp: ({ primaryColor, strokeWidth }) => (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx("path", { d: "M8.3 16.22V5l12-2v11.22", stroke: primaryColor, strokeWidth: strokeWidth, fill: "none" }), jsxRuntime.jsxs("g", { fill: primaryColor, children: [jsxRuntime.jsx("ellipse", { cx: "5.97", cy: "18", rx: "3.5", ry: "2.3", transform: "rotate(-24 5.97 18)" }), jsxRuntime.jsx("ellipse", { cx: "17.97", cy: "16", rx: "3.5", ry: "2.3", transform: "rotate(-24 17.97 16)" })] })] })),
154
+ solid: ({ primaryColor, strokeWidth }) => musicFilled(primaryColor, [primaryColor, primaryColor], strokeWidth),
155
+ // the square caps of `sharp` then end at the heads' edge
156
+ sharp: ({ primaryColor, strokeWidth }) => musicFilled(primaryColor, [primaryColor, primaryColor], strokeWidth, true),
144
157
  outline: ({ primaryColor, strokeWidth }) => (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx("path", { d: MUSIC_STEMS, stroke: primaryColor, strokeWidth: strokeWidth, fill: "none" }), jsxRuntime.jsxs("g", { stroke: primaryColor, strokeWidth: strokeWidth, fill: "none", children: [jsxRuntime.jsx("ellipse", { cx: "5.97", cy: "18", rx: "2.5", ry: "1.3", transform: "rotate(-24 5.97 18)" }), jsxRuntime.jsx("ellipse", { cx: "17.97", cy: "16", rx: "2.5", ry: "1.3", transform: "rotate(-24 17.97 16)" })] })] })),
145
- duotone: ({ primaryColor, secondaryColor, secondaryOpacity, strokeWidth }) => (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx("path", { d: "M8.3 5l12-2v12.22", stroke: secondaryColor, strokeWidth: strokeWidth, fill: "none", opacity: secondaryOpacity + 0.2 }), jsxRuntime.jsx("path", { d: MUSIC_STEMS, stroke: primaryColor, strokeWidth: strokeWidth, fill: "none" }), jsxRuntime.jsxs("g", { fill: primaryColor, children: [jsxRuntime.jsx("ellipse", { cx: "5.97", cy: "18", rx: "3.5", ry: "2.3", transform: "rotate(-24 5.97 18)" }), jsxRuntime.jsx("ellipse", { cx: "17.97", cy: "16", rx: "3.5", ry: "2.3", transform: "rotate(-24 17.97 16)" })] })] })),
146
- vivid: ({ primaryColor, secondaryColor, strokeWidth }) => (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx("path", { d: MUSIC_STEMS, stroke: primaryColor, strokeWidth: strokeWidth, fill: "none" }), jsxRuntime.jsx("ellipse", { cx: "5.97", cy: "18", rx: "3.5", ry: "2.3", transform: "rotate(-24 5.97 18)", fill: primaryColor }), jsxRuntime.jsx("ellipse", { cx: "17.97", cy: "16", rx: "3.5", ry: "2.3", transform: "rotate(-24 17.97 16)", fill: secondaryColor })] })),
158
+ duotone: ({ primaryColor, strokeWidth }) => musicFilled(primaryColor, [primaryColor, primaryColor], strokeWidth),
159
+ vivid: ({ primaryColor, secondaryColor, strokeWidth }) => musicFilled(primaryColor, [primaryColor, secondaryColor], strokeWidth),
147
160
  },
148
161
  });
149
162
  // The flap is a cut through the envelope, kept inside it: its ends meet the sides flush (the
@@ -223,12 +236,13 @@ const NtdNotification = /* @__PURE__ */ createIcon.createIcon({
223
236
  vivid: ({ primaryColor, secondaryColor }) => (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx("path", { d: "M18 8A6 6 0 006 8c0 7-3 9-3 9h18s-3-2-3-9z", fill: primaryColor }), jsxRuntime.jsx("path", { d: "M18 8A6 6 0 006 8c0 7-3 9-3 9h18s-3-2-3-9z", fill: "white", opacity: "0.08" }), jsxRuntime.jsx("circle", { cx: "18", cy: "4", r: "3.5", fill: secondaryColor }), jsxRuntime.jsx("path", { d: "M13.73 21a2 2 0 01-3.46 0", stroke: "white", strokeWidth: "1" })] })),
224
237
  },
225
238
  });
226
- // NtdWifi: three arcs round the dot (r 4.4 / 9.1 / 13.8 about 12,19.5, ±45°), 1.5 × the stroke
239
+ // NtdWifi: three arcs round the dot (r 5.2 / 9.5 / 13.8 about 12,19.5, ±45°), 1.5 × the stroke
227
240
  // width in every variant but `outline` — half again as heavy. Concentric, so the heavier arcs keep
228
- // even gaps, and small enough that the outer one's square caps in `sharp` stay in the box.
229
- // Duotone and vivid: the dot and the inner arc primary, the outer arcs secondary.
230
- const WIFI_INNER = 'M8.89 16.39A4.4 4.4 0 0 1 15.11 16.39';
231
- const WIFI_OUTER = 'M5.57 13.07A9.1 9.1 0 0 1 18.43 13.07M2.24 9.74A13.8 13.8 0 0 1 21.76 9.74';
241
+ // even gaps, and small enough that the outer one's square caps in `sharp` stay in the box. The
242
+ // inner arc sits further from the dot (it was r 4.4) and the arcs closer together, the outer one
243
+ // where it was. Duotone and vivid: the dot and the inner arc primary, the outer arcs secondary.
244
+ const WIFI_INNER = 'M8.32 15.82A5.2 5.2 0 0 1 15.68 15.82';
245
+ const WIFI_OUTER = 'M5.28 12.78A9.5 9.5 0 0 1 18.72 12.78M2.24 9.74A13.8 13.8 0 0 1 21.76 9.74';
232
246
  function wifiFilled(near, far, strokeWidth) {
233
247
  return (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx("path", { d: WIFI_OUTER, stroke: far, strokeWidth: strokeWidth * 1.5, fill: "none" }), jsxRuntime.jsx("path", { d: WIFI_INNER, stroke: near, strokeWidth: strokeWidth * 1.5, fill: "none" }), jsxRuntime.jsx("circle", { cx: "12", cy: "19.5", r: "1.5", fill: near })] }));
234
248
  }
@@ -260,13 +274,25 @@ const NtdPalette = /* @__PURE__ */ createIcon.createIcon({
260
274
  vivid: ({ primaryColor, secondaryColor }) => (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx("path", { d: "M12 3a9 9 0 100 18h1a2 2 0 000-4h-1a2 2 0 110-4h1a3 3 0 103-3 3 3 0 01-3-3V6a3 3 0 00-1-3z", fill: primaryColor, opacity: "0.25" }), jsxRuntime.jsx("path", { d: "M12 3a9 9 0 100 18h1a2 2 0 000-4h-1a2 2 0 110-4h1a3 3 0 103-3 3 3 0 01-3-3V6a3 3 0 00-1-3z", fill: "white", opacity: "0.08" }), jsxRuntime.jsx("circle", { cx: "7", cy: "9", r: "1.2", fill: secondaryColor }), jsxRuntime.jsx("circle", { cx: "10", cy: "7", r: "1.2", fill: "#8B5CF6" }), jsxRuntime.jsx("circle", { cx: "7", cy: "13", r: "1.2", fill: "#EF4444" })] })),
261
275
  },
262
276
  });
277
+ // NtdBrush: a paintbrush lying at 45° — a tapering handle with a round end, the metal ferrule, and
278
+ // the bristles swelling out of it to a point at the bottom left (it was a pencil-like wedge with a
279
+ // blob). Filled, the ferrule is set off from the handle and the bristles by two accent cuts.
280
+ // Duotone, fills only: the handle and the ferrule primary, the bristles secondary; vivid puts the
281
+ // ferrule in the accent colour.
282
+ const BRUSH_HANDLE = 'M19.35 2.81A1.3 1.3 0 0 1 21.19 4.65L13.91 12.49L11.51 10.09Z';
283
+ const BRUSH_FERRULE = 'M11.08 9.67L14.33 12.92L11.36 15.89L8.11 12.64Z';
284
+ const BRUSH_BRISTLES = 'M8.11 12.64L11.36 15.89C9.95 18.43 7.76 20.49 2.81 21.19C3.51 16.24 5.57 14.05 8.11 12.64Z';
285
+ const BRUSH_CUTS = 'M10.37 8.96L15.04 13.63M7.4 11.93L12.07 16.6';
286
+ function brushFilled(handle, ferrule, bristles, ferruleOpacity = 1) {
287
+ return (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx("path", { d: BRUSH_HANDLE, fill: handle }), jsxRuntime.jsx("path", { d: BRUSH_FERRULE, fill: ferrule, opacity: ferruleOpacity }), jsxRuntime.jsx("path", { d: BRUSH_BRISTLES, fill: bristles })] }));
288
+ }
263
289
  const NtdBrush = /* @__PURE__ */ createIcon.createIcon({
264
290
  displayName: 'NtdBrush',
265
291
  paths: {
266
- solid: ({ primaryColor, strokeWidth }) => (jsxRuntime.jsx("path", { d: "M14 4l6 6-8 8-6 2 2-6zM4 20c1.5 0 3-.8 3-2.5S6 15 4.5 15 2 16.2 2 18s.5 2 2 2z", stroke: primaryColor, strokeWidth: strokeWidth, fill: "none" })),
267
- outline: ({ primaryColor, strokeWidth }) => (jsxRuntime.jsx("path", { d: "M14 4l6 6-8 8-6 2 2-6zM4 20c1.5 0 3-.8 3-2.5S6 15 4.5 15 2 16.2 2 18s.5 2 2 2z", stroke: primaryColor, strokeWidth: strokeWidth, fill: "none" })),
268
- duotone: ({ primaryColor, secondaryColor, secondaryOpacity, strokeWidth }) => (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx("path", { d: "M14 4l6 6-8 8-6 2 2-6z", fill: secondaryColor, opacity: secondaryOpacity }), jsxRuntime.jsx("path", { d: "M14 4l6 6-8 8-6 2 2-6zM4 20c1.5 0 3-.8 3-2.5S6 15 4.5 15 2 16.2 2 18s.5 2 2 2z", stroke: primaryColor, strokeWidth: strokeWidth, fill: "none" })] })),
269
- vivid: ({ primaryColor, secondaryColor: _secondaryColor }) => (jsxRuntime.jsx(jsxRuntime.Fragment, { children: jsxRuntime.jsx("path", { d: "M14 4l6 6-8 8-6 2 2-6zM4 20c1.5 0 3-.8 3-2.5S6 15 4.5 15 2 16.2 2 18s.5 2 2 2z", stroke: primaryColor, strokeWidth: "2.2", fill: "none" }) })),
292
+ solid: ({ primaryColor, accentColor, accentOpacity, uid }) => (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [brushFilled(primaryColor, primaryColor, primaryColor), iconParts.within(uid, 'brush', jsxRuntime.jsx("path", { d: `${BRUSH_HANDLE}${BRUSH_FERRULE}${BRUSH_BRISTLES}` }), jsxRuntime.jsx("path", { d: BRUSH_CUTS, stroke: accentColor, strokeWidth: "1", opacity: accentOpacity }))] })),
293
+ outline: ({ primaryColor, strokeWidth }) => (jsxRuntime.jsx("path", { d: `${BRUSH_HANDLE}${BRUSH_FERRULE}${BRUSH_BRISTLES}`, stroke: primaryColor, strokeWidth: strokeWidth, fill: "none" })),
294
+ duotone: ({ primaryColor, secondaryColor }) => brushFilled(primaryColor, primaryColor, secondaryColor),
295
+ vivid: ({ primaryColor, secondaryColor, accentColor, accentOpacity }) => brushFilled(primaryColor, accentColor, secondaryColor, accentOpacity),
270
296
  },
271
297
  });
272
298
  const NtdPenTool = /* @__PURE__ */ createIcon.createIcon({
@@ -126,15 +126,17 @@ const NtdExternalLink = /* @__PURE__ */ createIcon.createIcon({
126
126
  });
127
127
  // NtdRefresh: two arcs round 12,12 (r 7), each ending in a filled head — a line glyph twice the
128
128
  // stroke width in every variant but `outline`. The tail stops inside its head, so no cap sticks
129
- // out of it in `sharp` (the old tails ran into the heads' corners). Duotone and vivid: the top
130
- // arrow primary, the bottom one secondary.
129
+ // out of it in `sharp` (the old tails ran into the heads' corners). Each head (7.2 wide, 4.2 long)
130
+ // points along the chord to the start of the other arrow's tail, with a clear gap before it — the
131
+ // bigger heads pointed past the tails and nearly touched them. Duotone and vivid: the top arrow
132
+ // primary, the bottom one secondary.
131
133
  const REFRESH_TOP = {
132
- tail: 'M5.82 8.71A7 7 0 0 1 18 8.39',
133
- head: 'M22.25 7L20.75 13.96L14.34 10.86z',
134
+ tail: 'M6.34 7.89A7 7 0 0 1 17.98 8.37',
135
+ head: 'M14.59 8.46L17.89 12.9L21.77 8.96z',
134
136
  };
135
137
  const REFRESH_BOTTOM = {
136
- tail: 'M18.18 15.29A7 7 0 0 1 6 15.61',
137
- head: 'M1.75 17L3.25 10.04L9.66 13.14z',
138
+ tail: 'M17.66 16.11A7 7 0 0 1 6.02 15.63',
139
+ head: 'M9.41 15.54L6.11 11.1L2.23 15.04z',
138
140
  };
139
141
  function refreshArrows(top, bottom, strokeWidth) {
140
142
  return (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx("path", { d: REFRESH_TOP.tail, stroke: top, strokeWidth: strokeWidth * 2, fill: "none" }), jsxRuntime.jsx("path", { d: REFRESH_TOP.head, fill: top }), jsxRuntime.jsx("path", { d: REFRESH_BOTTOM.tail, stroke: bottom, strokeWidth: strokeWidth * 2, fill: "none" }), jsxRuntime.jsx("path", { d: REFRESH_BOTTOM.head, fill: bottom })] }));
@@ -28,11 +28,14 @@ const APARTMENT_WINDOWS = [
28
28
  { x: 14, y: 13 },
29
29
  ];
30
30
  const APARTMENT_DOOR = { x: 10, y: 18, width: 4, height: 4 };
31
+ /** The door of the solid variants: it stops short of the ground, leaving a thin primary sill. */
32
+ const APARTMENT_DOOR_SILL = { ...APARTMENT_DOOR, height: 3.25 };
31
33
  const NtdApartment = /* @__PURE__ */ createIcon.createIcon({
32
34
  displayName: 'NtdApartment',
33
35
  paths: {
34
- // the windows and the door filled in the accent colour, no frames (round 33)
35
- solid: ({ primaryColor, accentColor, accentOpacity, uid }) => (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx("rect", { ...APARTMENT, fill: primaryColor }), jsxRuntime.jsxs("g", { fill: accentColor, opacity: accentOpacity, children: [APARTMENT_WINDOWS.map((w) => (jsxRuntime.jsx("rect", { ...w, width: "3", height: "3", rx: "0.5" }, `${w.x}-${w.y}`))), iconParts.within(uid, 'door', jsxRuntime.jsx("rect", { ...APARTMENT }), jsxRuntime.jsx("rect", { ...APARTMENT_DOOR }))] })] })),
36
+ // the windows and the door filled in the accent colour, no frames (round 33), a sill under the
37
+ // door (round 34)
38
+ solid: ({ primaryColor, accentColor, accentOpacity }) => (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx("rect", { ...APARTMENT, fill: primaryColor }), jsxRuntime.jsxs("g", { fill: accentColor, opacity: accentOpacity, children: [APARTMENT_WINDOWS.map((w) => (jsxRuntime.jsx("rect", { ...w, width: "3", height: "3", rx: "0.5" }, `${w.x}-${w.y}`))), jsxRuntime.jsx("rect", { ...APARTMENT_DOOR_SILL })] })] })),
36
39
  outline: ({ primaryColor, strokeWidth }) => (jsxRuntime.jsxs("g", { stroke: primaryColor, strokeWidth: strokeWidth, fill: "none", children: [jsxRuntime.jsx("rect", { ...APARTMENT }), APARTMENT_WINDOWS.map((w) => (jsxRuntime.jsx("rect", { ...w, width: "3", height: "3", rx: "0.5" }, `${w.x}-${w.y}`))), jsxRuntime.jsx("rect", { ...APARTMENT_DOOR })] })),
37
40
  duotone: ({ primaryColor, secondaryColor }) => (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx("rect", { ...APARTMENT, fill: primaryColor }), jsxRuntime.jsxs("g", { fill: secondaryColor, children: [APARTMENT_WINDOWS.map((w) => (jsxRuntime.jsx("rect", { ...w, width: "3", height: "3", rx: "0.5" }, `${w.x}-${w.y}`))), jsxRuntime.jsx("rect", { ...APARTMENT_DOOR })] })] })),
38
41
  vivid: ({ primaryColor, secondaryColor, accentColor, accentOpacity }) => (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx("rect", { ...APARTMENT, fill: primaryColor }), jsxRuntime.jsx("g", { fill: secondaryColor, children: APARTMENT_WINDOWS.map((w) => (jsxRuntime.jsx("rect", { ...w, width: "3", height: "3", rx: "0.5" }, `${w.x}-${w.y}`))) }), jsxRuntime.jsx("rect", { ...APARTMENT_DOOR, fill: accentColor, opacity: accentOpacity })] })),
@@ -240,13 +240,25 @@ const NtdMove = /* @__PURE__ */ createIcon.createIcon({
240
240
  vivid: ({ primaryColor, strokeWidth }) => (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx("path", { d: moveShape(strokeWidth), fill: primaryColor }), jsxRuntime.jsx("path", { d: moveShape(strokeWidth), fill: "white", opacity: "0.1" })] })),
241
241
  },
242
242
  });
243
+ // NtdRepeat: two hooked arrows, a line glyph twice the stroke width in every variant but `outline`
244
+ // — redrawn tighter (shafts at y 6 and 18, heads 3 long) so the heavier lines stay in the box. As
245
+ // in NtdMaximize, each shaft stops 0.35 × the line width short of its head's point, so the square
246
+ // cap of `sharp` stays inside the head (it stuck out of both points). Duotone and vivid: one arrow
247
+ // primary, the other secondary (vivid had a fixed #3B82F6 head).
248
+ const REPEAT_HEADS = ['M17 3L20 6L17 9', 'M7 21L4 18L7 15'];
249
+ const REPEAT_OUTLINE = 'M17 1l4 4-4 4M3 11V9a4 4 0 014-4h14M7 23l-4-4 4-4M21 13v2a4 4 0 01-4 4H3';
250
+ function repeatArrows(first, second, strokeWidth) {
251
+ const width = strokeWidth * 2;
252
+ const back = width * 0.35;
253
+ return (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx("path", { d: `${REPEAT_HEADS[0]}M4 10V9a3 3 0 013-3H${20 - back}`, stroke: first, strokeWidth: width, fill: "none" }), jsxRuntime.jsx("path", { d: `${REPEAT_HEADS[1]}M20 14v1a3 3 0 01-3 3H${4 + back}`, stroke: second, strokeWidth: width, fill: "none" })] }));
254
+ }
243
255
  const NtdRepeat = /* @__PURE__ */ createIcon.createIcon({
244
256
  displayName: 'NtdRepeat',
245
257
  paths: {
246
- solid: ({ primaryColor, strokeWidth }) => (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx("polyline", { points: "17,1 21,5 17,9", stroke: primaryColor, strokeWidth: strokeWidth, fill: "none" }), jsxRuntime.jsx("path", { d: "M3 11V9a4 4 0 014-4h14", stroke: primaryColor, strokeWidth: strokeWidth, fill: "none" }), jsxRuntime.jsx("polyline", { points: "7,23 3,19 7,15", stroke: primaryColor, strokeWidth: strokeWidth, fill: "none" }), jsxRuntime.jsx("path", { d: "M21 13v2a4 4 0 01-4 4H3", stroke: primaryColor, strokeWidth: strokeWidth, fill: "none" })] })),
247
- outline: ({ primaryColor, strokeWidth }) => (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx("polyline", { points: "17,1 21,5 17,9", stroke: primaryColor, strokeWidth: strokeWidth, fill: "none" }), jsxRuntime.jsx("path", { d: "M3 11V9a4 4 0 014-4h14", stroke: primaryColor, strokeWidth: strokeWidth, fill: "none" }), jsxRuntime.jsx("polyline", { points: "7,23 3,19 7,15", stroke: primaryColor, strokeWidth: strokeWidth, fill: "none" }), jsxRuntime.jsx("path", { d: "M21 13v2a4 4 0 01-4 4H3", stroke: primaryColor, strokeWidth: strokeWidth, fill: "none" })] })),
248
- duotone: ({ primaryColor, secondaryColor, secondaryOpacity, strokeWidth }) => (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx("path", { d: "M3 11V9a4 4 0 014-4h14", stroke: secondaryColor, strokeWidth: strokeWidth, fill: "none", opacity: secondaryOpacity + 0.2 }), jsxRuntime.jsx("path", { d: "M21 13v2a4 4 0 01-4 4H3", stroke: secondaryColor, strokeWidth: strokeWidth, fill: "none", opacity: secondaryOpacity + 0.2 }), jsxRuntime.jsx("polyline", { points: "17,1 21,5 17,9", stroke: primaryColor, strokeWidth: strokeWidth, fill: "none" }), jsxRuntime.jsx("polyline", { points: "7,23 3,19 7,15", stroke: primaryColor, strokeWidth: strokeWidth, fill: "none" })] })),
249
- vivid: ({ primaryColor, secondaryColor }) => (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx("polyline", { points: "17,1 21,5 17,9", stroke: primaryColor, strokeWidth: "2", fill: "none" }), jsxRuntime.jsx("path", { d: "M3 11V9a4 4 0 014-4h14", stroke: secondaryColor, strokeWidth: "1.8", fill: "none" }), jsxRuntime.jsx("polyline", { points: "7,23 3,19 7,15", stroke: "#3B82F6", strokeWidth: "1.5", fill: "none" }), jsxRuntime.jsx("path", { d: "M21 13v2a4 4 0 01-4 4H3", stroke: secondaryColor, strokeWidth: "1.5", fill: "none" })] })),
258
+ solid: ({ primaryColor, strokeWidth }) => repeatArrows(primaryColor, primaryColor, strokeWidth),
259
+ outline: ({ primaryColor, strokeWidth }) => (jsxRuntime.jsx("path", { d: REPEAT_OUTLINE, stroke: primaryColor, strokeWidth: strokeWidth, fill: "none" })),
260
+ duotone: ({ primaryColor, secondaryColor, strokeWidth }) => repeatArrows(primaryColor, secondaryColor, strokeWidth),
261
+ vivid: ({ primaryColor, secondaryColor, strokeWidth }) => repeatArrows(primaryColor, secondaryColor, strokeWidth),
250
262
  },
251
263
  });
252
264
  const NtdShuffle = /* @__PURE__ */ createIcon.createIcon({
@@ -43,26 +43,27 @@ const NtdCar = /* @__PURE__ */ createIcon.createIcon({
43
43
  vivid: ({ primaryColor, secondaryColor: _secondaryColor }) => (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx("path", { d: "M5 11l2-5h10l2 5M3 14v4a1 1 0 001 1h2a1 1 0 001-1v-1h10v1a1 1 0 001 1h2a1 1 0 001-1v-4a2 2 0 00-2-2H5a2 2 0 00-2 2z", fill: primaryColor }), jsxRuntime.jsx("path", { d: "M5 11l2-5h10l2 5M3 14v4a1 1 0 001 1h2a1 1 0 001-1v-1h10v1a1 1 0 001 1h2a1 1 0 001-1v-4a2 2 0 00-2-2H5a2 2 0 00-2 2z", fill: "white", opacity: "0.08" }), jsxRuntime.jsx("circle", { cx: "7", cy: "15", r: "1.5", fill: "white", opacity: "0.5" }), jsxRuntime.jsx("circle", { cx: "17", cy: "15", r: "1.5", fill: "white", opacity: "0.5" })] })),
44
44
  },
45
45
  });
46
- // NtdBus: a side view — the body with one long window, a passenger (NtdUser's head and shoulders)
47
- // in it on the left, a stripe below, and wheels set in arches. Filled, the window, the stripe, the
48
- // arches and the hubs are in the accent colour (fixed 50% white before) and the passenger primary.
49
- const BUS_BODY = { x: 2, y: 4, width: 20, height: 13, rx: 2.5 };
50
- const BUS_WINDOW = { x: 4, y: 6.5, width: 16, height: 4.5, rx: 1 };
51
- /** The passenger, cut off by the window's bottom edge. */
52
- const BUS_PASSENGER = 'M7 7.4a1.25 1.25 0 110 2.5 1.25 1.25 0 110-2.5zM4.9 11.6v-.3a1.9 1.9 0 011.9-1.9h.4a1.9 1.9 0 011.9 1.9v.3z';
53
- const BUS_STRIPE = 'M2 13.5h20';
54
- const BUS_WHEELS = 'M7 14.5a2.5 2.5 0 110 5 2.5 2.5 0 110-5zM17 14.5a2.5 2.5 0 110 5 2.5 2.5 0 110-5z';
55
- const BUS_ARCHES = 'M7 13.7a3.3 3.3 0 110 6.6 3.3 3.3 0 110-6.6zM17 13.7a3.3 3.3 0 110 6.6 3.3 3.3 0 110-6.6z';
56
- const BUS_HUBS = 'M7 16.1a.9.9 0 110 1.8.9.9 0 110-1.8zM17 16.1a.9.9 0 110 1.8.9.9 0 110-1.8z';
46
+ // NtdBus: seen from the front — the body with a big windscreen (its top frame 1.75, 30% less than
47
+ // the side view's), the driver (NtdUser's head and shoulders) in it on the left, two headlights and
48
+ // a bumper line below it, and the wheels as rectangles under the body (round side-view wheels
49
+ // read oddly). Filled, the windscreen, the headlights and the bumper are in the accent colour and
50
+ // the driver primary.
51
+ const BUS_BODY = { x: 3, y: 2, width: 18, height: 17, rx: 2.5 };
52
+ const BUS_WINDOW = { x: 4.75, y: 3.75, width: 14.5, height: 7.5, rx: 1 };
53
+ /** The driver, cut off by the windscreen's bottom edge. */
54
+ const BUS_DRIVER = 'M8.4 5.3a1.6 1.6 0 110 3.2 1.6 1.6 0 110-3.2zM5.6 11.5v-.1a2.3 2.3 0 012.3-2.3h1a2.3 2.3 0 012.3 2.3v.1z';
55
+ const BUS_LIGHTS = 'M6.6 13.7a1.3 1.3 0 110 2.6 1.3 1.3 0 110-2.6zM17.4 13.7a1.3 1.3 0 110 2.6 1.3 1.3 0 110-2.6z';
56
+ const BUS_BUMPER = 'M3 17.4h18';
57
+ const BUS_WHEELS = 'M5.5 18h3v3a1 1 0 01-1 1h-1a1 1 0 01-1-1zM15.5 18h3v3a1 1 0 01-1 1h-1a1 1 0 01-1-1z';
57
58
  function busFilled({ primaryColor, uid }, glass, details, detailOpacity) {
58
- return (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx("rect", { ...BUS_BODY, fill: primaryColor }), iconParts.within(uid, 'body', jsxRuntime.jsx("rect", { ...BUS_BODY }), jsxRuntime.jsxs("g", { opacity: detailOpacity, children: [jsxRuntime.jsx("path", { d: BUS_ARCHES, fill: details }), jsxRuntime.jsx("path", { d: BUS_STRIPE, stroke: details, strokeWidth: "1.2" })] })), jsxRuntime.jsx("rect", { ...BUS_WINDOW, fill: glass }), iconParts.within(uid, 'window', jsxRuntime.jsx("rect", { ...BUS_WINDOW }), jsxRuntime.jsx("path", { d: BUS_PASSENGER, fill: primaryColor })), jsxRuntime.jsx("path", { d: BUS_WHEELS, fill: primaryColor }), jsxRuntime.jsx("path", { d: BUS_HUBS, fill: details, opacity: detailOpacity })] }));
59
+ return (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx("path", { d: BUS_WHEELS, fill: primaryColor }), jsxRuntime.jsx("rect", { ...BUS_BODY, fill: primaryColor }), jsxRuntime.jsxs("g", { opacity: detailOpacity, children: [jsxRuntime.jsx("path", { d: BUS_LIGHTS, fill: details }), iconParts.within(uid, 'body', jsxRuntime.jsx("rect", { ...BUS_BODY }), jsxRuntime.jsx("path", { d: BUS_BUMPER, stroke: details, strokeWidth: "1.2" }))] }), jsxRuntime.jsx("rect", { ...BUS_WINDOW, fill: glass }), iconParts.within(uid, 'window', jsxRuntime.jsx("rect", { ...BUS_WINDOW }), jsxRuntime.jsx("path", { d: BUS_DRIVER, fill: primaryColor }))] }));
59
60
  }
60
61
  const NtdBus = /* @__PURE__ */ createIcon.createIcon({
61
62
  displayName: 'NtdBus',
62
63
  paths: {
63
64
  solid: (props) => busFilled(props, props.accentColor, props.accentColor, props.accentOpacity),
64
- outline: ({ primaryColor, strokeWidth }) => (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx("rect", { ...BUS_BODY, stroke: primaryColor, strokeWidth: strokeWidth, fill: "none" }), jsxRuntime.jsx("rect", { ...BUS_WINDOW, stroke: primaryColor, strokeWidth: strokeWidth, fill: "none" }), jsxRuntime.jsx("path", { d: BUS_PASSENGER, fill: primaryColor }), jsxRuntime.jsx("path", { d: "M4 13.5h16", stroke: primaryColor, strokeWidth: strokeWidth }), jsxRuntime.jsx("path", { d: BUS_WHEELS, stroke: primaryColor, strokeWidth: strokeWidth, fill: "none" })] })),
65
- // fills only: the body and the passenger primary, the window and the details secondary
65
+ outline: ({ primaryColor, strokeWidth, uid }) => (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx("rect", { ...BUS_BODY, stroke: primaryColor, strokeWidth: strokeWidth, fill: "none" }), jsxRuntime.jsx("rect", { ...BUS_WINDOW, stroke: primaryColor, strokeWidth: strokeWidth, fill: "none" }), iconParts.within(uid, 'window', jsxRuntime.jsx("rect", { ...BUS_WINDOW }), jsxRuntime.jsx("path", { d: BUS_DRIVER, fill: primaryColor })), jsxRuntime.jsx("path", { d: "M6.6 14a1 1 0 110 2 1 1 0 110-2zM17.4 14a1 1 0 110 2 1 1 0 110-2z", fill: primaryColor }), jsxRuntime.jsx("path", { d: "M6 19v2a1 1 0 001 1h1a1 1 0 001-1v-2M15 19v2a1 1 0 001 1h1a1 1 0 001-1v-2", stroke: primaryColor, strokeWidth: strokeWidth, fill: "none" })] })),
66
+ // fills only: the body and the driver primary, the windscreen and the details secondary
66
67
  duotone: (props) => busFilled(props, props.secondaryColor, props.secondaryColor, 1),
67
68
  vivid: (props) => busFilled(props, props.secondaryColor, props.accentColor, props.accentOpacity),
68
69
  },