Design
llms.txt digitalcrew.tech

Data display

MaxIconSet

Max's own SVG icons, exported as DC.MaxIcons: integration and channel logos, message delivery states, and the appearance-picker tiles.

MaxData displayShowcase page
MaxIconSet · live · 960px wideOpen

Guidelines#

Everything else comes from Lucide.

Use it for the things Lucide has no icon for: connected accounts and CRMs (Google, Outlook, LinkedIn, WhatsApp, HubSpot, Salesforce, Slack, Zoho, Notion), data providers (Apollo, Explorium, GetLeads), message status ticks in the Unibox, and the option tiles in Settings › Appearance.

What you provide:

  • Logo icons take { className, size }, with size defaulting to 16px. They keep their brand colours. MailIcon is the exception: it strokes in currentColor.
  • Message states take { className, size }, with size defaulting to 14px, and are shrink-0.
    • IconMessageSent: a single check.
    • IconMessageDelivered: a double check whose first tick is text-muted-foreground.
    • IconMessageRead: a double check in text-green-500 dark:text-green-400.
    • IconMessageFailed.
  • The tiles (IconThemeSystem, IconThemeLight, IconThemeDark, IconSplashCursor, IconSplashCursorDisabled) are 79.86 × 51.14 illustrations. They take SVG props and no size, so set their width with a class. IconThemeSystem fills with primary, falling back to muted-foreground inside an unchecked group. The splash tiles have dark: fills.

Anatomy: the page shows every export at 24px (the tiles at 24px tall), with the export name beside it.

Don't recolour brand logos. Don't use the tiles as inline icons: they are option previews.

Facts#

GroupData display
ProductMax
KindShowcase page (tokens and patterns, not a single export)
Sourcemax-agent: src/components/icons/

Example#

The code of the preview above: plain React.createElement against window.DigitalCrew, with realistic data.

<div id="root" class="p-6"></div>
<script>
(function () {
  var h = React.createElement, DC = window.DigitalCrew, I = DC.Icons;
  // Brand and message-state icons take size (px); the theme and splash tiles are
  // 79.86 × 51.14 illustrations sized by className, shown here 24px tall.
  var TILES = ["IconThemeSystem", "IconThemeLight", "IconThemeDark", "IconSplashCursor", "IconSplashCursorDisabled"];
  var GROUPS = [
    ["Integrations and channels", Object.keys(DC.MaxIcons).filter(function (n) { return /Icon$/.test(n); })],
    ["Message delivery states", Object.keys(DC.MaxIcons).filter(function (n) { return /^IconMessage/.test(n); })],
    ["Appearance tiles", Object.keys(DC.MaxIcons).filter(function (n) { return TILES.indexOf(n) >= 0; })]
  ];
  function Item(props) {
    var Icon = DC.MaxIcons[props.name], tile = TILES.indexOf(props.name) >= 0;
    return h("div", { className: "flex items-center gap-3 rounded-lg border bg-card px-3 py-2.5" },
      h("div", { className: "flex h-6 min-w-6 items-center justify-center" },
        tile ? h(Icon, { className: "h-6 w-auto", style: { height: 24, width: "auto" } }) : h(Icon, { size: 24 })),
      h("code", { className: "min-w-0 break-all font-mono text-xs leading-tight" }, props.name));
  }
  function App() {
    return h("div", { className: "space-y-5" },
      GROUPS.map(function (g) {
        return h("section", { key: g[0], className: "space-y-2" },
          h("p", { className: "text-xs font-semibold uppercase tracking-wider text-muted-foreground" }, g[0] + " · " + g[1].length),
          h("div", { className: "grid grid-cols-4 gap-2" }, g[1].map(function (n) { return h(Item, { key: n, name: n }); })));
      }));
  }
  ReactDOM.createRoot(document.getElementById("root")).render(h(DC.TooltipProvider, { delayDuration: 80 }, h(App)));
})();
</script>