@behindthemusictree/app-kit-ui 37.1.0 → 38.0.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.
@@ -23,8 +23,8 @@ import {
23
23
  useGenrePlaylistPlayback,
24
24
  useGenreRemoteSearchGroup,
25
25
  useSongSearchGroup
26
- } from "../chunk-57OI426Y.js";
27
- import "../chunk-DKQQLLMY.js";
26
+ } from "../chunk-F7H5XPWU.js";
27
+ import "../chunk-2GH7CSCE.js";
28
28
  export {
29
29
  EntityDetailPanel,
30
30
  GenreDetailPanel,
package/dist/index.cjs CHANGED
@@ -260,7 +260,7 @@ function Toast({ message, onClose, durationMs = 2200 }) {
260
260
  role: "status",
261
261
  "aria-live": "polite",
262
262
  "aria-atomic": "true",
263
- className: "pointer-events-auto w-full max-w-md rounded-md bg-[var(--color-surface)] px-4 py-4 text-sm text-[var(--color-text)] shadow-lg ring-1 ring-black/10",
263
+ className: "pointer-events-auto w-full max-w-md rounded-md bg-[var(--color-surface)] px-4 py-4 text-body text-[var(--color-text)] shadow-lg ring-1 ring-black/10",
264
264
  children: message
265
265
  }
266
266
  ) }),
@@ -332,14 +332,14 @@ function TrackUploadPopup({
332
332
  /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "flex items-center space-x-3", children: [
333
333
  getStatusIcon(item.status),
334
334
  /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { children: [
335
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "font-medium text-sm truncate max-w-xs", title: item.file.name, children: item.file.name }),
336
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "text-xs text-[var(--color-neutral-500)]", children: [
335
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "font-medium text-body truncate max-w-xs", title: item.file.name, children: item.file.name }),
336
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "text-caption text-[var(--color-neutral-500)]", children: [
337
337
  (item.file.size / 1024 / 1024).toFixed(1),
338
338
  " MB"
339
339
  ] })
340
340
  ] })
341
341
  ] }),
342
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "text-sm text-[var(--color-neutral-600)]", children: getStatusText(item.status) })
342
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "text-body text-[var(--color-neutral-600)]", children: getStatusText(item.status) })
343
343
  ] }),
344
344
  item.status === "uploading" && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "w-full bg-[var(--color-neutral-200)] rounded-full h-2", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
345
345
  "div",
@@ -348,9 +348,9 @@ function TrackUploadPopup({
348
348
  style: { width: `${item.progress}%` }
349
349
  }
350
350
  ) }),
351
- item.status === "error" && item.error && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "text-[var(--color-red-500)] text-sm mt-2", children: item.error.name === "InvalidInputError" ? "Upload failed due to invalid file data. Please check your file and try again." : item.error.name === "ZodError" ? "Upload failed due to a server error. Please try again later." : item.error.message })
351
+ item.status === "error" && item.error && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "text-[var(--color-red-500)] text-body mt-2", children: item.error.name === "InvalidInputError" ? "Upload failed due to invalid file data. Please check your file and try again." : item.error.name === "ZodError" ? "Upload failed due to a server error. Please try again later." : item.error.message })
352
352
  ] }, item.id)),
353
- allComplete && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "flex justify-between items-center", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "text-sm text-[var(--color-neutral-600)]", children: [
353
+ allComplete && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "flex justify-between items-center", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "text-body text-[var(--color-neutral-600)]", children: [
354
354
  successfulCount,
355
355
  " successful, ",
356
356
  errorCount,
@@ -399,7 +399,7 @@ function InternalErrorPopup({ errorCode, contactEmail, ...rest }) {
399
399
  " ",
400
400
  /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("a", { href: `mailto:${contactEmail}`, className: "text-[var(--color-primary)] hover:text-[var(--color-primary-hover)]", children: contactEmail })
401
401
  ] }) }),
402
- errorCode && /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "text-sm text-[var(--color-neutral-500)] bg-[var(--color-neutral-100)] p-3 rounded-lg border border-[var(--color-neutral-100)]", children: [
402
+ errorCode && /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "text-body text-[var(--color-neutral-500)] bg-[var(--color-neutral-100)] p-3 rounded-lg border border-[var(--color-neutral-100)]", children: [
403
403
  "Error Code: ",
404
404
  errorCode
405
405
  ] })
@@ -515,7 +515,7 @@ function SpotifyAuthErrorPopup({
515
515
  /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_fa2.FaSpotify, { className: "text-[#1DB954] text-7xl" }),
516
516
  /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "space-y-3 text-center", children: [
517
517
  /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("p", { className: "text-xl font-medium text-[var(--color-text)]", children: message }),
518
- details && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("p", { className: "text-sm text-[var(--color-neutral-500)] bg-[var(--color-neutral-100)] p-3 rounded-lg border border-[var(--color-neutral-100)]", children: details }),
518
+ details && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("p", { className: "text-body text-[var(--color-neutral-500)] bg-[var(--color-neutral-100)] p-3 rounded-lg border border-[var(--color-neutral-100)]", children: details }),
519
519
  /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "space-y-2 text-center", children: [
520
520
  /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("p", { className: "text-base text-[var(--color-neutral-700)]", children: "The Spotify app is in development mode, so only allowlisted accounts can connect." }),
521
521
  requestAccessHref && contactEmail ? /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("p", { className: "text-base text-[var(--color-neutral-700)]", children: [
@@ -1111,7 +1111,7 @@ function useArtistSearchGroup(getBaseUrl, text, onSelect, enabled = true) {
1111
1111
  artist.disambiguation
1112
1112
  ] })
1113
1113
  ] }),
1114
- artist.matchedAlias && /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("span", { className: "block truncate text-xs text-[var(--color-neutral-500)]", children: [
1114
+ artist.matchedAlias && /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("span", { className: "block truncate text-caption text-[var(--color-neutral-500)]", children: [
1115
1115
  "also known as ",
1116
1116
  artist.matchedAlias
1117
1117
  ] })
@@ -1136,7 +1136,7 @@ function useSongSearchGroup(getBaseUrl, text, onSelect, enabled = true) {
1136
1136
  key: song.uuid,
1137
1137
  content: /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("span", { className: (0, import_genre_tree7.isSongSearchResultPlayable)(song) ? void 0 : "opacity-60", children: [
1138
1138
  /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("span", { className: "block truncate font-medium", children: song.title }),
1139
- /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("span", { className: "block truncate text-xs text-[var(--color-neutral-500)]", children: [song.artists.map((artist) => artist.name).join(", "), song.genre?.name ?? "No genre"].filter(Boolean).join(" \xB7 ") })
1139
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("span", { className: "block truncate text-caption text-[var(--color-neutral-500)]", children: [song.artists.map((artist) => artist.name).join(", "), song.genre?.name ?? "No genre"].filter(Boolean).join(" \xB7 ") })
1140
1140
  ] }),
1141
1141
  onSelect: () => onSelect(song)
1142
1142
  })),
@@ -1159,9 +1159,9 @@ function useGenreRemoteSearchGroup(getBaseUrl, text, onSelect, { key = "genres",
1159
1159
  content: /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(import_jsx_runtime19.Fragment, { children: [
1160
1160
  /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("span", { className: "block truncate font-medium", children: [
1161
1161
  genre.name,
1162
- genre.isUmbrella && /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { className: "ml-2 text-xs font-normal italic text-[var(--color-text-muted)]", children: "umbrella" })
1162
+ genre.isUmbrella && /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { className: "ml-2 text-caption font-normal italic text-[var(--color-text-muted)]", children: "umbrella" })
1163
1163
  ] }),
1164
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { className: "block truncate text-xs text-[var(--color-neutral-500)]", children: describe?.(genre) ?? `${genre.treeName} \xB7 ${genre.root.name}` })
1164
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { className: "block truncate text-caption text-[var(--color-neutral-500)]", children: describe?.(genre) ?? `${genre.treeName} \xB7 ${genre.root.name}` })
1165
1165
  ] }),
1166
1166
  onSelect: () => onSelect(genre)
1167
1167
  })),
@@ -1202,7 +1202,7 @@ function GenreSearch({
1202
1202
  key: genrePlaylist.uuid,
1203
1203
  content: /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(import_jsx_runtime20.Fragment, { children: [
1204
1204
  genrePlaylist.name,
1205
- genrePlaylist.isUmbrella && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "ml-2 text-xs italic text-[var(--color-text-muted)]", children: "umbrella" })
1205
+ genrePlaylist.isUmbrella && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "ml-2 text-caption italic text-[var(--color-text-muted)]", children: "umbrella" })
1206
1206
  ] }),
1207
1207
  onSelect: () => select(genrePlaylist)
1208
1208
  }))
@@ -1303,7 +1303,7 @@ var import_si = require("react-icons/si");
1303
1303
 
1304
1304
  // src/genre-tree/ShareDestinationButton.tsx
1305
1305
  var import_jsx_runtime22 = require("react/jsx-runtime");
1306
- var className = "group flex min-w-0 flex-1 flex-col items-center justify-center gap-1.5 rounded-xl px-2 py-2 text-xs text-[var(--color-text)] transition-colors hover:bg-[var(--color-surface-muted)] focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--color-focus-ring)] disabled:cursor-not-allowed disabled:opacity-50";
1306
+ var className = "group flex min-w-0 flex-1 flex-col items-center justify-center gap-1.5 rounded-xl px-2 py-2 text-caption text-[var(--color-text)] transition-colors hover:bg-[var(--color-surface-muted)] focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--color-focus-ring)] disabled:cursor-not-allowed disabled:opacity-50";
1307
1307
  function Contents({ icon, label }) {
1308
1308
  return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(import_jsx_runtime22.Fragment, { children: [
1309
1309
  /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { className: "flex h-12 w-12 items-center justify-center rounded-full bg-[var(--color-surface-muted)] transition-colors group-hover:bg-[var(--color-border)]", children: icon }),
@@ -1333,9 +1333,9 @@ function SharePreviewCard({ target, url }) {
1333
1333
  return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "rounded-3xl bg-[var(--color-surface-muted)] p-4", children: /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "flex min-h-32 overflow-hidden rounded-2xl bg-[var(--color-surface)] shadow-lg", children: [
1334
1334
  /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "flex w-28 shrink-0 items-center justify-center bg-[var(--color-primary)]/15 text-[var(--color-primary)]", children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(Icon, { "aria-hidden": "true", className: "h-10 w-10" }) }),
1335
1335
  /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "flex min-w-0 flex-1 flex-col justify-center gap-1 p-4", children: [
1336
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "text-xs font-medium uppercase tracking-wide text-[var(--color-text-muted)]", children: typeLabel }),
1336
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "text-caption font-medium uppercase tracking-wide text-[var(--color-text-muted)]", children: typeLabel }),
1337
1337
  /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "truncate text-base font-semibold text-[var(--color-text)]", title: target.name, children: target.name }),
1338
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "truncate text-sm text-[var(--color-primary)]", title: url, children: url })
1338
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "truncate text-body text-[var(--color-primary)]", title: url, children: url })
1339
1339
  ] })
1340
1340
  ] }) });
1341
1341
  }
@@ -1476,8 +1476,8 @@ function SharePopup({ target, url, onClose }) {
1476
1476
  }
1477
1477
  )
1478
1478
  ] }),
1479
- copyStatus === "failed" && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("p", { role: "alert", className: "text-center text-sm text-[var(--color-red-500)]", children: "Could not copy the link." }),
1480
- shareError && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("p", { role: "alert", className: "text-center text-sm text-[var(--color-red-500)]", children: shareError })
1479
+ copyStatus === "failed" && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("p", { role: "alert", className: "text-center text-body text-[var(--color-red-500)]", children: "Could not copy the link." }),
1480
+ shareError && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("p", { role: "alert", className: "text-center text-body text-[var(--color-red-500)]", children: shareError })
1481
1481
  ] })
1482
1482
  }
1483
1483
  ),
@@ -1497,7 +1497,7 @@ function ShareActionButton({ target, url }) {
1497
1497
  {
1498
1498
  type: "button",
1499
1499
  onClick: openSharePopup,
1500
- className: "group flex flex-col items-center gap-1 w-16 text-xs text-center text-[var(--color-text)] focus-visible:outline-none",
1500
+ className: "group flex flex-col items-center gap-1 w-16 text-caption text-center text-[var(--color-text)] focus-visible:outline-none",
1501
1501
  "aria-label": `Share ${target.name}`,
1502
1502
  title: `Share ${target.name}`,
1503
1503
  children: [
@@ -1579,7 +1579,7 @@ function GenreActionBand({
1579
1579
  disabled: item.disabled,
1580
1580
  title: item.title,
1581
1581
  onClick: item.onClick,
1582
- className: "group flex flex-col items-center gap-1 w-16 text-xs text-center text-[var(--color-text)] focus-visible:outline-none disabled:opacity-50",
1582
+ className: "group flex flex-col items-center gap-1 w-16 text-caption text-center text-[var(--color-text)] focus-visible:outline-none disabled:opacity-50",
1583
1583
  children: [
1584
1584
  /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("span", { className: "flex items-center justify-center w-10 h-10 rounded-full group-focus-visible:ring-2 group-focus-visible:ring-[var(--color-focus-ring)] bg-[var(--color-surface-muted)] transition-colors group-hover:bg-[var(--color-border)] group-disabled:group-hover:bg-[var(--color-surface-muted)]", children: item.icon }),
1585
1585
  item.label
@@ -1598,7 +1598,7 @@ function GenreActionBand({
1598
1598
  "aria-label": "Admin actions",
1599
1599
  className: `px-3.5 py-3 ${items.length > 0 ? "border-t border-[var(--color-border)]" : ""}`,
1600
1600
  children: [
1601
- /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("h3", { className: "mb-2 text-xs font-semibold uppercase tracking-wide text-[var(--color-text-muted)]", children: "Admin" }),
1601
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("h3", { className: "mb-2 text-caption font-semibold uppercase tracking-wide text-[var(--color-text-muted)]", children: "Admin" }),
1602
1602
  /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { className: "flex flex-wrap gap-1", children: renderItems(adminItems) })
1603
1603
  ]
1604
1604
  }
@@ -1630,7 +1630,7 @@ function ClampedText({ children, className: className2 = "" }) {
1630
1630
  type: "button",
1631
1631
  "aria-expanded": expanded,
1632
1632
  onClick: () => setExpanded((value) => !value),
1633
- className: "mt-1 text-xs text-[var(--color-text-muted)] underline hover:text-[var(--color-text)]",
1633
+ className: "mt-1 text-caption text-[var(--color-text-muted)] underline hover:text-[var(--color-text)]",
1634
1634
  children: expanded ? "Show less" : "Show more"
1635
1635
  }
1636
1636
  )
@@ -1781,7 +1781,7 @@ function GenrePlaylistTracks({
1781
1781
  ".",
1782
1782
  " ",
1783
1783
  /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("button", { type: "button", className: "underline", onClick: () => void refetch(), children: "Retry" })
1784
- ] }) : tracks.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("p", { children: "\u2014" }) : /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("ul", { className: "mt-1 max-h-64 overflow-y-auto text-[0.8125rem] leading-[1.45] [container-type:inline-size]", "aria-label": `${genreName} ${trackNoun.plural}`, children: [
1784
+ ] }) : tracks.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("p", { children: "\u2014" }) : /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("ul", { className: "mt-1 max-h-64 overflow-y-auto text-body [container-type:inline-size]", "aria-label": `${genreName} ${trackNoun.plural}`, children: [
1785
1785
  tracks.map((track, index) => {
1786
1786
  const label = track.artists?.length ? `${track.title} \u2014 ${track.artists.map((artist2) => artist2.name).join(", ")}` : track.title;
1787
1787
  const isCurrent = playerTrackObject?.track.id === track.uuid;
@@ -1879,7 +1879,7 @@ function GenreDetailExtras({
1879
1879
  const { summary, summarySourceUrl, essentialSongs } = overview;
1880
1880
  const wikidataUrl = wikidataId ? `https://www.wikidata.org/wiki/${encodeURIComponent(wikidataId)}` : null;
1881
1881
  return /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)(import_jsx_runtime30.Fragment, { children: [
1882
- (summarySourceUrl || wikidataUrl) && /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(import_ui9.PanelSection, { title: "Links", children: /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { className: "flex flex-wrap gap-x-3 gap-y-1 text-xs text-[var(--color-text)]", children: [
1882
+ (summarySourceUrl || wikidataUrl) && /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(import_ui9.PanelSection, { title: "Links", children: /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { className: "flex flex-wrap gap-x-3 gap-y-1 text-caption text-[var(--color-text)]", children: [
1883
1883
  summarySourceUrl && /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)(
1884
1884
  "a",
1885
1885
  {
@@ -1907,10 +1907,10 @@ function GenreDetailExtras({
1907
1907
  }
1908
1908
  )
1909
1909
  ] }) }),
1910
- /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(import_ui9.PanelSection, { title: "Summary", children: renderSummary ? renderSummary(overview) : /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(ClampedText, { className: "text-[0.8125rem] leading-[1.45] text-[var(--color-text)]", children: summary ?? "\u2014" }, genreUuid) }),
1910
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(import_ui9.PanelSection, { title: "Summary", children: renderSummary ? renderSummary(overview) : /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(ClampedText, { className: "text-body text-[var(--color-text)]", children: summary ?? "\u2014" }, genreUuid) }),
1911
1911
  family,
1912
1912
  renderGenreDetailExtras?.(overview),
1913
- (renderEssentialTracks || essentialSongs) && /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(import_ui9.PanelSection, { title: `Essential ${trackNoun.plural}`, children: renderEssentialTracks ? renderEssentialTracks(overview) : essentialSongs && essentialSongs.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("ul", { className: "text-[0.8125rem] leading-[1.45] text-[var(--color-text)]", children: essentialSongs.map((track) => /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("li", { className: "py-1", children: track.title }, track.uuid)) }) : /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("p", { className: "text-[0.8125rem] leading-[1.45] text-[var(--color-text)]", children: "\u2014" }) }),
1913
+ (renderEssentialTracks || essentialSongs) && /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(import_ui9.PanelSection, { title: `Essential ${trackNoun.plural}`, children: renderEssentialTracks ? renderEssentialTracks(overview) : essentialSongs && essentialSongs.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("ul", { className: "text-body text-[var(--color-text)]", children: essentialSongs.map((track) => /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("li", { className: "py-1", children: track.title }, track.uuid)) }) : /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("p", { className: "text-body text-[var(--color-text)]", children: "\u2014" }) }),
1914
1914
  /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
1915
1915
  GenrePlaylistTracks,
1916
1916
  {
@@ -1976,7 +1976,7 @@ function GenreInfoPanelBody({
1976
1976
  return /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)(import_jsx_runtime31.Fragment, { children: [
1977
1977
  toolbar,
1978
1978
  genrePlaylist ? /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(GenreNodeActionBand, { ...band, genrePlaylist, playback }) : /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(GenreActionBand, { ...band }),
1979
- summary && catalogue && /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)("div", { className: "px-3.5 py-3 text-sm text-[var(--color-text)]", children: [
1979
+ summary && catalogue && /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)("div", { className: "px-3.5 py-3 text-body text-[var(--color-text)]", children: [
1980
1980
  /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)("p", { children: [
1981
1981
  "Catalogue ",
1982
1982
  noun.plural,
@@ -2066,7 +2066,7 @@ function useGenreDetailContent({
2066
2066
  if (isError) return {
2067
2067
  name: null,
2068
2068
  title: "Genre unavailable",
2069
- content: /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("p", { role: "alert", className: "p-4 text-sm text-[var(--color-text)]", children: "This genre could not be loaded." })
2069
+ content: /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("p", { role: "alert", className: "p-4 text-body text-[var(--color-text)]", children: "This genre could not be loaded." })
2070
2070
  };
2071
2071
  if (isPending || !detail || !view) return {
2072
2072
  name: null,
@@ -2202,7 +2202,7 @@ function ChangeParentPopup({
2202
2202
  return () => window.removeEventListener("keydown", handleKeyDown);
2203
2203
  }, [onClose]);
2204
2204
  return /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)(BasePopup_default, { title: `Change parent of ${genrePlaylist.name}`, onClose, showCancelButton: true, fitContent: true, children: [
2205
- /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)("p", { className: "mb-3 text-sm text-[var(--color-text-muted)]", children: [
2205
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)("p", { className: "mb-3 text-body text-[var(--color-text-muted)]", children: [
2206
2206
  "Current parent: ",
2207
2207
  genrePlaylist.parent?.name ?? "none"
2208
2208
  ] }),
@@ -2214,7 +2214,7 @@ function ChangeParentPopup({
2214
2214
  placeholder: "Search a new parent\u2026"
2215
2215
  }
2216
2216
  ) }),
2217
- formErrors.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("p", { role: "alert", className: "mt-3 text-sm text-[var(--color-red-500)]", children: formErrors.map(({ message }) => message).join(" ") })
2217
+ formErrors.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("p", { role: "alert", className: "mt-3 text-body text-[var(--color-red-500)]", children: formErrors.map(({ message }) => message).join(" ") })
2218
2218
  ] });
2219
2219
  }
2220
2220
 
@@ -2300,7 +2300,7 @@ function ExternalLink({ href, children }) {
2300
2300
  function ArtistPhoto({ image, name }) {
2301
2301
  return /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)("figure", { className: "flex flex-col gap-1.5 px-6 py-2.5", children: [
2302
2302
  /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("img", { src: image.url, alt: name, className: "h-64 w-full object-contain bg-[var(--color-surface-muted)] rounded" }),
2303
- /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)("figcaption", { className: "text-xs text-[var(--color-text-muted)]", children: [
2303
+ /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)("figcaption", { className: "text-caption text-[var(--color-text-muted)]", children: [
2304
2304
  "Photo: ",
2305
2305
  /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(ExternalLink, { href: image.pageUrl, children: image.author ?? "Wikimedia Commons" }),
2306
2306
  ",",
@@ -2499,7 +2499,7 @@ function TrackItem({
2499
2499
  /* @__PURE__ */ (0, import_jsx_runtime40.jsx)("div", { className: "flex max-w-full items-center gap-2", children: /* @__PURE__ */ (0, import_jsx_runtime40.jsx)("div", { className: "title text-lg font-bold text-[var(--color-text)] max-w-full truncate", children: renderSongLink ? renderSongLink(track) : (0, import_genre_tree22.isSong)(track) ? /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(MusicBrainzRecordingLink, { song: track, className: "hover:underline focus-visible:underline", children: track.title }) : track.title }) }),
2500
2500
  track.artists && track.artists.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime40.jsx)("div", { className: "artist text-base max-w-full truncate text-[var(--color-text-muted)]", children: /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(import_genre_tree23.ArtistNames, { artists: track.artists, renderArtistLink }) }) : ""
2501
2501
  ] }),
2502
- /* @__PURE__ */ (0, import_jsx_runtime40.jsx)("div", { className: "genre-name-container flex items-center justify-start w-[21.6%] min-w-0 shrink-0", children: track.genre ? /* @__PURE__ */ (0, import_jsx_runtime40.jsx)("div", { className: "genre-name max-w-full whitespace-normal break-words p-1 text-xs font-bold", children: track.genre.name }) : "" }),
2502
+ /* @__PURE__ */ (0, import_jsx_runtime40.jsx)("div", { className: "genre-name-container flex items-center justify-start w-[21.6%] min-w-0 shrink-0", children: track.genre ? /* @__PURE__ */ (0, import_jsx_runtime40.jsx)("div", { className: "genre-name max-w-full whitespace-normal break-words p-1 text-caption font-bold", children: track.genre.name }) : "" }),
2503
2503
  renderDuration && /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(
2504
2504
  "div",
2505
2505
  {
@@ -2555,14 +2555,14 @@ function ArtistSongs({ artist, getBackendBaseUrl, renderArtistLink, renderSongLi
2555
2555
  {
2556
2556
  type: "button",
2557
2557
  onClick: () => void play(),
2558
- className: "flex w-fit items-center gap-1.5 px-3 py-1 text-xs font-medium bg-gray-900 text-white rounded-full hover:bg-gray-700",
2558
+ className: "flex w-fit items-center gap-1.5 px-3 py-1 text-caption font-medium bg-gray-900 text-white rounded-full hover:bg-gray-700",
2559
2559
  children: [
2560
2560
  /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(import_lucide_react14.Play, { className: "h-3.5 w-3.5", "aria-hidden": "true" }),
2561
2561
  "Play all"
2562
2562
  ]
2563
2563
  }
2564
2564
  ),
2565
- /* @__PURE__ */ (0, import_jsx_runtime41.jsx)("div", { role: "group", "aria-label": "Sort songs by", className: "flex gap-1 text-xs", children: SORTS.map((sort) => /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
2565
+ /* @__PURE__ */ (0, import_jsx_runtime41.jsx)("div", { role: "group", "aria-label": "Sort songs by", className: "flex gap-1 text-caption", children: SORTS.map((sort) => /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
2566
2566
  "button",
2567
2567
  {
2568
2568
  type: "button",
@@ -2683,7 +2683,7 @@ function SongHistory({ uuid, getBackendBaseUrl }) {
2683
2683
  if (history.status === "loading") body = /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(import_ui17.Skeleton, { className: "h-10", "aria-busy": "true" });
2684
2684
  else if (history.status === "error") body = /* @__PURE__ */ (0, import_jsx_runtime43.jsx)("p", { className: "text-red-600", children: "Could not load the history." });
2685
2685
  else if (history.status === "success")
2686
- body = history.entries.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime43.jsx)("p", { className: "text-[var(--color-text-muted)]", children: "No changes yet." }) : /* @__PURE__ */ (0, import_jsx_runtime43.jsx)("ul", { className: "divide-y divide-[var(--color-border)]", children: history.entries.map((entry) => /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)("li", { className: "py-1.5 text-sm", children: [
2686
+ body = history.entries.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime43.jsx)("p", { className: "text-[var(--color-text-muted)]", children: "No changes yet." }) : /* @__PURE__ */ (0, import_jsx_runtime43.jsx)("ul", { className: "divide-y divide-[var(--color-border)]", children: history.entries.map((entry) => /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)("li", { className: "py-1.5 text-body", children: [
2687
2687
  /* @__PURE__ */ (0, import_jsx_runtime43.jsx)("span", { className: "font-medium", children: entry.action }),
2688
2688
  entry.oldValue !== null || entry.newValue !== null ? /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)("span", { className: "text-[var(--color-text-muted)]", children: [
2689
2689
  " ",
@@ -2692,7 +2692,7 @@ function SongHistory({ uuid, getBackendBaseUrl }) {
2692
2692
  " \u2192 ",
2693
2693
  entry.newValue ?? "none"
2694
2694
  ] }) : null,
2695
- /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)("span", { className: "block text-xs text-[var(--color-text-muted)]", children: [
2695
+ /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)("span", { className: "block text-caption text-[var(--color-text-muted)]", children: [
2696
2696
  entry.actorPseudo ?? "Anonymous",
2697
2697
  " \xB7 ",
2698
2698
  dateFormat.format(new Date(entry.createdOn))
@@ -2765,12 +2765,12 @@ function SongPanelContent(props) {
2765
2765
  });
2766
2766
  return /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)(import_jsx_runtime43.Fragment, { children: [
2767
2767
  /* @__PURE__ */ (0, import_jsx_runtime43.jsx)("div", { className: "genre-action-band border-b border-[var(--color-border)]", children: /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)("div", { className: "flex flex-wrap gap-1 px-3.5 py-3", children: [
2768
- unplayableReason ? /* @__PURE__ */ (0, import_jsx_runtime43.jsx)("p", { className: "flex items-center px-2.5 text-sm text-[var(--color-text-muted)]", children: unplayableReason }) : /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)(
2768
+ unplayableReason ? /* @__PURE__ */ (0, import_jsx_runtime43.jsx)("p", { className: "flex items-center px-2.5 text-body text-[var(--color-text-muted)]", children: unplayableReason }) : /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)(
2769
2769
  "button",
2770
2770
  {
2771
2771
  type: "button",
2772
2772
  onClick: () => isCurrent ? handlePlayPauseAction() : playNewTrackListFromTrackUuid(song, scope),
2773
- className: "group flex flex-col items-center gap-1 w-16 text-xs text-center text-[var(--color-text)] focus-visible:outline-none",
2773
+ className: "group flex flex-col items-center gap-1 w-16 text-caption text-center text-[var(--color-text)] focus-visible:outline-none",
2774
2774
  children: [
2775
2775
  /* @__PURE__ */ (0, import_jsx_runtime43.jsx)("span", { className: "flex items-center justify-center w-10 h-10 rounded-full group-focus-visible:ring-2 group-focus-visible:ring-[var(--color-focus-ring)] bg-[var(--color-surface-muted)] transition-colors group-hover:bg-[var(--color-border)]", children: isPlaying ? /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(import_lucide_react15.Pause, { "aria-hidden": "true", className: "w-5 h-5" }) : /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(import_lucide_react15.Play, { "aria-hidden": "true", className: "w-5 h-5" }) }),
2776
2776
  isPlaying ? "Pause" : "Play"
@@ -3278,7 +3278,7 @@ function GenreTreeView({
3278
3278
  ) : null;
3279
3279
  const renderArtistFilter = () => {
3280
3280
  if (isLoading || !filterArtist) return null;
3281
- return /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)("span", { className: "inline-flex items-center overflow-hidden rounded-full bg-[var(--color-neutral-100)] text-sm", children: [
3281
+ return /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)("span", { className: "inline-flex items-center overflow-hidden rounded-full bg-[var(--color-neutral-100)] text-body", children: [
3282
3282
  /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(
3283
3283
  "button",
3284
3284
  {
@@ -3389,14 +3389,14 @@ function GenreTreeView({
3389
3389
  /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(
3390
3390
  "div",
3391
3391
  {
3392
- className: `actions-container absolute z-30 flex items-center gap-2 ${placement === "regions" ? "left-[calc(var(--layout-gutter)+var(--layout-panel-inset))] top-[calc(var(--layout-gutter)+var(--layout-panel-inset))] max-md:right-[calc(var(--layout-gutter)+var(--layout-panel-inset))] max-md:top-[var(--layout-band-top)] max-md:flex-col max-md:items-stretch" : "left-5 top-5"}`,
3392
+ className: `actions-container absolute z-30 flex items-center gap-2 ${placement === "regions" ? "left-[calc(var(--layout-gutter)+var(--layout-panel-inset))] top-[calc(var(--layout-gutter)+var(--layout-panel-inset))] md:left-[var(--layout-panel-inset)] md:top-[var(--layout-panel-inset)] max-md:right-[calc(var(--layout-gutter)+var(--layout-panel-inset))] max-md:top-[var(--layout-band-top)] max-md:flex-col max-md:items-stretch" : "left-5 top-5"}`,
3393
3393
  children: actions
3394
3394
  }
3395
3395
  ),
3396
3396
  !isLoading && !isError && filterArtist && /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(
3397
3397
  "div",
3398
3398
  {
3399
- className: `absolute left-1/2 z-30 hidden -translate-x-1/2 md:block ${placement === "regions" ? "top-[calc(var(--layout-gutter)+var(--layout-panel-inset))]" : "top-5"}`,
3399
+ className: `absolute left-1/2 z-30 hidden -translate-x-1/2 md:block ${placement === "regions" ? "top-[calc(var(--layout-gutter)+var(--layout-panel-inset))] md:top-[var(--layout-panel-inset)]" : "top-5"}`,
3400
3400
  children: renderArtistFilter()
3401
3401
  }
3402
3402
  ),
@@ -3666,7 +3666,7 @@ function TrackListSidebar({
3666
3666
  /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("div", { className: "from h-auto flex flex-col justify-center items-center mr-2", children: "From" }),
3667
3667
  /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("div", { className: "name-container flex flex-col justify-center items-center text-[var(--color-text)] font-bold pr-2 max-w-[27.5rem]", children: /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("div", { className: "name max-w-full truncate", children: trackList.origin.label }) })
3668
3668
  ] }),
3669
- /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("div", { className: "info flex items-center text-sm text-[var(--color-text-muted)]", children: [
3669
+ /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("div", { className: "info flex items-center text-body text-[var(--color-text-muted)]", children: [
3670
3670
  trackList.origin.type === import_genre_tree30.TrackListOriginType.GENRE_PLAYLIST ? "Genre \u2022 " : trackList.origin.type === import_genre_tree30.TrackListOriginType.ARTIST ? "Artist \u2022 " : `${trackNoun.singular} playlist \u2022 `,
3671
3671
  `${trackList.total} ${trackList.total > 1 ? trackNoun.plural : trackNoun.singular}`
3672
3672
  ] })