# Sanity ID — full reference > Component library, design token library, and TailwindCSS v4 configuration for Sanity ID, the brand design system behind the Sanity marketing website and adjacent properties. TailwindCSS v4 is required. Version 1.15.2. ## Installation ```bash pnpm add @sanity/sanity-id ``` ## Basic Setup Add the following to your global stylesheet: ```css @import "@sanity/sanity-id/tailwind.css"; @import "@sanity/sanity-id/components.css"; ``` ## Font Setup Sanity ID uses [Waldenburg](https://kimeracorp.eu/typefaces/waldenburg) for sans-serif and [IBM Plex Mono](https://fonts.google.com/specimen/IBM+Plex+Mono) for monospace. Set up both fonts as recommended for your framework of choice and then define `--font-sans` and `--font-mono` custom properties at root level in your global styles.
Recommended Next.js setup ```tsx // fonts.ts import classNames from "classnames" import Local from "next/font/local" const waldenburgNormal = Local({ src: [ { path: "", weight: "400", style: "normal", }, { path: "", weight: "400", style: "italic", }, { path: "", weight: "600", style: "normal", }, ], display: "swap", variable: "--font-sans", fallback: ["ui-sans-serif", "system-ui", "sans-serif"], preload: true, }) const imbPlex = Local({ src: [ { path: "", weight: "400", }, { path: "", weight: "400", style: "italic", }, ], display: "swap", variable: "--font-mono", fallback: ["ui-monospace", "monospace"], preload: true, }) export const fonts = [waldenburgNormal.variable, imbPlex.variable].join(" ") // layout.tsx import { fonts } from "./fonts.tsx" export default function RootLayout(props) { return ( {props.children} ) } ```
## Using Components Components are imported separately, opposed to from a single barrel file. ```tsx import { Button } from "@sanity/sanity-id/components/button" import { Eyebrow } from "@sanity/sanity-id/components/eyebrow" function MyComponent() { return ( <> Eyebrow ) } ``` Every component's props, types, defaults, and descriptions are also available as data, generated from the components' own types at build time: ```js import manifest from "@sanity/sanity-id/manifest.json" ``` The same content is served as plain text at [llms.txt](https://sanity-id-docs.sanity.build/sanity-id/llms.txt) and [llms-full.txt](https://sanity-id-docs.sanity.build/sanity-id/llms-full.txt), for pointing an AI coding agent at the design system without it having to guess. Components are framework agnostic, so additional steps may be required when using a component from your framework of choice: ```tsx import { Button } from "@sanity/sanity-id/components/button" import { IconButton } from "@sanity/sanity-id/components/icon-button" import Link from "next/link" function MyComponent() { return ( <> Click ) } ``` ## Theming Sanity ID supports dark and light theming using a `data-theme` attribute. Apply this attribute to the root HTML element to theme an entire page and to nested elements to override the page theme (nesting only support 4 levels): ```html
``` To target a specific theme in Tailwind, use the `light` and `dark` variants: ```html

Sanity: The Content Operating System

``` ```css .background-image { @variant light { background-image: url("..."); } @variant dark { background-image: url("..."); } } ``` ## Typography Sanity ID uses Tailwind classes to apply typography styles to leverage the Tailwind's ergonomics. See the [Typography page](https://sanity-id-docs.sanity.build/sanity-id/typography) for a full breakdown of typography styles. ```html

Sanity: The Content Operating System

``` ## Color Tokens It's recommended to use TailwindCSS utility classes or CSS custom properties to use Sanity ID colors. But there may be scenarios where Tailwind or CSS is not available (e.g. Satori image rendering), in which case you can use the color token API: ```tsx import { primitiveColors, semanticColors } from "@sanity/sanity-id/colors" ``` ## Icons Sanity ID avoids inlining SVG icons since this often quickly leads to markup bloat, among other issues. Instead icons are loaded using SVG symbols, which allows for individually loading and strongly caching each icon while still letting them be styled via CSS. This is done using [Iconophor](https://github.com/msfragala/iconophor), a library for setting up SVG icon endpoints with support for transforming the SVG output. The Sanity website already has an Iconophor endpoint set up for Sanity Icons at `https://www.sanity.io/iconophor/sanity-icons//`. If you're project lives on the `www.sanity.io` domain, no need to set up an endpoint since you can instead use the existing one. If not, you can either set up an Iconophor endpoint or set up a proxy/rewrite to the Sanity website one. ## Components Every component is imported from its own subpath. Props marked required must be passed. Components also accepting native element props are noted as such. ### Avatar Stack A row of overlapping avatars for showing a group of people compactly. ```tsx import { AvatarStack } from "@sanity/sanity-id/components/avatar-stack" ``` #### Props | Prop | Type | Required | Default | Description | | --- | --- | --- | --- | --- | | `persons` | `Array<{ name?: string; image: string \| FunctionComponent> }>` | yes | — | List of persons to display as stacked avatars | | `className` | `string` | no | — | Additional CSS classes | | `size` | `"sm" \| "md"` | no | `"md"` | Size of each avatar | #### Usage ##### Small ```tsx import { AvatarStack } from "@sanity/sanity-id/components/avatar-stack" export default () => { const persons = [ { name: "Kevin Harwood", image: "https://cdn.sanity.io/images/3do82whm/next/30ff6e8265637f4efac13903d09284b6e350eda4-512x512.png" }, { name: "Saskia Bobinska", image: "https://cdn.sanity.io/images/3do82whm/next/20a113998dc15c76f6f7e31ce640524bdd6d5b5c-5184x3456.jpg" }, { name: "Bram Doppen", image: "https://cdn.sanity.io/images/3do82whm/next/1523a5ff4f2bc463580087d9b14946d9cea5208e-512x512.jpg" }, { name: "Elaine Sloboda", image: "https://cdn.sanity.io/images/3do82whm/next/cd1d1c5e029f7f271df66c5e04f628b752c478f4-400x400.jpg" }, { name: "Erin Allen", image: "https://cdn.sanity.io/images/3do82whm/next/b01c58c95c6ef9dff752e9a7919080ad64cc14da-978x960.png" }, { name: "Eppo Heemstra", image: "https://cdn.sanity.io/images/3do82whm/next/a5270d24093f2ffda0f9c1f647cbf6838e74fbe7-200x200.jpg" }, { name: "Zahra Dargahi", image: "https://cdn.sanity.io/images/3do82whm/next/86ecacf1b80e14b475b39ee7185982a213786fc3-400x400.jpg" }, { name: "Jamie Bradley", image: "https://cdn.sanity.io/images/3do82whm/next/90d4519bfffc348224d8a91f1de9351158394a4a-415x415.jpg" }, ] return (
) } ``` ##### Medium ```tsx import { AvatarStack } from "@sanity/sanity-id/components/avatar-stack" export default () => { const persons = [ { name: "Kevin Harwood", image: "https://cdn.sanity.io/images/3do82whm/next/30ff6e8265637f4efac13903d09284b6e350eda4-512x512.png" }, { name: "Saskia Bobinska", image: "https://cdn.sanity.io/images/3do82whm/next/20a113998dc15c76f6f7e31ce640524bdd6d5b5c-5184x3456.jpg" }, { name: "Bram Doppen", image: "https://cdn.sanity.io/images/3do82whm/next/1523a5ff4f2bc463580087d9b14946d9cea5208e-512x512.jpg" }, { name: "Elaine Sloboda", image: "https://cdn.sanity.io/images/3do82whm/next/cd1d1c5e029f7f271df66c5e04f628b752c478f4-400x400.jpg" }, { name: "Erin Allen", image: "https://cdn.sanity.io/images/3do82whm/next/b01c58c95c6ef9dff752e9a7919080ad64cc14da-978x960.png" }, { name: "Eppo Heemstra", image: "https://cdn.sanity.io/images/3do82whm/next/a5270d24093f2ffda0f9c1f647cbf6838e74fbe7-200x200.jpg" }, { name: "Zahra Dargahi", image: "https://cdn.sanity.io/images/3do82whm/next/86ecacf1b80e14b475b39ee7185982a213786fc3-400x400.jpg" }, { name: "Jamie Bradley", image: "https://cdn.sanity.io/images/3do82whm/next/90d4519bfffc348224d8a91f1de9351158394a4a-415x415.jpg" }, ] return (
) } ``` ### Badge A small inline label for status or metadata, optionally led by an icon. ```tsx import { Badge } from "@sanity/sanity-id/components/badge" ``` #### Props | Prop | Type | Required | Default | Description | | --- | --- | --- | --- | --- | | `children` | `ReactNode` | no | — | Content of the badge | | `className` | `string` | no | — | Additional CSS classes | | `icon` | `IconSymbol` | no | — | Icon displayed before the text | | `size` | `"sm" \| "md"` | no | `"md"` | Size of the badge | #### Usage ```tsx import { Badge } from "@sanity/sanity-id/components/badge" export default () => { return (
Badge with icon (medium) Badge (medium) Badge with icon (small) Badge (small)
) } ``` ### Breadcrumbs A navigation trail showing the current page's position in the site hierarchy. ```tsx import { Breadcrumbs } from "@sanity/sanity-id/components/breadcrumbs" ``` #### Props | Prop | Type | Required | Default | Description | | --- | --- | --- | --- | --- | | `label` | `string` | yes | — | Accessible label for the nav element | | `links` | `Array<{ title: string; href?: string; current?: boolean }>` | yes | — | Breadcrumb items to render | | `className` | `string` | no | — | Additional CSS classes | | `renderLink` | `ElementType & { href: string }>` | no | — | Custom link component for client-side navigation (e.g. Next.js Link) | #### Usage ```tsx import { Breadcrumbs } from "@sanity/sanity-id/components/breadcrumbs" export default () => { return (
) } ``` ### Button The primary call to action. Renders an `` when given an `href` and a ` ))} ))} ) } ``` ### Card A linkable content card combining an image, an eyebrow, and a title. The media area is reserved whether or not an `image` or `logo` is given, so cards in a row line their titles up even when only some of them have artwork. ```tsx import { Card } from "@sanity/sanity-id/components/card" ``` #### Props | Prop | Type | Required | Default | Description | | --- | --- | --- | --- | --- | | `title` | `string` | yes | — | Card title | | `arrow` | `"right" \| "top-right"` | no | — | **Deprecated.** Accepted but ignored. The arrow is derived from `href`: it appears only on a link that leaves the site, pointing top-right — Direction of the arrow indicator | | `className` | `string` | no | — | Additional CSS classes | | `description` | `string` | no | — | Supporting copy displayed below the title | | `eyebrow` | `string \| Array` | no | — | Small label displayed above the title. Several parts read as one bullet-separated line | | `href` | `string` | no | — | Makes the card a clickable link | | `image` | `CardMediaSource` | no | — | Image source URL, dark/light pair for theme-aware images, or a custom render function | | `logo` | `CardMediaSource` | no | — | Logo shown centered in the media area at its own aspect ratio, over `image` if there is one, which is then darkened | | `persons` | `Array` | no | — | People to credit, shown as a stack of avatars below the title | | `renderLink` | `ElementType & { href: string }>` | no | `"a"` | Custom link component for client-side navigation (e.g. Next.js Link) | | `sizes` | `string` | no | `"auto, (min-width: 1024px) 33vw, (min-width: 640px) 50vw, 100vw"` | How wide the image renders, for the browser to pick a srcset candidate against. Worth setting when the card is not in a one/two/three-column grid | | `tags` | `Array` | no | — | Tags shown below the title, each optionally linking somewhere of its own | `CardMediaSource`: `string | { dark: string; light: string } | ((props: ComponentProps<"img">) => ReactNode)` `CardPerson`: `{ name?: string; image: string | FunctionComponent> }` `CardTag`: `{ label: string; href?: string }` #### Usage ##### Image, eyebrow, and title ```tsx import { Card } from "@sanity/sanity-id/components/card" export default () => { return (
) } ``` ##### The arrow appears only on a link that leaves the site, and is not configurable ```tsx import { Card } from "@sanity/sanity-id/components/card" export default () => { return (
) } ``` ##### With a description ```tsx import { Card } from "@sanity/sanity-id/components/card" export default () => { return (
) } ``` ##### With a logo, centered in the same media area so mixed grids stay aligned. Given an image too, the logo sits over it and the image is darkened ```tsx import { Card } from "@sanity/sanity-id/components/card" export default () => { return (
) } ``` ##### The media area is reserved with no image or logo at all, so a grid of cards keeps its titles on one line ```tsx import { Card } from "@sanity/sanity-id/components/card" export default () => { return (
) } ``` ##### With tags and credited people. Tags and avatars sit outside the card's link, so a tag can link somewhere of its own. The first card's eyebrow is an array, joined into one bullet-separated line ```tsx import { Card } from "@sanity/sanity-id/components/card" export default () => { const persons = [ { name: "Kevin Harwood", image: "https://cdn.sanity.io/images/3do82whm/next/30ff6e8265637f4efac13903d09284b6e350eda4-512x512.png" }, { name: "Saskia Bobinska", image: "https://cdn.sanity.io/images/3do82whm/next/20a113998dc15c76f6f7e31ce640524bdd6d5b5c-5184x3456.jpg" }, { name: "Bram Doppen", image: "https://cdn.sanity.io/images/3do82whm/next/1523a5ff4f2bc463580087d9b14946d9cea5208e-512x512.jpg" }, ] return (
) } ``` ##### The footer shows whichever of avatars and tags is present — a card can have one without the other ```tsx import { Card } from "@sanity/sanity-id/components/card" export default () => { const persons = [ { name: "Kevin Harwood", image: "https://cdn.sanity.io/images/3do82whm/next/30ff6e8265637f4efac13903d09284b6e350eda4-512x512.png" }, { name: "Saskia Bobinska", image: "https://cdn.sanity.io/images/3do82whm/next/20a113998dc15c76f6f7e31ce640524bdd6d5b5c-5184x3456.jpg" }, ] return (
) } ``` ### Checkbox A single checkbox with an associated label and optional error message. ```tsx import { Checkbox } from "@sanity/sanity-id/components/checkbox" ``` #### Props | Prop | Type | Required | Default | Description | | --- | --- | --- | --- | --- | | `id` | `string` | yes | — | Unique input ID; connects the input to its label element | | `error` | `ReactNode` | no | — | Error message displayed below the checkbox | | `label` | `ReactNode` | no | — | Label displayed next to the checkbox | Also accepts every prop of `Omit, "type">`. #### Usage ```tsx import { Checkbox } from "@sanity/sanity-id/components/checkbox" export default () => { return (
) } ``` ### Chip A compact, optionally dismissible token — for filters, tags, and selections. ```tsx import { Chip } from "@sanity/sanity-id/components/chip" ``` #### Props | Prop | Type | Required | Default | Description | | --- | --- | --- | --- | --- | | `children` | `string` | no | — | Text content of the chip | | `className` | `string` | no | — | Additional CSS classes | | `deleteIcon` | `boolean` | no | `false` | Displays a delete/close button inside the chip | | `letterCase` | `"normal" \| "uppercase"` | no | `"normal"` | Text casing applied to the chip label | | `onDelete` | `(event: MouseEvent) => void` | no | — | Called when the delete button is clicked | | `size` | `"sm" \| "md"` | no | `"md"` | Size of the chip | | `state` | `"default" \| "active"` | no | `"default"` | Visual state of the chip | #### Usage ```tsx import { Chip } from "@sanity/sanity-id/components/chip" export default () => { return (
Chip (Medium) Chip (Medium) Chip (Medium) Chip (Medium) Chip (Medium) Chip (Medium) Chip (Medium) Chip (Medium) Chip (Small) Chip (Small) Chip (Small) Chip (Small) Chip (Small) Chip (Small) Chip (Small) Chip (Small)
) } ``` ### Code An inline code sample with syntax highlighting. ```tsx import { Code } from "@sanity/sanity-id/components/code" ``` #### Props | Prop | Type | Required | Default | Description | | --- | --- | --- | --- | --- | | `code` | `string` | yes | — | Source code to display | | `language` | `string` | yes | — | Language identifier for syntax highlighting | | `className` | `string` | no | — | Additional CSS classes | | `highlightLines` | `number[]` | no | — | Line numbers to highlight | | `showLineNumbers` | `boolean` | no | `true` | Shows the line number gutter for multi-line code | | `size` | `"sm" \| "md" \| "lg"` | no | `"md"` | Font size variant | #### Usage ```tsx import { Code } from "@sanity/sanity-id/components/code" export default () => { return (
', dataset: 'production', plugins: [structureTool()], schema: { types: [], }, }) `} /> ', dataset: 'production', plugins: [structureTool()], schema: { types: [], }, }) `} /> ', dataset: 'production', plugins: [structureTool()], schema: { types: [], }, }) `} />
) } ``` ### Code Block A tabbed code sample with syntax highlighting and optional line numbers. ```tsx import { CodeBlock } from "@sanity/sanity-id/components/code-block" ``` #### Props | Prop | Type | Required | Default | Description | | --- | --- | --- | --- | --- | | `tabs` | `Array` | yes | — | One or more code tabs to display | | `className` | `string` | no | — | Additional CSS classes | `CodeBlockTab`: `{ code: string; language: string; highlightLines?: number[]; showLineNumbers?: boolean; title?: string }` #### Usage ##### Single-line code with no title ```tsx import { CodeBlock } from "@sanity/sanity-id/components/code-block" export default () => { return ( ) } ``` ##### Single-line code with title ```tsx import { CodeBlock } from "@sanity/sanity-id/components/code-block" export default () => { return ( ) } ``` ##### Code with unsupported language ```tsx import { CodeBlock } from "@sanity/sanity-id/components/code-block" export default () => { return ( ) } ``` ##### Single-line code with multiple tabs ```tsx import { CodeBlock } from "@sanity/sanity-id/components/code-block" export default () => { return ( ) } ``` ##### Multiple-line code with no title ```tsx import { CodeBlock } from "@sanity/sanity-id/components/code-block" export default () => { return ( ', dataset: 'production', plugins: [structureTool()], schema: { types: schemaTypes, }, }) `, }, ]} /> ) } ``` ##### Multiple-line code with title ```tsx import { CodeBlock } from "@sanity/sanity-id/components/code-block" export default () => { return ( ', dataset: 'production', plugins: [structureTool()], schema: { types: schemaTypes, }, }) `, }, ]} /> ) } ``` ##### Multiple-line code with multiple tabs ```tsx import { CodeBlock } from "@sanity/sanity-id/components/code-block" export default () => { return ( ', dataset: 'production', plugins: [structureTool()], schema: { types: schemaTypes, }, }) `, }, { title: "schemas.ts", language: "typescript", code: ` import {defineType,defineField} from 'sanity' import {structureTool} from 'sanity/structure' import {schemaTypes} from './schemas' export default [ defineType({ name: "person", type: "object", fields: [ defineField({ name: "name", type: "string", }) ] }) ] `, }, ]} /> ) } ``` ### Disclosure A collapsible section built on `
`, animating between open and closed. ```tsx import { Disclosure } from "@sanity/sanity-id/components/disclosure" ``` #### Props | Prop | Type | Required | Default | Description | | --- | --- | --- | --- | --- | | `summary` | `string` | yes | — | Clickable summary text shown when the disclosure is collapsed | | `children` | `ReactNode` | no | — | Content shown when the disclosure is expanded | | `disableAnimations` | `boolean` | no | — | Disables animation when opening and closing the disclosure contents. Note animations only work in browsers that support interpolate-size | Also accepts every prop of `ComponentProps<"details">`. #### Usage ##### Example 1 ```tsx import { Disclosure } from "@sanity/sanity-id/components/disclosure" export default () => { return (

Occaecat dolor ipsum sint labore deserunt elit nulla duis anim ut sit fugiat eiusmod dolore Lorem. Dolore consectetur cillum commodo sint in velit magna duis nisi nisi fugiat dolor culpa. Veniam nostrud id deserunt nulla sit aliqua nostrud nostrud dolor elit voluptate veniam tempor. Veniam Lorem qui sunt. In laborum ea consequat nisi sunt anim labore consequat officia pariatur laborum ullamco voluptate labore sit. Magna do non enim reprehenderit laborum duis. Nulla voluptate cillum adipisicing. Amet voluptate fugiat et.

Enim veniam cillum aliquip culpa est cupidatat reprehenderit deserunt reprehenderit id esse esse. Laborum voluptate laboris amet proident. Officia cupidatat culpa deserunt excepteur sunt esse sit sit sit dolor labore ex ex ullamco Lorem. Ullamco culpa anim irure culpa irure proident do mollit sint deserunt. Deserunt et et incididunt veniam consequat sint voluptate quis ea commodo. Deserunt fugiat id dolor sit. Nulla incididunt nostrud anim consectetur consectetur non. Ad aliqua fugiat magna officia et.

Exercitation enim adipisicing minim sint. Excepteur reprehenderit excepteur consectetur nisi consectetur. Ullamco minim sint exercitation reprehenderit deserunt et eiusmod laborum laborum. Reprehenderit fugiat amet incididunt et eiusmod.

Nulla voluptate laboris aliqua. Adipisicing Lorem irure reprehenderit pariatur eiusmod do consequat do consequat aute. Pariatur officia culpa est ad pariatur velit velit. Consequat amet occaecat exercitation esse eu mollit amet esse fugiat deserunt. Nisi Lorem dolore amet labore duis commodo aute. Velit pariatur ut sit velit esse proident sunt nisi culpa occaecat.

Esse qui aliqua quis elit duis ut ullamco ullamco culpa laborum adipisicing consectetur excepteur dolor. Mollit quis aute deserunt. Id aliqua sit dolor elit eu laborum culpa. Officia mollit nulla anim ex culpa reprehenderit sit non et. Culpa exercitation eu in pariatur ullamco mollit pariatur amet. Qui aliqua est nostrud amet cillum. Amet enim duis commodo officia irure id adipisicing ullamco dolor labore. Pariatur adipisicing occaecat reprehenderit laborum incididunt nisi do consectetur mollit reprehenderit.

Fugiat eu ea dolor cillum irure fugiat labore adipisicing officia irure consectetur enim et. Dolore occaecat velit veniam ex labore ex ex est dolor sint. Officia enim aliqua ea cillum. Culpa laborum occaecat aute magna irure ad fugiat est culpa amet excepteur. Dolore Lorem ea ut aliqua reprehenderit deserunt nostrud excepteur aliquip ut sit. Magna magna veniam consectetur mollit mollit excepteur irure Lorem ad eu est ad dolore elit. Cillum anim et proident commodo sit laborum duis quis voluptate minim sunt in et officia. Anim excepteur magna sint id anim consequat non incididunt esse consectetur laborum esse pariatur est sunt.

Proident excepteur irure amet nulla nisi et esse quis. Excepteur do culpa laborum magna dolor Lorem proident cupidatat voluptate ad tempor. Veniam nostrud enim sint mollit sunt ex dolor dolor est ullamco. Duis laboris amet amet amet incididunt dolor esse pariatur exercitation. Amet nulla ad adipisicing cupidatat incididunt occaecat mollit in enim amet enim exercitation veniam adipisicing sint. Reprehenderit cillum minim aliqua aliqua amet cupidatat. Est excepteur culpa eiusmod.

Irure consequat et consectetur ullamco deserunt deserunt nostrud in. Excepteur non et sint nisi dolore. In sit voluptate enim dolor minim laborum sint ea aliqua consectetur excepteur tempor. Qui enim consequat aliqua et officia excepteur. Nulla do aute esse ullamco culpa mollit nostrud officia elit fugiat nostrud elit anim. Sunt nostrud incididunt ea esse adipisicing cupidatat pariatur duis eiusmod sunt anim do sit.

Id mollit officia deserunt minim qui consequat velit. Esse minim officia sunt ad amet laboris Lorem cillum proident duis laboris cillum. Ad ipsum nostrud nulla consequat occaecat laboris nisi fugiat magna do sit cillum. Officia id esse magna ex et ut sit qui ut. Cupidatat mollit cupidatat proident enim excepteur. Labore Lorem ullamco ea ut commodo elit qui. Officia nisi reprehenderit ut nulla enim commodo qui laborum. Occaecat cillum anim consequat elit non exercitation.

Aliquip proident sit fugiat nisi fugiat qui minim. Cillum ea enim consequat enim nulla quis pariatur. Incididunt proident tempor consectetur et cillum culpa consectetur amet excepteur magna duis ad amet laboris. Magna dolore anim eiusmod laborum laboris sint consectetur exercitation exercitation. Anim nulla sint nostrud quis sunt anim.

Eu proident aliquip non ullamco ut ullamco pariatur est in do duis nulla. Anim consequat aliqua amet velit ad ea exercitation consectetur dolor culpa magna sit in ipsum. Do irure aliqua irure eu proident minim deserunt mollit cupidatat velit. Laboris mollit duis ullamco ullamco nostrud ut officia et ad duis velit incididunt quis nostrud.

Incididunt fugiat do id consectetur aute commodo et eu. Ad ex ut nisi enim esse dolor. Officia sint culpa quis quis excepteur ad in. Cupidatat eu commodo reprehenderit culpa sit amet officia eiusmod reprehenderit ut cillum elit. Amet cillum reprehenderit esse do id cupidatat ex nulla dolor ex veniam labore adipisicing fugiat aliqua. Exercitation sint cillum quis dolor aute adipisicing.

Fugiat reprehenderit irure id Lorem do sint excepteur excepteur duis nulla eu tempor nisi commodo. Reprehenderit in sit pariatur officia. Labore excepteur minim laborum Lorem aliqua elit cupidatat anim aliqua id incididunt. Magna incididunt ut sunt velit adipisicing commodo nulla labore ipsum consectetur consequat proident qui fugiat nostrud. Mollit minim veniam cillum pariatur. Deserunt sunt voluptate enim proident consequat esse Lorem excepteur nulla voluptate sit minim occaecat quis consequat. Anim labore reprehenderit pariatur aute voluptate do esse elit ut.

Irure sit minim quis nostrud officia duis laboris cillum elit deserunt. Eu est anim ex. Nostrud tempor ex magna ad sit dolor. Ad ullamco cillum adipisicing in eu sint velit laboris eiusmod anim cillum aliqua consequat ex. Mollit eiusmod cillum dolor elit sit fugiat sint occaecat officia tempor anim. Minim cupidatat duis incididunt sint commodo mollit aliqua ipsum. Veniam esse occaecat qui elit laborum veniam culpa exercitation in laborum fugiat culpa anim.

) } ``` ##### Disabling opening/closing animations ```tsx import { Disclosure } from "@sanity/sanity-id/components/disclosure" export default () => { return (

Occaecat dolor ipsum sint labore deserunt elit nulla duis anim ut sit fugiat eiusmod dolore Lorem. Dolore consectetur cillum commodo sint in velit magna duis nisi nisi fugiat dolor culpa. Veniam nostrud id deserunt nulla sit aliqua nostrud nostrud dolor elit voluptate veniam tempor. Veniam Lorem qui sunt. In laborum ea consequat nisi sunt anim labore consequat officia pariatur laborum ullamco voluptate labore sit. Magna do non enim reprehenderit laborum duis. Nulla voluptate cillum adipisicing. Amet voluptate fugiat et.

) } ``` ### Eyebrow A small label sitting above a heading, optionally paired with a call to action. ```tsx import { Eyebrow } from "@sanity/sanity-id/components/eyebrow" ``` #### Props | Prop | Type | Required | Default | Description | | --- | --- | --- | --- | --- | | `children` | `ReactNode` | no | — | Label text content | | `className` | `string` | no | — | Additional CSS classes | | `cta` | `{ as?: E; text: string; href?: string; arrow?: LinkCTAProps["arrow"] }` | no | — | Optional CTA link rendered alongside the label | #### Usage ```tsx import { Eyebrow } from "@sanity/sanity-id/components/eyebrow" export default () => { return (
Eyebrow Eyebrow
) } ``` ### Icon Button A square button containing only an icon. Requires `label` for accessibility. Renders an `
` when given an `href` and a `