> ## Documentation Index
> Fetch the complete documentation index at: https://anvil.servicetitan.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Empty States

> Reference implementations for empty state lockups.

export const LiveCode = ({children, customHeight, clickToLoad, example, fullWidth, fullHeight, hideCodeInLiveCode, screenshot, screenshotOnly, showCode: showCodeProp}) => {
  const SCREENSHOTS_BASE = "https://servicetitan.github.io/anvil2-docs-live-code/screenshots";
  const STACKBLITZ_BASE = "https://stackblitz.com/github/servicetitan/anvil2-docs-live-code/tree/main/examples";
  const [showCodeBlock, setShowCodeBlock] = useState(showCodeProp ?? false);
  const [isLocalOverride, setIsLocalOverride] = useState(false);
  useEffect(() => {
    const examplePath = `/images/live-code-screenshots-tmp/${example}.png`;
    fetch(examplePath, {
      method: "HEAD"
    }).then(r => {
      if (r.ok) setIsLocalOverride(true);
    }).catch(() => {});
  }, [example]);
  const screenshotBase = isLocalOverride ? "/images/live-code-screenshots-tmp" : SCREENSHOTS_BASE;
  if (screenshotOnly) {
    return <Frame className="flex flex-col">
        <div className="flex dark:hidden" style={{
      justifyContent: "center",
      alignItems: "center",
      width: fullWidth ? "100%" : "50%",
      minHeight: fullHeight ? "284px" : undefined,
      background: "#FFFFFF"
    }}>
          <img srcset={`${screenshotBase}/${example}.png, ${screenshotBase}/${example}-2x.png 2x`} src={`${screenshotBase}/${example}.png`} alt={example} noZoom />
        </div>
        <div className="hidden dark:flex" style={{
      justifyContent: "center",
      alignItems: "center",
      width: fullWidth ? "100%" : "50%",
      minHeight: fullHeight ? "284px" : undefined,
      background: "#141414"
    }}>
          <img srcset={`${screenshotBase}/${example}-dark.png, ${screenshotBase}/${example}-dark-2x.png 2x`} src={`${screenshotBase}/${example}-dark.png`} alt={example} noZoom />
        </div>
      </Frame>;
  }
  if (screenshot) {
    return <Frame className="flex flex-col -mb-2">
        <div className="flex dark:hidden bg-white dark:bg-codeblock border border-gray-950/10 dark:border-white/10 dark:twoslash-dark rounded-2xl overflow-hidden" style={{
      justifyContent: "center",
      alignItems: "center",
      width: fullWidth ? "100%" : "50%",
      minHeight: fullHeight ? "284px" : undefined
    }}>
          <img srcset={`${screenshotBase}/${example}.png, ${screenshotBase}/${example}-2x.png 2x`} src={`${screenshotBase}/${example}.png`} alt={example} noZoom />
        </div>

        <div className="hidden dark:flex bg-white dark:bg-codeblock border border-gray-950/10 dark:border-white/10 dark:twoslash-dark rounded-2xl overflow-hidden" style={{
      background: "#141414",
      justifyContent: "center",
      alignItems: "center",
      width: fullWidth ? "100%" : "50%",
      minHeight: fullHeight ? "284px" : undefined
    }}>
          <img srcset={`${screenshotBase}/${example}-dark.png, ${screenshotBase}/${example}-dark-2x.png 2x`} src={`${screenshotBase}/${example}-dark.png`} alt={example} noZoom />
        </div>

        <div className="flex justify-end items-center text-xs py-2 px-1 gap-4">
          {!showCodeProp ? <button className="inline-flex justify-end items-center text-gray-700 dark:text-gray-50 hover:text-blue-500 dark:hover:text-blue-300 transition-colors group self-end gap-1 cursor-pointer" onClick={() => setShowCodeBlock(!showCodeBlock)} style={{
      appearance: "none"
    }}>
              <Icon icon="code" size="12px" className="group-hover:bg-blue-500 dark:group-hover:bg-blue-300" />
              <span>{showCodeBlock ? "Hide code" : "Show code"}</span>
            </button> : null}

          <a className="inline-flex justify-end items-center hover:text-blue-500 dark:hover:text-blue-300 transition-colors group self-end gap-1" href={`${STACKBLITZ_BASE}/${example}?file=src/App.tsx`} target="_blank" rel="noreferrer">
            <Icon icon="bolt" size="12px" className="group-hover:bg-blue-500 dark:group-hover:bg-blue-300" />
            <span>StackBlitz demo</span>
          </a>
        </div>

        <div className="grid transition-[grid-template-rows] duration-300 ease-in-out overflow-auto overflow-y-hidden overflow-x-auto" style={showCodeBlock ? {
      gridTemplateRows: "1fr"
    } : {
      gridTemplateRows: "0fr"
    }}>
          <div style={{
      minHeight: 0,
      overflowX: "auto",
      overflowY: "hidden",
      marginBlockStart: "-1.25rem",
      marginBlockEnd: "-1.5rem"
    }}>
            {children}
          </div>
        </div>
      </Frame>;
  } else {
    return <div style={{
      display: "flex",
      width: fullWidth ? "100%" : "50%",
      minHeight: customHeight ? customHeight : "316px",
      resize: "vertical",
      overflow: "auto"
    }}>
        <iframe title={example} style={{
      flex: 1,
      width: fullWidth ? "100%" : "50%",
      minHeight: customHeight ? customHeight : "316px"
    }} src={`${STACKBLITZ_BASE}/${example}?embed=1&hideNavigation=1&hideExplorer=1&terminalHeight=0&file=src/App.tsx${clickToLoad ? "&ctl=1" : ""}${hideCodeInLiveCode ? "&view=preview" : ""}`} allow="accelerometer; ambient-light-sensor; camera; encrypted-media; geolocation; gyroscope; hid; microphone; midi; payment; usb; vr; xr-spatial-tracking" sandbox="allow-forms allow-modals allow-popups allow-presentation allow-same-origin allow-scripts" />
      </div>;
  }
};

Empty states tell the user there is nothing to show yet — a first-run setup, a cleared queue, a search with no results, or a system state outside their control. Each example below is a starting point: copy it, then adapt the copy, icon or illustration, and actions to your use case. For guidance on when each type applies, see the Empty states pattern.

## Resources

<Card title="Empty states pattern" icon="layer-group" href="/docs/web/patterns/empty-states">
  When to use empty states and related guidance.
</Card>

<Card title="Empty states" icon="figma" href="https://www.figma.com/design/9OB8FwOZZc079PBR6XY8vP/Anvil-Blocks?node-id=2-2053">
  Figma reference implementations for empty state lockups.
</Card>

## Start Setup

Guide the user to configure a feature that has not been set up yet, with an illustration and a primary action.

<LiveCode example="block-empty-state-start-setup" screenshot fullWidth>
  ```tsx lines theme={null}
  import {
    Flex,
    Text,
    Button,
    usePrefersColorScheme,
  } from "@servicetitan/anvil2";
  import FirstUseLight from "@servicetitan/anvil2-illustrations/illustrations/empty-state-first-use-light.svg";
  import FirstUseDark from "@servicetitan/anvil2-illustrations/illustrations/empty-state-first-use-dark.svg";

  function App() {
    const { mode } = usePrefersColorScheme();
    const Illustration = mode === "dark" ? FirstUseDark : FirstUseLight;

    return (
      <Flex justifyContent="center" style={{ padding: "2rem", width: "100%" }}>
        <Flex
          direction="column"
          alignItems="center"
          gap={4}
          style={{ textAlign: "center", maxWidth: 480, width: "100%" }}
        >
          <div
            style={{
              flexShrink: 0,
              width: 300,
              maxWidth: "100%",
              overflow: "hidden",
            }}
          >
            <Illustration
              aria-hidden
              style={{ display: "block", width: "100%", height: "auto" }}
            />
          </div>
          <Flex direction="column" alignItems="center" gap={2}>
            <Text size="large" inline style={{ fontWeight: "bold" }}>
              Looks like Reports haven’t been set up yet
            </Text>
            <Text subdued>
              Set it up today to start improving your business through our
              integrated system.
            </Text>
          </Flex>
          <Button appearance="primary" onClick={() => console.log("Start Setup")}>
            Start Setup
          </Button>
        </Flex>
      </Flex>
    );
  }

  export default App;
  ```
</LiveCode>

## Headlines

Introduce a feature area with a bold headline, supporting text, and a secondary action.

<LiveCode example="block-empty-state-headlines" screenshot fullWidth>
  ```tsx lines theme={null}
  import {
    Flex,
    Text,
    Button,
    usePrefersColorScheme,
  } from "@servicetitan/anvil2";
  import NoSearchResultsLight from "@servicetitan/anvil2-illustrations/illustrations/empty-state-no-search-results-light.svg";
  import NoSearchResultsDark from "@servicetitan/anvil2-illustrations/illustrations/empty-state-no-search-results-dark.svg";

  function App() {
    const { mode } = usePrefersColorScheme();
    const Illustration =
      mode === "dark" ? NoSearchResultsDark : NoSearchResultsLight;

    return (
      <Flex justifyContent="center" style={{ padding: "2rem", width: "100%" }}>
        <Flex
          direction="column"
          alignItems="center"
          gap={4}
          style={{ textAlign: "center", maxWidth: 480, width: "100%" }}
        >
          <div
            style={{
              flexShrink: 0,
              width: 300,
              maxWidth: "100%",
              overflow: "hidden",
            }}
          >
            <Illustration
              aria-hidden
              style={{ display: "block", width: "100%", height: "auto" }}
            />
          </div>
          <Flex direction="column" alignItems="center" gap={2}>
            <Text size="large" inline style={{ fontWeight: "bold" }}>
              Bookmark Your Reports
            </Text>
            <Text subdued>
              Bookmarked reports will appear here for quick access.
            </Text>
          </Flex>
          <Button
            appearance="secondary"
            onClick={() => console.log("Learn More")}
          >
            Learn More
          </Button>
        </Flex>
      </Flex>
    );
  }

  export default App;
  ```
</LiveCode>

## Neutral Feedback

State a neutral, informational empty result. Use when there is nothing to show yet and no action is needed.

<LiveCode example="block-empty-state-neutral-feedback" screenshot fullWidth>
  ```tsx lines theme={null}
  import { Flex, Text } from "@servicetitan/anvil2";

  function App() {
    return (
      <Flex justifyContent="center" style={{ padding: "2rem", width: "100%" }}>
        <Flex
          direction="column"
          alignItems="center"
          style={{ textAlign: "center", maxWidth: 480, width: "100%" }}
        >
          <Text subdued style={{ textAlign: "center" }}>
            You have no billing history. When an invoice is complete, it will
            appear here.
          </Text>
        </Flex>
      </Flex>
    );
  }

  export default App;
  ```
</LiveCode>

## Neutral Feedback (alt)

The neutral message with a subdued icon for a little more presence.

<LiveCode example="block-empty-state-neutral-feedback-alt" screenshot fullWidth>
  ```tsx lines theme={null}
  import { Flex, Text, Icon } from "@servicetitan/anvil2";
  import MoneyOff from "@servicetitan/anvil2/assets/icons/material/round/money_off.svg";

  function App() {
    return (
      <Flex justifyContent="center" style={{ padding: "2rem", width: "100%" }}>
        <Flex
          direction="column"
          alignItems="center"
          gap={4}
          style={{ textAlign: "center", maxWidth: 480, width: "100%" }}
        >
          <Icon
            svg={MoneyOff}
            size="large"
            color="var(--a2-foreground-color-subdued)"
            aria-hidden
          />
          <Text subdued style={{ textAlign: "center" }}>
            You have no billing history. When an invoice is complete, it will
            appear here.
          </Text>
        </Flex>
      </Flex>
    );
  }

  export default App;
  ```
</LiveCode>

## Negative Feedback

Signal a failed or empty search and offer a corrective action inline.

<LiveCode example="block-empty-state-negative-feedback" screenshot fullWidth>
  ```tsx lines theme={null}
  import { Flex, Text, Icon, Link } from "@servicetitan/anvil2";
  import Block from "@servicetitan/anvil2/assets/icons/material/round/block.svg";

  function App() {
    return (
      <Flex justifyContent="center" style={{ padding: "2rem", width: "100%" }}>
        <Flex
          direction="column"
          alignItems="center"
          gap={4}
          style={{ textAlign: "center", maxWidth: 480, width: "100%" }}
        >
          <Icon
            svg={Block}
            size="large"
            color="var(--a2-color-red-600)"
            aria-hidden
          />
          <Text subdued style={{ textAlign: "center" }}>
            No results found. Try another search or{" "}
            <Link href="#">create a new report</Link>.
          </Text>
        </Flex>
      </Flex>
    );
  }

  export default App;
  ```
</LiveCode>

## Positive Feedback (icon)

Confirm an up-to-date state with a success icon and a short message.

<LiveCode example="block-empty-state-positive-feedback-icon" screenshot fullWidth>
  ```tsx lines theme={null}
  import { Flex, Text, Icon } from "@servicetitan/anvil2";
  import CheckCircle from "@servicetitan/anvil2/assets/icons/material/round/check_circle.svg";

  function App() {
    return (
      <Flex justifyContent="center" style={{ padding: "2rem", width: "100%" }}>
        <Flex
          direction="column"
          alignItems="center"
          gap={4}
          style={{ textAlign: "center", maxWidth: 480, width: "100%" }}
        >
          <Icon
            svg={CheckCircle}
            size="large"
            color="var(--a2-color-blue-600)"
            aria-hidden
          />
          <Text subdued style={{ textAlign: "center" }}>
            Your report is up-to-date! Check back later for new updates.
          </Text>
        </Flex>
      </Flex>
    );
  }

  export default App;
  ```
</LiveCode>

## Positive Feedback (illustration)

Confirm success with an illustration and an optional follow-up link.

<LiveCode example="block-empty-state-positive-feedback-illustration" screenshot fullWidth>
  ```tsx lines theme={null}
  import { Flex, Text, Link, usePrefersColorScheme } from "@servicetitan/anvil2";
  import SuccessLight from "@servicetitan/anvil2-illustrations/illustrations/empty-state-success-light.svg";
  import SuccessDark from "@servicetitan/anvil2-illustrations/illustrations/empty-state-success-dark.svg";

  function App() {
    const { mode } = usePrefersColorScheme();
    const Illustration = mode === "dark" ? SuccessDark : SuccessLight;

    return (
      <Flex justifyContent="center" style={{ padding: "2rem", width: "100%" }}>
        <Flex
          direction="column"
          alignItems="center"
          gap={4}
          style={{ textAlign: "center", maxWidth: 480, width: "100%" }}
        >
          <div
            style={{
              flexShrink: 0,
              width: 300,
              maxWidth: "100%",
              overflow: "hidden",
            }}
          >
            <Illustration
              aria-hidden
              style={{ display: "block", width: "100%", height: "auto" }}
            />
          </div>
          <Text subdued style={{ textAlign: "center" }}>
            Your report is up-to-date! Check back later for new updates. To see
            the history of changes, <Link href="#">view your sync log</Link>.
          </Text>
        </Flex>
      </Flex>
    );
  }

  export default App;
  ```
</LiveCode>

## Out of User Control (icon)

Explain a system state the user cannot act on, with an icon and a short message.

<LiveCode example="block-empty-state-out-of-user-control-icon" screenshot fullWidth>
  ```tsx lines theme={null}
  import { Flex, Text, Icon } from "@servicetitan/anvil2";
  import Build from "@servicetitan/anvil2/assets/icons/material/round/build.svg";

  function App() {
    return (
      <Flex justifyContent="center" style={{ padding: "2rem", width: "100%" }}>
        <Flex
          direction="column"
          alignItems="center"
          gap={4}
          style={{ textAlign: "center", maxWidth: 480, width: "100%" }}
        >
          <Icon
            svg={Build}
            size="large"
            color="var(--a2-foreground-color-subdued)"
            aria-hidden
          />
          <Text subdued style={{ textAlign: "center" }}>
            This account is going through routine maintenance. Your connection
            should resume as normal in a couple hours.
          </Text>
        </Flex>
      </Flex>
    );
  }

  export default App;
  ```
</LiveCode>

## Out of User Control (illustration)

Explain a longer system process with an illustration, headline, and detail.

<LiveCode example="block-empty-state-out-of-user-control-illustration" screenshot fullWidth>
  ```tsx lines theme={null}
  import { Flex, Text, usePrefersColorScheme } from "@servicetitan/anvil2";
  import UserClearedLight from "@servicetitan/anvil2-illustrations/illustrations/empty-state-user-cleared-light.svg";
  import UserClearedDark from "@servicetitan/anvil2-illustrations/illustrations/empty-state-user-cleared-dark.svg";

  function App() {
    const { mode } = usePrefersColorScheme();
    const Illustration = mode === "dark" ? UserClearedDark : UserClearedLight;

    return (
      <Flex justifyContent="center" style={{ padding: "2rem", width: "100%" }}>
        <Flex
          direction="column"
          alignItems="center"
          gap={4}
          style={{ textAlign: "center", maxWidth: 480, width: "100%" }}
        >
          <div
            style={{
              flexShrink: 0,
              width: 300,
              maxWidth: "100%",
              overflow: "hidden",
            }}
          >
            <Illustration
              aria-hidden
              style={{ display: "block", width: "100%", height: "auto" }}
            />
          </div>
          <Flex direction="column" alignItems="center" gap={2}>
            <Text size="large" inline style={{ fontWeight: "bold" }}>
              Your Account is Being Migrated
            </Text>
            <Text subdued>
              We are working on setting up your account. Verifying the information
              can take up to 3 business days. You will receive an email when your
              account is ready.
            </Text>
          </Flex>
        </Flex>
      </Flex>
    );
  }

  export default App;
  ```
</LiveCode>

## Empty Error (icon)

Report an error with a subdued icon and an inline recovery link.

<LiveCode example="block-empty-state-empty-error-icon" screenshot fullWidth>
  ```tsx lines theme={null}
  import { Flex, Text, Icon, Link } from "@servicetitan/anvil2";
  import Error from "@servicetitan/anvil2/assets/icons/material/round/error.svg";

  function App() {
    return (
      <Flex justifyContent="center" style={{ padding: "2rem", width: "100%" }}>
        <Flex
          direction="column"
          alignItems="center"
          gap={4}
          style={{ textAlign: "center", maxWidth: 480, width: "100%" }}
        >
          <Icon
            svg={Error}
            size="large"
            color="var(--a2-foreground-color-subdued)"
            aria-hidden
          />
          <Text subdued style={{ textAlign: "center" }}>
            The server didn’t recognize your request. We are currently
            investigating the problem. Go back or <Link href="#">try again</Link>.
          </Text>
        </Flex>
      </Flex>
    );
  }

  export default App;
  ```
</LiveCode>

## Empty Error (illustration)

Report an error with an illustration, an inline recovery link, and a recovery action.

<LiveCode example="block-empty-state-empty-error-illustration" screenshot fullWidth>
  ```tsx lines theme={null}
  import {
    Flex,
    Text,
    Button,
    Link,
    usePrefersColorScheme,
  } from "@servicetitan/anvil2";
  import ErrorLight from "@servicetitan/anvil2-illustrations/illustrations/empty-state-error-light.svg";
  import ErrorDark from "@servicetitan/anvil2-illustrations/illustrations/empty-state-error-dark.svg";

  function App() {
    const { mode } = usePrefersColorScheme();
    const Illustration = mode === "dark" ? ErrorDark : ErrorLight;

    return (
      <Flex justifyContent="center" style={{ padding: "2rem", width: "100%" }}>
        <Flex
          direction="column"
          alignItems="center"
          gap={4}
          style={{ textAlign: "center", maxWidth: 480, width: "100%" }}
        >
          <div
            style={{
              flexShrink: 0,
              width: 300,
              maxWidth: "100%",
              overflow: "hidden",
            }}
          >
            <Illustration
              aria-hidden
              style={{ display: "block", width: "100%", height: "auto" }}
            />
          </div>
          <Flex direction="column" alignItems="center" gap={2}>
            <Text size="large" inline style={{ fontWeight: "bold" }}>
              We Didn’t Catch That
            </Text>
            <Text subdued>
              The server didn’t recognize your request. We are currently
              investigating the problem. Go back or{" "}
              <Link href="#">try again</Link>.
            </Text>
          </Flex>
          <Button appearance="secondary" onClick={() => console.log("Go Back")}>
            Go Back
          </Button>
        </Flex>
      </Flex>
    );
  }

  export default App;
  ```
</LiveCode>

## Starting Points

Offer a set of suggested next actions in interactive cards to help the user begin.

<LiveCode example="block-empty-state-starting-points" screenshot fullWidth>
  ```tsx lines theme={null}
  import { Flex, Grid, Divider, Button, Text, Icon } from "@servicetitan/anvil2";
  import { InteractiveCard } from "@servicetitan/anvil2/beta";
  import Build from "@servicetitan/anvil2/assets/icons/material/round/build.svg";
  import CardMembership from "@servicetitan/anvil2/assets/icons/material/round/card_membership.svg";
  import Pause from "@servicetitan/anvil2/assets/icons/material/round/pause.svg";
  import Schedule from "@servicetitan/anvil2/assets/icons/material/round/schedule.svg";
  import ArrowForward from "@servicetitan/anvil2/assets/icons/material/round/arrow_forward.svg";

  function App() {
    return (
      <Flex justifyContent="center" style={{ padding: "2rem", width: "100%" }}>
        <Flex direction="column" gap={5} style={{ maxWidth: 850, width: "100%" }}>
          <Flex
            direction="column"
            alignItems="center"
            gap={1}
            style={{ textAlign: "center", width: "100%" }}
          >
            <Text variant="headline" el="h2" size="medium">
              Welcome to Reports
            </Text>
            <Text subdued>
              You don’t have any reports. Here are some suggestions to get started
              with your first one.
            </Text>
          </Flex>

          <Divider spacing="0" />

          <Grid
            templateColumns="1fr"
            gap={4}
            md={{ templateColumns: "repeat(2, minmax(0, 1fr))" }}
          >
            <Grid.Item>
              <InteractiveCard
                wrapperProps={{
                  "aria-label": "Unsold Estimates card",
                  style: { height: "100%" },
                }}
                actionProps={{
                  "aria-label": "Unsold Estimates",
                  onClick: () => console.log("Unsold Estimates"),
                }}
                contentProps={{
                  padding: "medium",
                  gap: 4,
                  style: { width: "100%" },
                }}
              >
                <Icon svg={Build} size="small" aria-hidden />
                <Flex direction="column" gap={1} style={{ minWidth: 0 }}>
                  <Text inline style={{ fontWeight: "bold" }}>
                    Unsold Estimates
                  </Text>
                  <Text subdued size="small">
                    Find and target open estimates. Leave no opportunity behind by
                    creating custom parameters with your audience.
                  </Text>
                </Flex>
              </InteractiveCard>
            </Grid.Item>

            <Grid.Item>
              <InteractiveCard
                wrapperProps={{
                  "aria-label": "Expiring Memberships card",
                  style: { height: "100%" },
                }}
                actionProps={{
                  "aria-label": "Expiring Memberships",
                  onClick: () => console.log("Expiring Memberships"),
                }}
                contentProps={{
                  padding: "medium",
                  gap: 4,
                  style: { width: "100%" },
                }}
              >
                <Icon svg={CardMembership} size="small" aria-hidden />
                <Flex direction="column" gap={1} style={{ minWidth: 0 }}>
                  <Text inline style={{ fontWeight: "bold" }}>
                    Expiring Memberships
                  </Text>
                  <Text subdued size="small">
                    Automatically reach out to customers with soon to expire
                    memberships. Allow customers to see what memberships will
                    expire and when. Prompt them to take action and renew.
                  </Text>
                </Flex>
              </InteractiveCard>
            </Grid.Item>

            <Grid.Item>
              <InteractiveCard
                wrapperProps={{
                  "aria-label": "Idle Account card",
                  style: { height: "100%" },
                }}
                actionProps={{
                  "aria-label": "Idle Account",
                  onClick: () => console.log("Idle Account"),
                }}
                contentProps={{
                  padding: "medium",
                  gap: 4,
                  style: { width: "100%" },
                }}
              >
                <Icon svg={Pause} size="small" aria-hidden />
                <Flex direction="column" gap={1} style={{ minWidth: 0 }}>
                  <Text inline style={{ fontWeight: "bold" }}>
                    Idle Account
                  </Text>
                  <Text subdued size="small">
                    Follow up with existing customers who have no recent activity
                    in ServiceTitan. Customize the date parameter to find
                    customers who have not called or booked a job.
                  </Text>
                </Flex>
              </InteractiveCard>
            </Grid.Item>

            <Grid.Item>
              <InteractiveCard
                wrapperProps={{
                  "aria-label": "Aging Equipment card",
                  style: { height: "100%" },
                }}
                actionProps={{
                  "aria-label": "Aging Equipment",
                  onClick: () => console.log("Aging Equipment"),
                }}
                contentProps={{
                  padding: "medium",
                  gap: 4,
                  style: { width: "100%" },
                }}
              >
                <Icon svg={Schedule} size="small" aria-hidden />
                <Flex direction="column" gap={1} style={{ minWidth: 0 }}>
                  <Text inline style={{ fontWeight: "bold" }}>
                    Aging Equipment
                  </Text>
                  <Text subdued size="small">
                    Target customers with specific equipment. Let them know you’re
                    aware of their home and encourage them to take the next step
                    in protecting their home.
                  </Text>
                </Flex>
              </InteractiveCard>
            </Grid.Item>
          </Grid>

          <Flex justifyContent="end">
            <Button
              appearance="secondary"
              icon={{ after: ArrowForward }}
              onClick={() => console.log("Or start from an empty project")}
            >
              Or start from an empty project
            </Button>
          </Flex>
        </Flex>
      </Flex>
    );
  }

  export default App;
  ```
</LiveCode>

## Best Match

Show a no-results state with recommended alternatives the user can act on.

<LiveCode example="block-empty-state-best-match" screenshot fullWidth>
  ```tsx lines theme={null}
  import {
    Avatar,
    Button,
    Divider,
    Flex,
    Text,
    usePrefersColorScheme,
  } from "@servicetitan/anvil2";
  import Add from "@servicetitan/anvil2/assets/icons/material/round/add.svg";
  import NoSearchResultsLight from "@servicetitan/anvil2-illustrations/illustrations/empty-state-no-search-results-light.svg";
  import NoSearchResultsDark from "@servicetitan/anvil2-illustrations/illustrations/empty-state-no-search-results-dark.svg";

  function App() {
    const { mode } = usePrefersColorScheme();
    const Illustration =
      mode === "dark" ? NoSearchResultsDark : NoSearchResultsLight;

    return (
      <Flex justifyContent="center" style={{ padding: "2rem", width: "100%" }}>
        <Flex direction="column" gap={5} style={{ maxWidth: 600, width: "100%" }}>
          <Flex
            direction="column"
            alignItems="center"
            gap={1}
            style={{ textAlign: "center", width: "100%" }}
          >
            <div
              style={{
                flexShrink: 0,
                width: 300,
                maxWidth: "100%",
                overflow: "hidden",
              }}
            >
              <Illustration
                aria-hidden
                style={{ display: "block", width: "100%", height: "auto" }}
              />
            </div>
            <Text size="large" inline style={{ fontWeight: "bold" }}>
              Sorry, we couldn’t find any results for{" "}
              <Text inline style={{ color: "var(--a2-color-blue-600)" }}>
                “jfjkleiklfj”
              </Text>
            </Text>
            <Text subdued>
              Remember to check your spelling or try searching for something else.
            </Text>
          </Flex>

          <Text inline style={{ fontWeight: "bold" }}>
            Try these instead:
          </Text>

          <Flex direction="column" style={{ width: "100%" }}>
            <Divider spacing="4" />
            <Flex
              alignItems="center"
              justifyContent="space-between"
              gap={3}
              style={{ width: "100%" }}
            >
              <Flex alignItems="center" gap={2} style={{ minWidth: 0 }}>
                <Avatar name="Lindsay Walton" size="medium" />
                <Flex direction="column" style={{ minWidth: 0 }}>
                  <Text inline style={{ fontWeight: "bold" }}>
                    Lindsay Walton
                  </Text>
                  <Text subdued size="small">
                    Front-end Developer
                  </Text>
                </Flex>
              </Flex>
              <Button
                appearance="secondary"
                icon={{ before: Add }}
                onClick={() => console.log("Invite Lindsay Walton")}
                style={{ flexShrink: 0 }}
              >
                Invite
              </Button>
            </Flex>
            <Divider spacing="4" />

            <Flex
              alignItems="center"
              justifyContent="space-between"
              gap={3}
              style={{ width: "100%" }}
            >
              <Flex alignItems="center" gap={2} style={{ minWidth: 0 }}>
                <Avatar name="Courtney Henry" size="medium" />
                <Flex direction="column" style={{ minWidth: 0 }}>
                  <Text inline style={{ fontWeight: "bold" }}>
                    Courtney Henry
                  </Text>
                  <Text subdued size="small">
                    Designer
                  </Text>
                </Flex>
              </Flex>
              <Button
                appearance="secondary"
                icon={{ before: Add }}
                onClick={() => console.log("Invite Courtney Henry")}
                style={{ flexShrink: 0 }}
              >
                Invite
              </Button>
            </Flex>
            <Divider spacing="4" />

            <Flex
              alignItems="center"
              justifyContent="space-between"
              gap={3}
              style={{ width: "100%" }}
            >
              <Flex alignItems="center" gap={2} style={{ minWidth: 0 }}>
                <Avatar name="Tom Cook" size="medium" />
                <Flex direction="column" style={{ minWidth: 0 }}>
                  <Text inline style={{ fontWeight: "bold" }}>
                    Tom Cook
                  </Text>
                  <Text subdued size="small">
                    Director of Product
                  </Text>
                </Flex>
              </Flex>
              <Button
                appearance="secondary"
                icon={{ before: Add }}
                onClick={() => console.log("Invite Tom Cook")}
                style={{ flexShrink: 0 }}
              >
                Invite
              </Button>
            </Flex>
            <Divider spacing="4" />
          </Flex>
        </Flex>
      </Flex>
    );
  }

  export default App;
  ```
</LiveCode>

## Queue Cleared

Celebrate a cleared queue or completed work with a light illustration.

<LiveCode example="block-empty-state-queue-cleared" screenshot fullWidth>
  ```tsx lines theme={null}
  import { Flex, Text, usePrefersColorScheme } from "@servicetitan/anvil2";
  import UserClearedLight from "@servicetitan/anvil2-illustrations/illustrations/empty-state-user-cleared-light.svg";
  import UserClearedDark from "@servicetitan/anvil2-illustrations/illustrations/empty-state-user-cleared-dark.svg";

  function App() {
    const { mode } = usePrefersColorScheme();
    const Illustration = mode === "dark" ? UserClearedDark : UserClearedLight;

    return (
      <Flex justifyContent="center" style={{ padding: "2rem", width: "100%" }}>
        <Flex
          direction="column"
          alignItems="center"
          gap={4}
          style={{ textAlign: "center", maxWidth: 480, width: "100%" }}
        >
          <div
            style={{
              flexShrink: 0,
              width: 300,
              maxWidth: "100%",
              overflow: "hidden",
            }}
          >
            <Illustration
              aria-hidden
              style={{ display: "block", width: "100%", height: "auto" }}
            />
          </div>
          <Flex direction="column" alignItems="center" gap={2}>
            <Text inline style={{ fontWeight: "bold" }}>
              Queue cleared
            </Text>
            <Text size="small" subdued>
              Grab a coffee?
            </Text>
          </Flex>
        </Flex>
      </Flex>
    );
  }

  export default App;
  ```
</LiveCode>
