{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "typeset-story",
  "title": "Typeset Story",
  "author": "Lloyd Richards <lloyd.d.richards@gmail.com>",
  "description": "Storybook-only documentation for shadcn Typeset; bundled CSS supports the story, while applications generate and own their CSS",
  "registryDependencies": [
    "button"
  ],
  "files": [
    {
      "path": "registry/tokens/typeset-story/typeset-radix.stories.tsx",
      "content": "import type { Meta, StoryObj } from \"@storybook/nextjs-vite\";\nimport { useEffect, useState } from \"react\";\nimport { expect, userEvent, waitFor } from \"storybook/test\";\n\nimport { Button } from \"@/components/ui/button\";\n\nimport \"./typeset.css\";\n\n/**\n * Applies shadcn Typeset rhythm to semantic HTML and rendered Markdown.\n *\n * This registry adopts Typeset as paired Base UI and Radix UI Storybook\n * stories. The bundled `typeset.css` supports these stories and is not a\n * standalone application distribution. Applications should generate and own\n * their CSS with the [shadcn Typeset builder](https://ui.shadcn.com/typeset),\n * then import it after Tailwind.\n *\n * Typeset inherits theme colors, fonts, and radius. Use `--typeset-size`,\n * `--typeset-leading`, and `--typeset-flow` to control its rhythm; the\n * surrounding layout owns its measure.\n */\nconst meta = {\n  title: \"design/radix/Typeset\",\n  tags: [\"autodocs\"],\n  parameters: {\n    layout: \"centered\",\n  },\n  decorators: (Story) => (\n    <div className=\"w-full min-w-sm max-w-2xl px-6\">\n      <Story />\n    </div>\n  ),\n} satisfies Meta;\n\nexport default meta;\n\ntype Story = StoryObj<typeof meta>;\n\nconst getPresentation = (element: HTMLElement) => {\n  const style = window.getComputedStyle(element);\n  const bounds = element.getBoundingClientRect();\n\n  return {\n    backgroundColor: style.backgroundColor,\n    borderBlockEnd: style.borderBlockEnd,\n    borderBlockStart: style.borderBlockStart,\n    color: style.color,\n    fontFamily: style.fontFamily,\n    fontSize: style.fontSize,\n    fontWeight: style.fontWeight,\n    height: bounds.height,\n    letterSpacing: style.letterSpacing,\n    lineHeight: style.lineHeight,\n    marginBlockEnd: style.marginBlockEnd,\n    marginBlockStart: style.marginBlockStart,\n    paddingBlockEnd: style.paddingBlockEnd,\n    paddingBlockStart: style.paddingBlockStart,\n    width: bounds.width,\n  };\n};\n\n/**\n * Shows headings, lists, quotes, code, and tables under one reading rhythm.\n * This complements the Typography stories, which document raw tokens.\n */\nexport const Documentation: Story = {\n  render: () => (\n    <article className=\"typeset typeset-docs\">\n      <h1>Build a registry people can trust</h1>\n      <p>\n        A useful registry shows how components behave, explains their purpose,\n        and keeps the installed source easy to own.\n      </p>\n      <h2>Review the important states</h2>\n      <p>\n        Start with the common path, then include the boundaries a consumer is\n        likely to encounter.\n      </p>\n      <ul>\n        <li>Use semantic HTML for meaningful structure.</li>\n        <li>Keep examples small enough to understand at a glance.</li>\n        <li>\n          Verify interactive states with focused <code>play</code> tests.\n        </li>\n      </ul>\n      <blockquote>\n        <p>A story is documentation that can prove its own behavior.</p>\n      </blockquote>\n      <pre>\n        <code>{`bun run test:storybook\\nbun run registry:build`}</code>\n      </pre>\n      <table>\n        <thead>\n          <tr>\n            <th>Surface</th>\n            <th>Purpose</th>\n          </tr>\n        </thead>\n        <tbody>\n          <tr>\n            <td>Typography</td>\n            <td>Raw design tokens</td>\n          </tr>\n          <tr>\n            <td>Typeset</td>\n            <td>Rendered content rhythm</td>\n          </tr>\n        </tbody>\n      </table>\n    </article>\n  ),\n};\n\n/** Keep wide semantic tables readable with an opt-in horizontal scroller. */\nexport const ResponsiveTable: Story = {\n  render: () => (\n    <article className=\"typeset typeset-docs\">\n      <h2>Release compatibility</h2>\n      <p>\n        Wrap a wide table in <code>typeset-scroll</code> when preserving every\n        column is more useful than allowing the cells to compress.\n      </p>\n      <div className=\"typeset-scroll max-w-lg\" data-testid=\"table-scroller\">\n        <table>\n          <thead>\n            <tr>\n              <th>Release</th>\n              <th>React</th>\n              <th>Tailwind</th>\n              <th>Storybook</th>\n              <th>Browser tests</th>\n              <th>Registry format</th>\n            </tr>\n          </thead>\n          <tbody>\n            <tr>\n              <td>Current</td>\n              <td>19.2</td>\n              <td>4.3</td>\n              <td>10.4</td>\n              <td>Playwright</td>\n              <td>v3 JSON</td>\n            </tr>\n          </tbody>\n        </table>\n      </div>\n    </article>\n  ),\n  play: async ({ canvas }) => {\n    const scroller = canvas.getByTestId(\"table-scroller\");\n    await expect(scroller.scrollWidth).toBeGreaterThan(scroller.clientWidth);\n    await expect(canvas.getByRole(\"table\")).toBeVisible();\n  },\n};\n\nfunction ChatExample() {\n  const [continued, setContinued] = useState(false);\n\n  return (\n    <div className=\"w-full rounded-xl border bg-muted/30 p-4\">\n      <div className=\"typeset typeset-chat\" data-testid=\"chat-content\">\n        <p data-testid=\"existing-block\">\n          Typeset uses forward-only spacing so streamed content can be appended\n          without changing blocks already on screen.\n        </p>\n        {continued ? (\n          <p>\n            This paragraph arrived later, while the first paragraph kept the\n            same computed presentation.\n          </p>\n        ) : null}\n      </div>\n      <Button\n        variant=\"outline\"\n        size=\"sm\"\n        className=\"mt-4\"\n        disabled={continued}\n        onClick={() => setContinued(true)}\n      >\n        {continued ? \"Response continued\" : \"Continue response\"}\n      </Button>\n    </div>\n  );\n}\n\n/** Manually append another response block to the conversation. */\nexport const Chat: Story = {\n  render: () => <ChatExample />,\n};\n\nconst streamedResponse =\n  \"New text arrives a few characters at a time while the completed paragraph above stays visually stable.\";\n\nfunction StreamingText({\n  intervalMs = 35,\n  startDelay = 400,\n}: {\n  intervalMs?: number;\n  startDelay?: number;\n}) {\n  const [length, setLength] = useState(0);\n\n  useEffect(() => {\n    let interval: number | undefined;\n    const start = window.setTimeout(() => {\n      interval = window.setInterval(() => {\n        setLength((current) => {\n          if (current >= streamedResponse.length) {\n            window.clearInterval(interval);\n            return current;\n          }\n\n          return current + 1;\n        });\n      }, intervalMs);\n    }, startDelay);\n\n    return () => {\n      window.clearTimeout(start);\n      window.clearInterval(interval);\n    };\n  }, [intervalMs, startDelay]);\n\n  return (\n    <p>\n      <span aria-hidden=\"true\" data-testid=\"streamed-text\">\n        {streamedResponse.slice(0, length)}\n        {length < streamedResponse.length ? (\n          <span className=\"animate-pulse\">▍</span>\n        ) : null}\n      </span>\n      <span className=\"sr-only\" aria-live=\"polite\">\n        {length < streamedResponse.length\n          ? \"Response is streaming\"\n          : streamedResponse}\n      </span>\n    </p>\n  );\n}\n\nfunction StreamingExample({\n  intervalMs,\n  startDelay,\n}: {\n  intervalMs?: number;\n  startDelay?: number;\n}) {\n  const [run, setRun] = useState(0);\n\n  return (\n    <div className=\"w-full rounded-xl border bg-muted/30 p-4\">\n      <div className=\"typeset typeset-chat\">\n        <p>\n          Typeset keeps completed blocks stable while a response is still\n          arriving.\n        </p>\n        <StreamingText\n          key={run}\n          intervalMs={intervalMs}\n          startDelay={startDelay}\n        />\n      </div>\n      <Button\n        variant=\"outline\"\n        size=\"sm\"\n        className=\"mt-4\"\n        onClick={() => setRun((current) => current + 1)}\n      >\n        Replay stream\n      </Button>\n    </div>\n  );\n}\n\n/** Preview a response arriving over time with story-only timing. */\nexport const Streaming: Story = {\n  render: () => <StreamingExample />,\n};\n\n/** Verify appending a response does not restyle completed content. */\nexport const ShouldPreserveExistingContentWhenAppendingResponse: Story = {\n  name: \"should preserve existing chat content when appending a response\",\n  tags: [\"!dev\", \"!autodocs\"],\n  render: () => <ChatExample />,\n  play: async ({ canvas }) => {\n    const existingBlock = canvas.getByTestId(\"existing-block\");\n    const presentation = getPresentation(existingBlock);\n\n    await userEvent.click(\n      canvas.getByRole(\"button\", { name: \"Continue response\" }),\n    );\n    await canvas.findByText(/This paragraph arrived later/);\n\n    await expect(getPresentation(existingBlock)).toEqual(presentation);\n  },\n};\n\n/** Verify timed content completes and restarts when replayed. */\nexport const ShouldRestartStreamingWhenReplayed: Story = {\n  name: \"should restart streaming when replayed\",\n  tags: [\"!dev\", \"!autodocs\"],\n  render: () => <StreamingExample intervalMs={1} startDelay={50} />,\n  play: async ({ canvas }) => {\n    const streamedText = canvas.getByTestId(\"streamed-text\");\n\n    await waitFor(\n      () => expect(streamedText).toHaveTextContent(streamedResponse),\n      { timeout: 2_000 },\n    );\n    await userEvent.click(\n      canvas.getByRole(\"button\", { name: \"Replay stream\" }),\n    );\n    const replayedText = canvas.getByTestId(\"streamed-text\");\n    await waitFor(() => expect(replayedText).toHaveTextContent(\"▍\"));\n    await waitFor(\n      () => expect(replayedText).toHaveTextContent(streamedResponse),\n      { timeout: 2_000 },\n    );\n  },\n};\n\n/** Opt a component subtree out with a class or data attribute. */\nexport const EscapeHatch: Story = {\n  render: () => (\n    <article className=\"typeset typeset-docs\">\n      <h2>Mix prose with application UI</h2>\n      <p>Typeset styles this paragraph as part of the surrounding document.</p>\n      <div className=\"not-typeset mt-6 rounded-lg border bg-muted p-4\">\n        <p className=\"font-medium text-sm\">Class-based opt-out</p>\n        <p className=\"mt-1 text-muted-foreground text-sm\">\n          This entire subtree keeps its component-owned spacing and typography.\n        </p>\n      </div>\n      <div data-not-typeset className=\"mt-4 rounded-lg border bg-muted p-4\">\n        <p className=\"font-medium text-sm\">Attribute-based opt-out</p>\n        <div className=\"typeset mt-1 text-muted-foreground text-sm\">\n          A nested typeset container stays opted out with the rest of this\n          subtree.\n        </div>\n      </div>\n    </article>\n  ),\n};\n",
      "type": "registry:component",
      "target": "@ui/typeset.stories.tsx"
    },
    {
      "path": "registry/tokens/typeset-story/typeset.css",
      "content": "/*\n * shadcn/typeset\n * https://ui.shadcn.com/docs/typeset\n */\n\n@layer components {\n  .typeset {\n    --typeset-font-body: inherit;\n    --typeset-font-heading: var(--font-heading);\n    --typeset-font-mono: var(--font-mono);\n    --typeset-size: 1em;\n    --typeset-leading: 1.75;\n    --typeset-flow: 1.25em;\n  }\n}\n\n/* Presets used by the stories. Consumers can tune these three rhythm controls\n * for their own content after copying Typeset into their application. */\n.typeset-docs {\n  --typeset-size: 15px;\n  --typeset-leading: 1.75;\n  --typeset-flow: 1.5em;\n}\n\n.typeset-chat {\n  --typeset-leading: 1.6;\n  --typeset-flow: 1em;\n}\n\n@layer components {\n  .typeset {\n    font-family: var(--typeset-font-body);\n    font-size: calc(var(--typeset-size) * 1.125);\n    line-height: var(--typeset-leading);\n    color: var(--color-foreground, currentColor);\n    overflow-wrap: break-word;\n    margin-trim: block-start;\n\n    @media (min-width: 48rem), print {\n      font-size: var(--typeset-size);\n    }\n\n    --typeset-muted: var(\n      --color-muted-foreground,\n      color-mix(in oklab, currentColor 60%, transparent)\n    );\n    --typeset-rule: var(\n      --color-border,\n      color-mix(in oklab, currentColor 20%, transparent)\n    );\n  }\n\n  .typeset\n    *:not(\n      :where(\n        .not-typeset,\n        [data-not-typeset],\n        .not-typeset *,\n        [data-not-typeset] *\n      )\n    ) {\n    /* Paragraphs. */\n    &:where(p) {\n      margin-block-start: var(--typeset-flow);\n      margin-block-end: 0;\n    }\n\n    /* Headings. */\n    &:where(h1, h2, h3, h4, h5, h6) {\n      color: var(--color-foreground, currentColor);\n      font-family: var(--typeset-font-heading);\n      font-weight: 600;\n      margin-block-end: 0;\n    }\n    &:where(h1) {\n      font-size: 1.75em;\n      line-height: 1.3;\n      margin-block-start: var(--typeset-flow);\n    }\n    &:where(h2) {\n      font-size: 1.25em;\n      line-height: 1.4;\n      margin-block-start: calc(var(--typeset-flow) * 1.4);\n    }\n    &:where(h3) {\n      font-size: 1.125em;\n      line-height: 1.45;\n      margin-block-start: var(--typeset-flow);\n    }\n    &:where(h4) {\n      font-size: 1em;\n      line-height: 1.5;\n      margin-block-start: var(--typeset-flow);\n    }\n    &:where(h5) {\n      font-size: 0.875em;\n      line-height: 1.5;\n      font-weight: 500;\n      color: var(--typeset-muted);\n      margin-block-start: calc(var(--typeset-flow) / 0.875);\n    }\n    &:where(h6) {\n      font-size: 0.8125em;\n      line-height: 1.5;\n      font-weight: 500;\n      letter-spacing: 0.08em;\n      text-transform: uppercase;\n      color: var(--typeset-muted);\n      margin-block-start: calc(var(--typeset-flow) / 0.8125);\n    }\n    /* Anchors. */\n    &:where([id]) {\n      scroll-margin-block-start: var(--typeset-flow);\n    }\n\n    /* Headings own the space below them. */\n    &:where(h1 + *, h2 + *, h3 + *, h4 + *, h5 + *, h6 + *) {\n      margin-block-start: 1em;\n    }\n    &:where(:is(h1, h2, h3, h4) :is(code)) {\n      font-size: 0.9em;\n    }\n\n    /* Links. */\n    &:where(a) {\n      color: inherit;\n      font-weight: 500;\n      text-decoration-line: underline;\n      text-decoration-color: color-mix(in oklab, currentColor 30%, transparent);\n    }\n    &:where(a:hover) {\n      text-decoration-color: currentColor;\n    }\n    &:where(a:focus-visible) {\n      outline: 2px solid var(--color-ring, currentColor);\n      outline-offset: 2px;\n      border-radius: 0.125em;\n    }\n    &:where(:is(h1, h2, h3, h4, h5, h6) :is(a)) {\n      font-weight: inherit;\n    }\n\n    /* Inline semantics. */\n    &:where(strong, b) {\n      font-weight: 600;\n    }\n    &:where(:is(h1, h2, h3, h4) :is(strong, b)) {\n      font-weight: 600;\n    }\n    &:where(mark) {\n      background-color: color-mix(\n        in oklab,\n        oklch(0.86 0.17 95) 40%,\n        transparent\n      );\n      color: inherit;\n      padding: 0.05em 0.15em;\n      border-radius: 0.2em;\n    }\n    &:where(abbr[title]) {\n      text-decoration-line: underline;\n      text-decoration-style: dotted;\n      text-underline-offset: 0.2em;\n      cursor: help;\n    }\n    &:where(del, s) {\n      color: var(--typeset-muted);\n      text-decoration-line: line-through;\n    }\n    &:where(sup, sub) {\n      font-size: 0.75em;\n      line-height: 0;\n      position: relative;\n      vertical-align: baseline;\n    }\n    &:where(sup) {\n      top: -0.5em;\n    }\n    &:where(sub) {\n      bottom: -0.25em;\n    }\n    &:where(sup a) {\n      text-decoration-line: none;\n      font-weight: 500;\n    }\n\n    /* Lists. */\n    &:where(ul) {\n      list-style-type: disc;\n    }\n    &:where(ol) {\n      list-style-type: decimal;\n    }\n    &:where(ul ul) {\n      list-style-type: circle;\n    }\n    &:where(ul ul ul) {\n      list-style-type: square;\n    }\n    &:where(ol[type=\"a\" i]) {\n      list-style-type: lower-alpha;\n    }\n    &:where(ol[type=\"i\" i]) {\n      list-style-type: lower-roman;\n    }\n    &:where(ol[type=\"A\" s]) {\n      list-style-type: upper-alpha;\n    }\n    &:where(ol[type=\"I\" s]) {\n      list-style-type: upper-roman;\n    }\n    &:where(ul, ol) {\n      margin-block-start: var(--typeset-flow);\n      margin-block-end: 0;\n      padding-inline-start: 1.5em;\n    }\n    &:where(li) {\n      margin-block-start: 0.5em;\n      padding-inline-start: 0.4em;\n    }\n    &:where(li > p, li > ul, li > ol) {\n      margin-block-start: 0.5em;\n    }\n    &:where(ul > li)::marker {\n      color: var(--typeset-muted);\n    }\n    &:where(ol > li)::marker {\n      color: var(--typeset-muted);\n    }\n\n    /* GFM task lists. */\n    &:where(ul.contains-task-list) {\n      list-style-type: none;\n      padding-inline-start: 0.25em;\n    }\n    &:where(li.task-list-item > input[type=\"checkbox\"]) {\n      margin-inline-end: 0.5em;\n      vertical-align: -0.1em;\n      accent-color: var(--color-primary, currentColor);\n    }\n\n    /* Disclosures. */\n    &:where(details) {\n      margin-block-start: var(--typeset-flow);\n      margin-block-end: 0;\n    }\n    &:where(summary) {\n      cursor: pointer;\n      font-weight: 500;\n    }\n    &:where(summary)::marker {\n      color: var(--typeset-muted);\n    }\n\n    /* Keyboard keys. */\n    &:where(kbd) {\n      font-family: inherit;\n      font-size: 0.85em;\n      font-weight: 500;\n      border: 1px solid var(--typeset-rule);\n      border-block-end-width: 2px;\n      border-radius: min(calc(var(--radius, 0.5em) * 0.6), 0.35em);\n      padding: 0.0625em 0.35em;\n    }\n\n    /* Definition lists. */\n    &:where(dl) {\n      margin-block-start: var(--typeset-flow);\n      margin-block-end: 0;\n    }\n    &:where(dt) {\n      font-weight: 500;\n      margin-block-start: 1em;\n    }\n    &:where(dt + dt) {\n      margin-block-start: 0.25em;\n    }\n    &:where(dd) {\n      margin-block-start: 0.25em;\n      margin-inline-start: 0;\n      padding-inline-start: 1em;\n      color: var(--typeset-muted);\n    }\n\n    /* Inline code. */\n    &:where(:not(pre) > code) {\n      background-color: var(\n        --color-muted,\n        color-mix(in oklab, currentColor 8%, transparent)\n      );\n      font-family: var(--typeset-font-mono);\n      font-size: 0.85em;\n      border-radius: min(calc(var(--radius, 0.5em) * 0.6), 0.35em);\n      padding: 0.125em 0.3em;\n    }\n\n    /* Code blocks. */\n    &:where(pre) {\n      background-color: var(\n        --color-muted,\n        color-mix(in oklab, currentColor 8%, transparent)\n      );\n      font-family: var(--typeset-font-mono);\n      font-size: 0.875em;\n      line-height: 1.5;\n      tab-size: 2;\n      direction: ltr;\n      border-radius: var(--radius, 0.5em);\n      padding: 0.75em 1em;\n      overflow-x: auto;\n      margin-block-start: calc(var(--typeset-flow) / 0.875);\n      margin-block-end: 0;\n    }\n    &:where(pre code) {\n      background-color: transparent;\n      font-family: inherit;\n      font-size: inherit;\n      padding: 0;\n      border-radius: 0;\n    }\n\n    /* Blockquote. */\n    &:where(blockquote) {\n      border-inline-start: 2px solid var(--typeset-rule);\n      padding-inline-start: 1em;\n      margin-block-start: var(--typeset-flow);\n      margin-block-end: 0;\n      margin-inline: 0;\n    }\n\n    /* Dividers. */\n    &:where(hr) {\n      border: 0;\n      border-block-start: 1px solid var(--typeset-rule);\n      margin-block-start: calc(var(--typeset-flow) * 2.4);\n      margin-block-end: 0;\n    }\n    &:where(hr + h1, hr + h2, hr + h3, hr + h4) {\n      margin-block-start: var(--typeset-flow);\n    }\n\n    /* GFM footnotes. */\n    &:where(.footnotes, [data-footnotes]) {\n      margin-block-start: calc(var(--typeset-flow) * 2);\n      border-block-start: 1px solid var(--typeset-rule);\n      padding-block-start: var(--typeset-flow);\n      font-size: 0.875em;\n      color: var(--typeset-muted);\n    }\n\n    /* Math. */\n    &:where(math[display=\"block\"]) {\n      margin-block-start: var(--typeset-flow);\n      margin-block-end: 0;\n      overflow-x: auto;\n      overflow-y: hidden;\n      padding-block: 0.25em;\n    }\n\n    /* Media. */\n    &:where(img, video) {\n      border-radius: var(--radius, 0.5em);\n      max-width: 100%;\n      height: auto;\n      margin-block-start: var(--typeset-flow);\n      margin-block-end: 0;\n    }\n    &:where(p img) {\n      margin-block-start: 0;\n    }\n    &:where(figure) {\n      margin-block-start: var(--typeset-flow);\n      margin-block-end: 0;\n      margin-inline: 0;\n    }\n    &:where(figcaption, caption) {\n      color: var(--typeset-muted);\n      font-size: 0.875em;\n      text-align: center;\n      margin-block-start: calc(0.75em / 0.875);\n    }\n    &:where(caption) {\n      caption-side: bottom;\n    }\n\n    /* Tables. Separators sit on cells, not tr:last-child: append-safe.\n       Bare tables stay real tables (keep their semantics) and wrap to fit. */\n    &:where(table) {\n      max-width: 100%;\n      font-size: 1em;\n      line-height: 1.5;\n      font-variant-numeric: tabular-nums;\n      border-collapse: separate;\n      border-spacing: 0;\n      border-block-end: 1px solid var(--typeset-rule);\n      margin-block-start: var(--typeset-flow);\n      margin-block-end: 0;\n    }\n\n    /* Horizontal scroll for any wide block. Wrap it and the wrapper owns the\n       flow margin. Tables shrink to fit, so widen the table to make it scroll\n       instead of compress. */\n    &:where(.typeset-scroll) {\n      overflow-x: auto;\n      margin-block-start: var(--typeset-flow);\n    }\n    &:where(.typeset-scroll > *) {\n      margin-block-start: 0;\n    }\n    &:where(.typeset-scroll table) {\n      width: max-content;\n      max-width: none;\n    }\n    &:where(thead th) {\n      font-weight: 500;\n      text-align: start;\n      white-space: nowrap;\n      padding: 0.65em 1em;\n    }\n    &:where(:is(tbody, tfoot) :is(td, th)) {\n      padding: 0.75em 1em;\n      text-align: start;\n      vertical-align: top;\n      border-block-start: 1px solid var(--typeset-rule);\n    }\n    &:where(tbody th, tfoot th) {\n      font-weight: 500;\n    }\n    &:where(th:first-child, td:first-child) {\n      padding-inline-start: 0;\n    }\n    &:where(th[align=\"center\"], td[align=\"center\"]) {\n      text-align: center;\n    }\n    &:where(th[align=\"right\"], td[align=\"right\"]) {\n      text-align: end;\n    }\n\n    /* Blocks inside list items keep the list's tighter rhythm. */\n    &:where(li > blockquote, li > table, li > figure) {\n      margin-block-start: 0.5em;\n    }\n    &:where(li > pre) {\n      margin-block-start: calc(0.5em / 0.875);\n    }\n\n    @media print {\n      &:where(pre, table, blockquote, figure) {\n        break-inside: avoid;\n      }\n      &:where(h1, h2, h3, h4) {\n        break-after: avoid;\n      }\n    }\n\n    /* Forced colors strips the code background, so give it a border. */\n    @media (forced-colors: active) {\n      &:where(:not(pre) > code) {\n        border: 1px solid;\n      }\n    }\n  }\n\n  /* First child adds no space above. Last so it wins ties. */\n  .typeset\n  > :where(:first-child):not(\n    :where(\n      .not-typeset,\n      [data-not-typeset],\n      .not-typeset *,\n      [data-not-typeset] *\n    )\n  ),\n  .typeset\n    > :where(:first-child)\n    > :where(:first-child):not(\n      :where(\n        .not-typeset,\n        [data-not-typeset],\n        .not-typeset *,\n        [data-not-typeset] *\n      )\n    ),\n  .typeset\n    :where(\n      li > :first-child,\n      blockquote > :first-child,\n      td > :first-child,\n      th > :first-child,\n      dd > :first-child,\n      figure > :first-child,\n      figure > picture > img\n    ):not(\n      :where(\n        .not-typeset,\n        [data-not-typeset],\n        .not-typeset *,\n        [data-not-typeset] *\n      )\n    ) {\n    margin-block-start: 0;\n  }\n}\n",
      "type": "registry:file",
      "target": "@ui/typeset.css"
    }
  ],
  "categories": [
    "design",
    "storybook",
    "typography",
    "markdown"
  ],
  "type": "registry:component"
}