@vegastack/design 0.8.11 → 0.8.12

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.
@@ -91,6 +91,35 @@ var prose = {
91
91
  img: "[&_img]:my-2 [&_img]:max-w-full [&_img]:rounded-lg [&_img]:border [&_img]:border-border"
92
92
  };
93
93
  var proseClassName = Object.values(prose).join(" ");
94
+ var proseDocument = {
95
+ /** Body: 14/24 on a fine pointer, 16/26 on a coarse pointer or below the `sm` width. */
96
+ root: "text-sm/6 pointer-coarse:text-base/6.5 max-sm:text-base/6.5",
97
+ // Headings: semibold (the base recipe's weight), more room above than below. The first block
98
+ // keeps `first:mt-0` from the base recipe. `scroll-mt-18` clears a 56px sticky header + 16.
99
+ h1: "[&_h1]:mt-8 [&_h1]:mb-3 [&_h1]:scroll-mt-18 [&_h1]:text-2xl/8",
100
+ h2: "[&_h2]:mt-7 [&_h2]:mb-2 [&_h2]:scroll-mt-18 [&_h2]:text-xl/7",
101
+ h3: "[&_h3]:mt-6 [&_h3]:mb-1.5 [&_h3]:scroll-mt-18 [&_h3]:text-base/6 pointer-coarse:[&_h3]:text-lg/7 max-sm:[&_h3]:text-lg/7",
102
+ h4: "[&_h4]:mt-5 [&_h4]:mb-1 [&_h4]:scroll-mt-18 [&_h4]:text-sm/6 [&_h4]:font-semibold pointer-coarse:[&_h4]:text-base/6.5 max-sm:[&_h4]:text-base/6.5",
103
+ // A 12px gap between paragraphs; none before the first or after the last.
104
+ p: "[&_p]:my-3",
105
+ // Lists indent 24, items 4 apart, a nested list 4 below its item's text.
106
+ ul: "[&_ul]:my-3 [&_ul]:ms-6",
107
+ ol: "[&_ol]:my-3 [&_ol]:ms-6",
108
+ li: "[&_li_ul]:mt-1 [&_li_ul]:mb-0 [&_li_ol]:mt-1 [&_li_ol]:mb-0",
109
+ // A quote is a rule and an indent, never italic; blocks breathe 16 apart.
110
+ blockquote: "[&_blockquote]:my-4 [&_blockquote]:ps-4",
111
+ // No orange in documents: inline code is a grey chip in the body's own ink.
112
+ code: "[&_code]:text-foreground",
113
+ pre: "[&_pre:not([data-slot='code-block-pre'])]:my-4",
114
+ hr: "[&_hr]:my-6",
115
+ img: "[&_img]:my-4",
116
+ // Tables read at 14/20 at every pointer, 16 from the blocks around them (the scroll box is the
117
+ // consumer's: `MarkdownView`'s `markdown-table`, the editor's `.tableWrapper`).
118
+ table: "[&_th]:text-sm/5 [&_td]:text-sm/5 [&_[data-slot=markdown-table]]:my-4 [&_.tableWrapper]:my-4",
119
+ // Callouts, toggles, code blocks and media sit 16 from their neighbours; a toggle's summary is
120
+ // a 24px row, 44px on a coarse pointer.
121
+ blocks: "[&_[data-slot=callout]]:my-4 [&_[data-slot=code-block]]:my-4 [&_details]:my-4 [&_video]:my-4 [&_audio]:my-4 [&_summary]:min-h-6 pointer-coarse:[&_summary]:min-h-11"
122
+ };
94
123
 
95
124
  // src/index.ts
96
125
  var twMerge = tailwindMerge;
@@ -132,6 +161,10 @@ var FLOATING = {
132
161
  sideOffsetDetached: 8,
133
162
  collisionPadding: 8
134
163
  };
164
+ var proseDocumentClassName = cn(
165
+ proseClassName,
166
+ Object.values(proseDocument).join(" ")
167
+ );
135
168
  function mergeRefs(...refs) {
136
169
  return (node) => {
137
170
  const cleanups = refs.map((ref) => {
@@ -166,8 +199,10 @@ function mergeRefs(...refs) {
166
199
  export {
167
200
  prose,
168
201
  proseClassName,
202
+ proseDocument,
169
203
  cn,
170
204
  TIMINGS,
171
205
  FLOATING,
206
+ proseDocumentClassName,
172
207
  mergeRefs
173
208
  };
@@ -41,10 +41,135 @@ var import_react = require("motion/react");
41
41
  // src/index.ts
42
42
  var import_clsx = require("clsx");
43
43
  var import_tailwind_merge = require("tailwind-merge");
44
+
45
+ // src/prose.ts
46
+ var prose = {
47
+ /**
48
+ * The root's own FAMILY, ink and size — every rule below is relative to this.
49
+ *
50
+ * `font-sans` is load-bearing and was missing. A prose root has to be self-describing, because
51
+ * neither of its two consumers sets a family of its own: `MarkdownView` and `TextEdit` both wear
52
+ * nothing but `proseClassName`. With no family declared here, prose inherited whatever surrounded
53
+ * it — drop either surface inside a mono container (`terminal-body` is one in this very
54
+ * registry, and a chat or log panel is the obvious consumer case) and the WHOLE tree went mono:
55
+ * headings, paragraphs, table cells, and the `1.` / `2.` markers of an ordered list, because
56
+ * `::marker` inherits font properties from its originating element.
57
+ *
58
+ * Geist Mono is now the exception the recipe names explicitly — `code`, `pre` and `pre code` —
59
+ * rather than something prose falls into by accident. A consumer who genuinely wants mono prose
60
+ * still says so on the root, where it reads as a decision.
61
+ *
62
+ * `min-w-0 wrap-anywhere` is the no-horizontal-overflow contract (2026-09-26): a long word, URL
63
+ * or inline code run breaks inside the line instead of widening the page, and `anywhere` (not
64
+ * `break-word`) also lowers the min-content width, so a prose root inside a flex item shrinks.
65
+ * Fenced code (`white-space: pre`) and tables keep their lines and scroll inside their own box.
66
+ */
67
+ root: "font-sans text-sm font-normal text-foreground min-w-0 wrap-anywhere",
68
+ // Headings follow the app's type scale (design.md §Headings), not a document scale: the page
69
+ // title is the only `text-2xl`, so a heading inside rendered text stops at `text-lg` for `#`,
70
+ // the section size (`text-base`) for `##`, and body size for everything below — weight carries
71
+ // the rest. Every heading wears `font-heading` like the app's own titles.
72
+ h1: "[&_h1]:mt-5 [&_h1]:mb-2 [&_h1]:scroll-m-20 [&_h1]:font-heading [&_h1]:text-lg [&_h1]:font-semibold [&_h1]:text-foreground [&_h1]:first:mt-0",
73
+ h2: "[&_h2]:mt-4 [&_h2]:mb-2 [&_h2]:scroll-m-20 [&_h2]:font-heading [&_h2]:text-base [&_h2]:font-semibold [&_h2]:text-foreground [&_h2]:first:mt-0",
74
+ h3: "[&_h3]:mt-4 [&_h3]:mb-1.5 [&_h3]:scroll-m-20 [&_h3]:font-heading [&_h3]:text-sm [&_h3]:font-semibold [&_h3]:text-foreground [&_h3]:first:mt-0",
75
+ h4: "[&_h4]:mt-3 [&_h4]:mb-1.5 [&_h4]:font-heading [&_h4]:text-sm [&_h4]:font-medium [&_h4]:text-foreground [&_h4]:first:mt-0",
76
+ h5: "[&_h5]:mt-3 [&_h5]:mb-1.5 [&_h5]:font-heading [&_h5]:text-sm [&_h5]:font-medium [&_h5]:text-foreground [&_h5]:first:mt-0",
77
+ h6: "[&_h6]:mt-3 [&_h6]:mb-1.5 [&_h6]:font-heading [&_h6]:text-sm [&_h6]:font-medium [&_h6]:text-foreground [&_h6]:first:mt-0",
78
+ // Body text is the app's body text — size, leading and ink inherit from the root, so a paragraph
79
+ // here is indistinguishable from any other `text-sm` paragraph in the product. No prose look.
80
+ p: "[&_p]:my-2 [&_p]:first:mt-0 [&_p]:last:mb-0",
81
+ // Marks. Links are `info` ink per design.md §Colours at body weight; `s` is Tiptap's strike
82
+ // element and `del` is GFM's — the same mark from two producers.
83
+ a: "[&_a]:text-info-text [&_a]:underline [&_a]:underline-offset-4 [&_a]:hover:text-info-text/88",
84
+ strong: "[&_strong]:font-semibold",
85
+ em: "[&_em]:italic",
86
+ del: "[&_del]:line-through [&_s]:line-through",
87
+ // Lists. Items and markers are body text: family, size and ink inherit (a `::marker` takes the
88
+ // item's font), so `1.` and `•` never read as a second typeface or a second colour. One thing
89
+ // does NOT inherit: the user-agent stylesheet gives `::marker` `font-variant-numeric:
90
+ // tabular-nums`, and Geist's tabular figures are fixed-width — that is what made ordered-list
91
+ // numbers look monospaced. `marker:normal-nums` restores the body's proportional figures. A GFM task
92
+ // list carries `contains-task-list` and its checkbox IS the marker, so the disc goes — expressed
93
+ // as a second, more specific descendant rule rather than a class on the element, which would
94
+ // lose the cascade (see the header).
95
+ ul: "[&_ul]:my-2 [&_ul]:ms-5 [&_ul]:list-disc [&_ul.contains-task-list]:list-none",
96
+ ol: "[&_ol]:my-2 [&_ol]:ms-5 [&_ol]:list-decimal",
97
+ li: "[&_li]:mt-1 [&_li]:marker:normal-nums [&_li]:marker:text-inherit [&_li_p]:my-0",
98
+ // Task lists, one shape for both producers: `MarkdownView` tags the GFM list
99
+ // `data-type="taskList"` and each item `data-type="taskItem"` with its body in a
100
+ // `data-slot="task-item-content"` box, which is exactly the DOM Tiptap's `TaskItem` node view
101
+ // renders — so the checkbox IS the marker, the body wraps beside it, and a nested list indents
102
+ // under the body in view and edit alike. The checkbox's hit area is trimmed to exactly 24px tall
103
+ // here (`after:-inset-y-1.25` — the pseudo insets from inside the 1px border — not its own 30px) and items sit 26px apart (`mt-1.5`), so each
104
+ // checkbox owns a whole 24px target with a hair to spare instead of reaching into its
105
+ // neighbour's.
106
+ taskList: "[&_ul[data-type=taskList]]:ms-0 [&_ul[data-type=taskList]]:list-none [&_li[data-type=taskItem]]:mt-1.5 [&_li[data-type=taskItem]]:flex [&_li[data-type=taskItem]]:items-start [&_li[data-type=taskItem]]:gap-2 [&_li[data-type=taskItem]_[data-slot=checkbox]]:mt-0.5 [&_li[data-type=taskItem]_[data-slot=checkbox]]:me-0 [&_li[data-type=taskItem]_[data-slot=checkbox]]:after:-inset-y-1.25 [&_[data-slot=task-item-content]]:min-w-0 [&_[data-slot=task-item-content]]:flex-1",
107
+ blockquote: "[&_blockquote]:my-2 [&_blockquote]:border-s-2 [&_blockquote]:border-border [&_blockquote]:ps-3",
108
+ // Inline code is a chip. Code inside a `pre` is not: it inherits the panel's ground, so the chip
109
+ // is undone at higher specificity (`[&_pre_code]` is (0,1,2) against the chip's (0,1,1)).
110
+ // Slack/Notion: a neutral grey chip with orange text (the syntax palette's literal colour), so
111
+ // inline code reads apart from prose in both themes; `tag-orange-text` on `muted` clears AA.
112
+ code: "[&_code]:rounded-sm [&_code]:bg-muted [&_code]:px-1.5 [&_code]:py-0.5 [&_code]:font-mono [&_code]:text-sm [&_code]:text-tag-orange-text",
113
+ // A bare `<pre>` wears `CodeBlock`'s surface — the same sunken panel, one vocabulary (B4-09).
114
+ // `CodeBlock`'s own `pre` is excluded: it already sits inside a `figure` carrying the border,
115
+ // radius and ground, and re-applying them here would draw a second panel inside the first.
116
+ pre: "[&_pre:not([data-slot='code-block-pre'])]:my-2 [&_pre:not([data-slot='code-block-pre'])]:overflow-x-auto [&_pre:not([data-slot='code-block-pre'])]:rounded-lg [&_pre:not([data-slot='code-block-pre'])]:border [&_pre:not([data-slot='code-block-pre'])]:border-border [&_pre:not([data-slot='code-block-pre'])]:bg-muted [&_pre:not([data-slot='code-block-pre'])]:p-4 [&_pre:not([data-slot='code-block-pre'])]:text-foreground",
117
+ preCode: "[&_pre_code]:bg-transparent [&_pre_code]:p-0 [&_pre_code]:font-mono [&_pre_code]:text-sm [&_pre_code]:text-foreground",
118
+ hr: "[&_hr]:my-4 [&_hr]:border-border",
119
+ // GFM tables, Notion's simple table: a rounded outer border, a rule between every cell, and a
120
+ // header row on a subtle muted ground at medium weight. The scroll container is structural and
121
+ // belongs to the consumer (MarkdownView and TextEdit each wrap the table in an `overflow-x-auto`
122
+ // box); these are the cell and rule tokens. `border-separate` with zero spacing is what lets the
123
+ // table itself take the radius (a collapsed table cannot); each cell draws only its bottom and
124
+ // end rule, the last row and column drop theirs against the outer border, and the corner cells
125
+ // take the radius so a header or selected fill never pokes past the curve. Cells take
126
+ // `break-word`, not the root's `anywhere`, so a column keeps its words whole and the table scrolls
127
+ // in its box rather than crushing to one character per line.
128
+ table: "[&_table]:w-full [&_table]:border-separate [&_table]:border-spacing-0 [&_table]:rounded-lg [&_table]:border [&_table]:border-border",
129
+ tableRules: "[&_th]:border-e [&_th]:border-b [&_th]:border-border [&_td]:border-e [&_td]:border-b [&_td]:border-border [&_tr>*:last-child]:border-e-0 [&_tbody>tr:last-child>*]:border-b-0 [&_tr:first-child>*:first-child]:rounded-ss-lg [&_tr:first-child>*:last-child]:rounded-se-lg [&_tbody>tr:last-child>*:first-child]:rounded-es-lg [&_tbody>tr:last-child>*:last-child]:rounded-ee-lg",
130
+ tableCells: "[&_th]:bg-muted/50 [&_th]:px-3 [&_th]:py-2 [&_th]:text-start [&_th]:align-top [&_th]:font-medium [&_td]:px-3 [&_td]:py-2 [&_td]:align-top [&_td_p]:my-0 [&_th_p]:my-0 [&_th]:wrap-break-word [&_td]:wrap-break-word",
131
+ img: "[&_img]:my-2 [&_img]:max-w-full [&_img]:rounded-lg [&_img]:border [&_img]:border-border"
132
+ };
133
+ var proseClassName = Object.values(prose).join(" ");
134
+ var proseDocument = {
135
+ /** Body: 14/24 on a fine pointer, 16/26 on a coarse pointer or below the `sm` width. */
136
+ root: "text-sm/6 pointer-coarse:text-base/6.5 max-sm:text-base/6.5",
137
+ // Headings: semibold (the base recipe's weight), more room above than below. The first block
138
+ // keeps `first:mt-0` from the base recipe. `scroll-mt-18` clears a 56px sticky header + 16.
139
+ h1: "[&_h1]:mt-8 [&_h1]:mb-3 [&_h1]:scroll-mt-18 [&_h1]:text-2xl/8",
140
+ h2: "[&_h2]:mt-7 [&_h2]:mb-2 [&_h2]:scroll-mt-18 [&_h2]:text-xl/7",
141
+ h3: "[&_h3]:mt-6 [&_h3]:mb-1.5 [&_h3]:scroll-mt-18 [&_h3]:text-base/6 pointer-coarse:[&_h3]:text-lg/7 max-sm:[&_h3]:text-lg/7",
142
+ h4: "[&_h4]:mt-5 [&_h4]:mb-1 [&_h4]:scroll-mt-18 [&_h4]:text-sm/6 [&_h4]:font-semibold pointer-coarse:[&_h4]:text-base/6.5 max-sm:[&_h4]:text-base/6.5",
143
+ // A 12px gap between paragraphs; none before the first or after the last.
144
+ p: "[&_p]:my-3",
145
+ // Lists indent 24, items 4 apart, a nested list 4 below its item's text.
146
+ ul: "[&_ul]:my-3 [&_ul]:ms-6",
147
+ ol: "[&_ol]:my-3 [&_ol]:ms-6",
148
+ li: "[&_li_ul]:mt-1 [&_li_ul]:mb-0 [&_li_ol]:mt-1 [&_li_ol]:mb-0",
149
+ // A quote is a rule and an indent, never italic; blocks breathe 16 apart.
150
+ blockquote: "[&_blockquote]:my-4 [&_blockquote]:ps-4",
151
+ // No orange in documents: inline code is a grey chip in the body's own ink.
152
+ code: "[&_code]:text-foreground",
153
+ pre: "[&_pre:not([data-slot='code-block-pre'])]:my-4",
154
+ hr: "[&_hr]:my-6",
155
+ img: "[&_img]:my-4",
156
+ // Tables read at 14/20 at every pointer, 16 from the blocks around them (the scroll box is the
157
+ // consumer's: `MarkdownView`'s `markdown-table`, the editor's `.tableWrapper`).
158
+ table: "[&_th]:text-sm/5 [&_td]:text-sm/5 [&_[data-slot=markdown-table]]:my-4 [&_.tableWrapper]:my-4",
159
+ // Callouts, toggles, code blocks and media sit 16 from their neighbours; a toggle's summary is
160
+ // a 24px row, 44px on a coarse pointer.
161
+ blocks: "[&_[data-slot=callout]]:my-4 [&_[data-slot=code-block]]:my-4 [&_details]:my-4 [&_video]:my-4 [&_audio]:my-4 [&_summary]:min-h-6 pointer-coarse:[&_summary]:min-h-11"
162
+ };
163
+
164
+ // src/index.ts
44
165
  var twMerge = import_tailwind_merge.twMerge;
45
166
  function cn(...inputs) {
46
167
  return twMerge((0, import_clsx.clsx)(inputs));
47
168
  }
169
+ var proseDocumentClassName = cn(
170
+ proseClassName,
171
+ Object.values(proseDocument).join(" ")
172
+ );
48
173
 
49
174
  // src/icons/create-animated-icon.tsx
50
175
  var import_jsx_runtime = require("react/jsx-runtime");
@@ -1,7 +1,7 @@
1
1
  "use client";
2
2
  import {
3
3
  cn
4
- } from "./chunk-R6IZOGT5.js";
4
+ } from "./chunk-DG7GQHEH.js";
5
5
 
6
6
  // src/icons/create-animated-icon.tsx
7
7
  import * as React from "react";
@@ -55,10 +55,135 @@ var React2 = require("react");
55
55
  // src/index.ts
56
56
  var import_clsx = require("clsx");
57
57
  var import_tailwind_merge = require("tailwind-merge");
58
+
59
+ // src/prose.ts
60
+ var prose = {
61
+ /**
62
+ * The root's own FAMILY, ink and size — every rule below is relative to this.
63
+ *
64
+ * `font-sans` is load-bearing and was missing. A prose root has to be self-describing, because
65
+ * neither of its two consumers sets a family of its own: `MarkdownView` and `TextEdit` both wear
66
+ * nothing but `proseClassName`. With no family declared here, prose inherited whatever surrounded
67
+ * it — drop either surface inside a mono container (`terminal-body` is one in this very
68
+ * registry, and a chat or log panel is the obvious consumer case) and the WHOLE tree went mono:
69
+ * headings, paragraphs, table cells, and the `1.` / `2.` markers of an ordered list, because
70
+ * `::marker` inherits font properties from its originating element.
71
+ *
72
+ * Geist Mono is now the exception the recipe names explicitly — `code`, `pre` and `pre code` —
73
+ * rather than something prose falls into by accident. A consumer who genuinely wants mono prose
74
+ * still says so on the root, where it reads as a decision.
75
+ *
76
+ * `min-w-0 wrap-anywhere` is the no-horizontal-overflow contract (2026-09-26): a long word, URL
77
+ * or inline code run breaks inside the line instead of widening the page, and `anywhere` (not
78
+ * `break-word`) also lowers the min-content width, so a prose root inside a flex item shrinks.
79
+ * Fenced code (`white-space: pre`) and tables keep their lines and scroll inside their own box.
80
+ */
81
+ root: "font-sans text-sm font-normal text-foreground min-w-0 wrap-anywhere",
82
+ // Headings follow the app's type scale (design.md §Headings), not a document scale: the page
83
+ // title is the only `text-2xl`, so a heading inside rendered text stops at `text-lg` for `#`,
84
+ // the section size (`text-base`) for `##`, and body size for everything below — weight carries
85
+ // the rest. Every heading wears `font-heading` like the app's own titles.
86
+ h1: "[&_h1]:mt-5 [&_h1]:mb-2 [&_h1]:scroll-m-20 [&_h1]:font-heading [&_h1]:text-lg [&_h1]:font-semibold [&_h1]:text-foreground [&_h1]:first:mt-0",
87
+ h2: "[&_h2]:mt-4 [&_h2]:mb-2 [&_h2]:scroll-m-20 [&_h2]:font-heading [&_h2]:text-base [&_h2]:font-semibold [&_h2]:text-foreground [&_h2]:first:mt-0",
88
+ h3: "[&_h3]:mt-4 [&_h3]:mb-1.5 [&_h3]:scroll-m-20 [&_h3]:font-heading [&_h3]:text-sm [&_h3]:font-semibold [&_h3]:text-foreground [&_h3]:first:mt-0",
89
+ h4: "[&_h4]:mt-3 [&_h4]:mb-1.5 [&_h4]:font-heading [&_h4]:text-sm [&_h4]:font-medium [&_h4]:text-foreground [&_h4]:first:mt-0",
90
+ h5: "[&_h5]:mt-3 [&_h5]:mb-1.5 [&_h5]:font-heading [&_h5]:text-sm [&_h5]:font-medium [&_h5]:text-foreground [&_h5]:first:mt-0",
91
+ h6: "[&_h6]:mt-3 [&_h6]:mb-1.5 [&_h6]:font-heading [&_h6]:text-sm [&_h6]:font-medium [&_h6]:text-foreground [&_h6]:first:mt-0",
92
+ // Body text is the app's body text — size, leading and ink inherit from the root, so a paragraph
93
+ // here is indistinguishable from any other `text-sm` paragraph in the product. No prose look.
94
+ p: "[&_p]:my-2 [&_p]:first:mt-0 [&_p]:last:mb-0",
95
+ // Marks. Links are `info` ink per design.md §Colours at body weight; `s` is Tiptap's strike
96
+ // element and `del` is GFM's — the same mark from two producers.
97
+ a: "[&_a]:text-info-text [&_a]:underline [&_a]:underline-offset-4 [&_a]:hover:text-info-text/88",
98
+ strong: "[&_strong]:font-semibold",
99
+ em: "[&_em]:italic",
100
+ del: "[&_del]:line-through [&_s]:line-through",
101
+ // Lists. Items and markers are body text: family, size and ink inherit (a `::marker` takes the
102
+ // item's font), so `1.` and `•` never read as a second typeface or a second colour. One thing
103
+ // does NOT inherit: the user-agent stylesheet gives `::marker` `font-variant-numeric:
104
+ // tabular-nums`, and Geist's tabular figures are fixed-width — that is what made ordered-list
105
+ // numbers look monospaced. `marker:normal-nums` restores the body's proportional figures. A GFM task
106
+ // list carries `contains-task-list` and its checkbox IS the marker, so the disc goes — expressed
107
+ // as a second, more specific descendant rule rather than a class on the element, which would
108
+ // lose the cascade (see the header).
109
+ ul: "[&_ul]:my-2 [&_ul]:ms-5 [&_ul]:list-disc [&_ul.contains-task-list]:list-none",
110
+ ol: "[&_ol]:my-2 [&_ol]:ms-5 [&_ol]:list-decimal",
111
+ li: "[&_li]:mt-1 [&_li]:marker:normal-nums [&_li]:marker:text-inherit [&_li_p]:my-0",
112
+ // Task lists, one shape for both producers: `MarkdownView` tags the GFM list
113
+ // `data-type="taskList"` and each item `data-type="taskItem"` with its body in a
114
+ // `data-slot="task-item-content"` box, which is exactly the DOM Tiptap's `TaskItem` node view
115
+ // renders — so the checkbox IS the marker, the body wraps beside it, and a nested list indents
116
+ // under the body in view and edit alike. The checkbox's hit area is trimmed to exactly 24px tall
117
+ // here (`after:-inset-y-1.25` — the pseudo insets from inside the 1px border — not its own 30px) and items sit 26px apart (`mt-1.5`), so each
118
+ // checkbox owns a whole 24px target with a hair to spare instead of reaching into its
119
+ // neighbour's.
120
+ taskList: "[&_ul[data-type=taskList]]:ms-0 [&_ul[data-type=taskList]]:list-none [&_li[data-type=taskItem]]:mt-1.5 [&_li[data-type=taskItem]]:flex [&_li[data-type=taskItem]]:items-start [&_li[data-type=taskItem]]:gap-2 [&_li[data-type=taskItem]_[data-slot=checkbox]]:mt-0.5 [&_li[data-type=taskItem]_[data-slot=checkbox]]:me-0 [&_li[data-type=taskItem]_[data-slot=checkbox]]:after:-inset-y-1.25 [&_[data-slot=task-item-content]]:min-w-0 [&_[data-slot=task-item-content]]:flex-1",
121
+ blockquote: "[&_blockquote]:my-2 [&_blockquote]:border-s-2 [&_blockquote]:border-border [&_blockquote]:ps-3",
122
+ // Inline code is a chip. Code inside a `pre` is not: it inherits the panel's ground, so the chip
123
+ // is undone at higher specificity (`[&_pre_code]` is (0,1,2) against the chip's (0,1,1)).
124
+ // Slack/Notion: a neutral grey chip with orange text (the syntax palette's literal colour), so
125
+ // inline code reads apart from prose in both themes; `tag-orange-text` on `muted` clears AA.
126
+ code: "[&_code]:rounded-sm [&_code]:bg-muted [&_code]:px-1.5 [&_code]:py-0.5 [&_code]:font-mono [&_code]:text-sm [&_code]:text-tag-orange-text",
127
+ // A bare `<pre>` wears `CodeBlock`'s surface — the same sunken panel, one vocabulary (B4-09).
128
+ // `CodeBlock`'s own `pre` is excluded: it already sits inside a `figure` carrying the border,
129
+ // radius and ground, and re-applying them here would draw a second panel inside the first.
130
+ pre: "[&_pre:not([data-slot='code-block-pre'])]:my-2 [&_pre:not([data-slot='code-block-pre'])]:overflow-x-auto [&_pre:not([data-slot='code-block-pre'])]:rounded-lg [&_pre:not([data-slot='code-block-pre'])]:border [&_pre:not([data-slot='code-block-pre'])]:border-border [&_pre:not([data-slot='code-block-pre'])]:bg-muted [&_pre:not([data-slot='code-block-pre'])]:p-4 [&_pre:not([data-slot='code-block-pre'])]:text-foreground",
131
+ preCode: "[&_pre_code]:bg-transparent [&_pre_code]:p-0 [&_pre_code]:font-mono [&_pre_code]:text-sm [&_pre_code]:text-foreground",
132
+ hr: "[&_hr]:my-4 [&_hr]:border-border",
133
+ // GFM tables, Notion's simple table: a rounded outer border, a rule between every cell, and a
134
+ // header row on a subtle muted ground at medium weight. The scroll container is structural and
135
+ // belongs to the consumer (MarkdownView and TextEdit each wrap the table in an `overflow-x-auto`
136
+ // box); these are the cell and rule tokens. `border-separate` with zero spacing is what lets the
137
+ // table itself take the radius (a collapsed table cannot); each cell draws only its bottom and
138
+ // end rule, the last row and column drop theirs against the outer border, and the corner cells
139
+ // take the radius so a header or selected fill never pokes past the curve. Cells take
140
+ // `break-word`, not the root's `anywhere`, so a column keeps its words whole and the table scrolls
141
+ // in its box rather than crushing to one character per line.
142
+ table: "[&_table]:w-full [&_table]:border-separate [&_table]:border-spacing-0 [&_table]:rounded-lg [&_table]:border [&_table]:border-border",
143
+ tableRules: "[&_th]:border-e [&_th]:border-b [&_th]:border-border [&_td]:border-e [&_td]:border-b [&_td]:border-border [&_tr>*:last-child]:border-e-0 [&_tbody>tr:last-child>*]:border-b-0 [&_tr:first-child>*:first-child]:rounded-ss-lg [&_tr:first-child>*:last-child]:rounded-se-lg [&_tbody>tr:last-child>*:first-child]:rounded-es-lg [&_tbody>tr:last-child>*:last-child]:rounded-ee-lg",
144
+ tableCells: "[&_th]:bg-muted/50 [&_th]:px-3 [&_th]:py-2 [&_th]:text-start [&_th]:align-top [&_th]:font-medium [&_td]:px-3 [&_td]:py-2 [&_td]:align-top [&_td_p]:my-0 [&_th_p]:my-0 [&_th]:wrap-break-word [&_td]:wrap-break-word",
145
+ img: "[&_img]:my-2 [&_img]:max-w-full [&_img]:rounded-lg [&_img]:border [&_img]:border-border"
146
+ };
147
+ var proseClassName = Object.values(prose).join(" ");
148
+ var proseDocument = {
149
+ /** Body: 14/24 on a fine pointer, 16/26 on a coarse pointer or below the `sm` width. */
150
+ root: "text-sm/6 pointer-coarse:text-base/6.5 max-sm:text-base/6.5",
151
+ // Headings: semibold (the base recipe's weight), more room above than below. The first block
152
+ // keeps `first:mt-0` from the base recipe. `scroll-mt-18` clears a 56px sticky header + 16.
153
+ h1: "[&_h1]:mt-8 [&_h1]:mb-3 [&_h1]:scroll-mt-18 [&_h1]:text-2xl/8",
154
+ h2: "[&_h2]:mt-7 [&_h2]:mb-2 [&_h2]:scroll-mt-18 [&_h2]:text-xl/7",
155
+ h3: "[&_h3]:mt-6 [&_h3]:mb-1.5 [&_h3]:scroll-mt-18 [&_h3]:text-base/6 pointer-coarse:[&_h3]:text-lg/7 max-sm:[&_h3]:text-lg/7",
156
+ h4: "[&_h4]:mt-5 [&_h4]:mb-1 [&_h4]:scroll-mt-18 [&_h4]:text-sm/6 [&_h4]:font-semibold pointer-coarse:[&_h4]:text-base/6.5 max-sm:[&_h4]:text-base/6.5",
157
+ // A 12px gap between paragraphs; none before the first or after the last.
158
+ p: "[&_p]:my-3",
159
+ // Lists indent 24, items 4 apart, a nested list 4 below its item's text.
160
+ ul: "[&_ul]:my-3 [&_ul]:ms-6",
161
+ ol: "[&_ol]:my-3 [&_ol]:ms-6",
162
+ li: "[&_li_ul]:mt-1 [&_li_ul]:mb-0 [&_li_ol]:mt-1 [&_li_ol]:mb-0",
163
+ // A quote is a rule and an indent, never italic; blocks breathe 16 apart.
164
+ blockquote: "[&_blockquote]:my-4 [&_blockquote]:ps-4",
165
+ // No orange in documents: inline code is a grey chip in the body's own ink.
166
+ code: "[&_code]:text-foreground",
167
+ pre: "[&_pre:not([data-slot='code-block-pre'])]:my-4",
168
+ hr: "[&_hr]:my-6",
169
+ img: "[&_img]:my-4",
170
+ // Tables read at 14/20 at every pointer, 16 from the blocks around them (the scroll box is the
171
+ // consumer's: `MarkdownView`'s `markdown-table`, the editor's `.tableWrapper`).
172
+ table: "[&_th]:text-sm/5 [&_td]:text-sm/5 [&_[data-slot=markdown-table]]:my-4 [&_.tableWrapper]:my-4",
173
+ // Callouts, toggles, code blocks and media sit 16 from their neighbours; a toggle's summary is
174
+ // a 24px row, 44px on a coarse pointer.
175
+ blocks: "[&_[data-slot=callout]]:my-4 [&_[data-slot=code-block]]:my-4 [&_details]:my-4 [&_video]:my-4 [&_audio]:my-4 [&_summary]:min-h-6 pointer-coarse:[&_summary]:min-h-11"
176
+ };
177
+
178
+ // src/index.ts
58
179
  var twMerge = import_tailwind_merge.twMerge;
59
180
  function cn(...inputs) {
60
181
  return twMerge((0, import_clsx.clsx)(inputs));
61
182
  }
183
+ var proseDocumentClassName = cn(
184
+ proseClassName,
185
+ Object.values(proseDocument).join(" ")
186
+ );
62
187
 
63
188
  // src/icons/brand-icon.tsx
64
189
  var import_jsx_runtime2 = require("react/jsx-runtime");
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  cn
3
- } from "../chunk-R6IZOGT5.js";
3
+ } from "../chunk-DG7GQHEH.js";
4
4
 
5
5
  // src/icons/icon.tsx
6
6
  import "react";
package/dist/index.cjs CHANGED
@@ -25,7 +25,9 @@ __export(src_exports, {
25
25
  cn: () => cn,
26
26
  mergeRefs: () => mergeRefs,
27
27
  prose: () => prose,
28
- proseClassName: () => proseClassName
28
+ proseClassName: () => proseClassName,
29
+ proseDocument: () => proseDocument,
30
+ proseDocumentClassName: () => proseDocumentClassName
29
31
  });
30
32
  module.exports = __toCommonJS(src_exports);
31
33
  var import_clsx = require("clsx");
@@ -120,6 +122,35 @@ var prose = {
120
122
  img: "[&_img]:my-2 [&_img]:max-w-full [&_img]:rounded-lg [&_img]:border [&_img]:border-border"
121
123
  };
122
124
  var proseClassName = Object.values(prose).join(" ");
125
+ var proseDocument = {
126
+ /** Body: 14/24 on a fine pointer, 16/26 on a coarse pointer or below the `sm` width. */
127
+ root: "text-sm/6 pointer-coarse:text-base/6.5 max-sm:text-base/6.5",
128
+ // Headings: semibold (the base recipe's weight), more room above than below. The first block
129
+ // keeps `first:mt-0` from the base recipe. `scroll-mt-18` clears a 56px sticky header + 16.
130
+ h1: "[&_h1]:mt-8 [&_h1]:mb-3 [&_h1]:scroll-mt-18 [&_h1]:text-2xl/8",
131
+ h2: "[&_h2]:mt-7 [&_h2]:mb-2 [&_h2]:scroll-mt-18 [&_h2]:text-xl/7",
132
+ h3: "[&_h3]:mt-6 [&_h3]:mb-1.5 [&_h3]:scroll-mt-18 [&_h3]:text-base/6 pointer-coarse:[&_h3]:text-lg/7 max-sm:[&_h3]:text-lg/7",
133
+ h4: "[&_h4]:mt-5 [&_h4]:mb-1 [&_h4]:scroll-mt-18 [&_h4]:text-sm/6 [&_h4]:font-semibold pointer-coarse:[&_h4]:text-base/6.5 max-sm:[&_h4]:text-base/6.5",
134
+ // A 12px gap between paragraphs; none before the first or after the last.
135
+ p: "[&_p]:my-3",
136
+ // Lists indent 24, items 4 apart, a nested list 4 below its item's text.
137
+ ul: "[&_ul]:my-3 [&_ul]:ms-6",
138
+ ol: "[&_ol]:my-3 [&_ol]:ms-6",
139
+ li: "[&_li_ul]:mt-1 [&_li_ul]:mb-0 [&_li_ol]:mt-1 [&_li_ol]:mb-0",
140
+ // A quote is a rule and an indent, never italic; blocks breathe 16 apart.
141
+ blockquote: "[&_blockquote]:my-4 [&_blockquote]:ps-4",
142
+ // No orange in documents: inline code is a grey chip in the body's own ink.
143
+ code: "[&_code]:text-foreground",
144
+ pre: "[&_pre:not([data-slot='code-block-pre'])]:my-4",
145
+ hr: "[&_hr]:my-6",
146
+ img: "[&_img]:my-4",
147
+ // Tables read at 14/20 at every pointer, 16 from the blocks around them (the scroll box is the
148
+ // consumer's: `MarkdownView`'s `markdown-table`, the editor's `.tableWrapper`).
149
+ table: "[&_th]:text-sm/5 [&_td]:text-sm/5 [&_[data-slot=markdown-table]]:my-4 [&_.tableWrapper]:my-4",
150
+ // Callouts, toggles, code blocks and media sit 16 from their neighbours; a toggle's summary is
151
+ // a 24px row, 44px on a coarse pointer.
152
+ blocks: "[&_[data-slot=callout]]:my-4 [&_[data-slot=code-block]]:my-4 [&_details]:my-4 [&_video]:my-4 [&_audio]:my-4 [&_summary]:min-h-6 pointer-coarse:[&_summary]:min-h-11"
153
+ };
123
154
 
124
155
  // src/index.ts
125
156
  var twMerge = import_tailwind_merge.twMerge;
@@ -161,6 +192,10 @@ var FLOATING = {
161
192
  sideOffsetDetached: 8,
162
193
  collisionPadding: 8
163
194
  };
195
+ var proseDocumentClassName = cn(
196
+ proseClassName,
197
+ Object.values(proseDocument).join(" ")
198
+ );
164
199
  function mergeRefs(...refs) {
165
200
  return (node) => {
166
201
  const cleanups = refs.map((ref) => {
@@ -198,5 +233,7 @@ function mergeRefs(...refs) {
198
233
  cn,
199
234
  mergeRefs,
200
235
  prose,
201
- proseClassName
236
+ proseClassName,
237
+ proseDocument,
238
+ proseDocumentClassName
202
239
  });
package/dist/index.d.cts CHANGED
@@ -96,6 +96,45 @@ type ProseElement = keyof typeof prose;
96
96
  * string that never changes.
97
97
  */
98
98
  declare const proseClassName: string;
99
+ /**
100
+ * THE document type scale — `typeScale="document"` on `MarkdownView` and `TextEdit` (TYP-20, MK
101
+ * 2026-10-14, Regent Pages v2 Round 2). A page read as a document: calm 14/24 body text on a fine
102
+ * pointer, 16/26 on a coarse pointer or a narrow window (the same 16px INT-13 already gives a
103
+ * touch editor, so reading and editing never jump and iOS never zooms), a 12px paragraph gap,
104
+ * and headings H1 24 · H2 20 · H3 16 with more room above than below. On 16px body text H3 steps
105
+ * up to 18 and H4 to 16, so a heading never sits at the body's own size.
106
+ *
107
+ * It is an OVERLAY on `prose`, never a replacement: compose it after the base recipe through
108
+ * `cn` (tailwind-merge resolves each `[&_h1]:text-lg` against its `[&_h1]:text-2xl/8`), or use
109
+ * `proseDocumentClassName`, which is that composition done once.
110
+ *
111
+ * The measure (about 67 characters a line) is the layout's, not the recipe's: `DocumentLayout`
112
+ * caps its text column at `--document-measure` (47ch), in the same font size this recipe sets.
113
+ *
114
+ * @example
115
+ * <div className={cn(proseClassName, proseDocument.root, proseDocument.h1)} />
116
+ */
117
+ declare const proseDocument: {
118
+ /** Body: 14/24 on a fine pointer, 16/26 on a coarse pointer or below the `sm` width. */
119
+ readonly root: "text-sm/6 pointer-coarse:text-base/6.5 max-sm:text-base/6.5";
120
+ readonly h1: "[&_h1]:mt-8 [&_h1]:mb-3 [&_h1]:scroll-mt-18 [&_h1]:text-2xl/8";
121
+ readonly h2: "[&_h2]:mt-7 [&_h2]:mb-2 [&_h2]:scroll-mt-18 [&_h2]:text-xl/7";
122
+ readonly h3: "[&_h3]:mt-6 [&_h3]:mb-1.5 [&_h3]:scroll-mt-18 [&_h3]:text-base/6 pointer-coarse:[&_h3]:text-lg/7 max-sm:[&_h3]:text-lg/7";
123
+ readonly h4: "[&_h4]:mt-5 [&_h4]:mb-1 [&_h4]:scroll-mt-18 [&_h4]:text-sm/6 [&_h4]:font-semibold pointer-coarse:[&_h4]:text-base/6.5 max-sm:[&_h4]:text-base/6.5";
124
+ readonly p: "[&_p]:my-3";
125
+ readonly ul: "[&_ul]:my-3 [&_ul]:ms-6";
126
+ readonly ol: "[&_ol]:my-3 [&_ol]:ms-6";
127
+ readonly li: "[&_li_ul]:mt-1 [&_li_ul]:mb-0 [&_li_ol]:mt-1 [&_li_ol]:mb-0";
128
+ readonly blockquote: "[&_blockquote]:my-4 [&_blockquote]:ps-4";
129
+ readonly code: "[&_code]:text-foreground";
130
+ readonly pre: "[&_pre:not([data-slot='code-block-pre'])]:my-4";
131
+ readonly hr: "[&_hr]:my-6";
132
+ readonly img: "[&_img]:my-4";
133
+ readonly table: "[&_th]:text-sm/5 [&_td]:text-sm/5 [&_[data-slot=markdown-table]]:my-4 [&_.tableWrapper]:my-4";
134
+ readonly blocks: "[&_[data-slot=callout]]:my-4 [&_[data-slot=code-block]]:my-4 [&_details]:my-4 [&_video]:my-4 [&_audio]:my-4 [&_summary]:min-h-6 pointer-coarse:[&_summary]:min-h-11";
135
+ };
136
+ /** The element roles the document overlay covers. */
137
+ type ProseDocumentElement = keyof typeof proseDocument;
99
138
 
100
139
  /**
101
140
  * Merges Tailwind CSS class names with intelligent conflict resolution.
@@ -180,6 +219,16 @@ declare const FLOATING: {
180
219
  readonly collisionPadding: 8;
181
220
  };
182
221
 
222
+ /**
223
+ * The document type scale as one class string: the base `prose` recipe with the `proseDocument`
224
+ * overlay merged over it (TYP-20) — what `MarkdownView` and `TextEdit` wear with
225
+ * `typeScale="document"`. Merged once here, through `cn`, so every `[&_h1]:text-lg` of the base
226
+ * recipe yields to its document value and nothing pays for a `tailwind-merge` pass per render.
227
+ *
228
+ * @example
229
+ * <article className={proseDocumentClassName}>…</article>
230
+ */
231
+ declare const proseDocumentClassName: string;
183
232
  /**
184
233
  * Fan one DOM node out to several refs — a forwarded `ref` prop plus one or more internal
185
234
  * refs — as a single ref callback. Skips `null`/`undefined` entries, so an optional
@@ -210,4 +259,4 @@ declare const FLOATING: {
210
259
  */
211
260
  declare function mergeRefs<T>(...refs: Array<React.Ref<T> | null | undefined>): React.RefCallback<T>;
212
261
 
213
- export { FLOATING, type ProseElement, TIMINGS, cn, mergeRefs, prose, proseClassName };
262
+ export { FLOATING, type ProseDocumentElement, type ProseElement, TIMINGS, cn, mergeRefs, prose, proseClassName, proseDocument, proseDocumentClassName };
package/dist/index.d.ts CHANGED
@@ -96,6 +96,45 @@ type ProseElement = keyof typeof prose;
96
96
  * string that never changes.
97
97
  */
98
98
  declare const proseClassName: string;
99
+ /**
100
+ * THE document type scale — `typeScale="document"` on `MarkdownView` and `TextEdit` (TYP-20, MK
101
+ * 2026-10-14, Regent Pages v2 Round 2). A page read as a document: calm 14/24 body text on a fine
102
+ * pointer, 16/26 on a coarse pointer or a narrow window (the same 16px INT-13 already gives a
103
+ * touch editor, so reading and editing never jump and iOS never zooms), a 12px paragraph gap,
104
+ * and headings H1 24 · H2 20 · H3 16 with more room above than below. On 16px body text H3 steps
105
+ * up to 18 and H4 to 16, so a heading never sits at the body's own size.
106
+ *
107
+ * It is an OVERLAY on `prose`, never a replacement: compose it after the base recipe through
108
+ * `cn` (tailwind-merge resolves each `[&_h1]:text-lg` against its `[&_h1]:text-2xl/8`), or use
109
+ * `proseDocumentClassName`, which is that composition done once.
110
+ *
111
+ * The measure (about 67 characters a line) is the layout's, not the recipe's: `DocumentLayout`
112
+ * caps its text column at `--document-measure` (47ch), in the same font size this recipe sets.
113
+ *
114
+ * @example
115
+ * <div className={cn(proseClassName, proseDocument.root, proseDocument.h1)} />
116
+ */
117
+ declare const proseDocument: {
118
+ /** Body: 14/24 on a fine pointer, 16/26 on a coarse pointer or below the `sm` width. */
119
+ readonly root: "text-sm/6 pointer-coarse:text-base/6.5 max-sm:text-base/6.5";
120
+ readonly h1: "[&_h1]:mt-8 [&_h1]:mb-3 [&_h1]:scroll-mt-18 [&_h1]:text-2xl/8";
121
+ readonly h2: "[&_h2]:mt-7 [&_h2]:mb-2 [&_h2]:scroll-mt-18 [&_h2]:text-xl/7";
122
+ readonly h3: "[&_h3]:mt-6 [&_h3]:mb-1.5 [&_h3]:scroll-mt-18 [&_h3]:text-base/6 pointer-coarse:[&_h3]:text-lg/7 max-sm:[&_h3]:text-lg/7";
123
+ readonly h4: "[&_h4]:mt-5 [&_h4]:mb-1 [&_h4]:scroll-mt-18 [&_h4]:text-sm/6 [&_h4]:font-semibold pointer-coarse:[&_h4]:text-base/6.5 max-sm:[&_h4]:text-base/6.5";
124
+ readonly p: "[&_p]:my-3";
125
+ readonly ul: "[&_ul]:my-3 [&_ul]:ms-6";
126
+ readonly ol: "[&_ol]:my-3 [&_ol]:ms-6";
127
+ readonly li: "[&_li_ul]:mt-1 [&_li_ul]:mb-0 [&_li_ol]:mt-1 [&_li_ol]:mb-0";
128
+ readonly blockquote: "[&_blockquote]:my-4 [&_blockquote]:ps-4";
129
+ readonly code: "[&_code]:text-foreground";
130
+ readonly pre: "[&_pre:not([data-slot='code-block-pre'])]:my-4";
131
+ readonly hr: "[&_hr]:my-6";
132
+ readonly img: "[&_img]:my-4";
133
+ readonly table: "[&_th]:text-sm/5 [&_td]:text-sm/5 [&_[data-slot=markdown-table]]:my-4 [&_.tableWrapper]:my-4";
134
+ readonly blocks: "[&_[data-slot=callout]]:my-4 [&_[data-slot=code-block]]:my-4 [&_details]:my-4 [&_video]:my-4 [&_audio]:my-4 [&_summary]:min-h-6 pointer-coarse:[&_summary]:min-h-11";
135
+ };
136
+ /** The element roles the document overlay covers. */
137
+ type ProseDocumentElement = keyof typeof proseDocument;
99
138
 
100
139
  /**
101
140
  * Merges Tailwind CSS class names with intelligent conflict resolution.
@@ -180,6 +219,16 @@ declare const FLOATING: {
180
219
  readonly collisionPadding: 8;
181
220
  };
182
221
 
222
+ /**
223
+ * The document type scale as one class string: the base `prose` recipe with the `proseDocument`
224
+ * overlay merged over it (TYP-20) — what `MarkdownView` and `TextEdit` wear with
225
+ * `typeScale="document"`. Merged once here, through `cn`, so every `[&_h1]:text-lg` of the base
226
+ * recipe yields to its document value and nothing pays for a `tailwind-merge` pass per render.
227
+ *
228
+ * @example
229
+ * <article className={proseDocumentClassName}>…</article>
230
+ */
231
+ declare const proseDocumentClassName: string;
183
232
  /**
184
233
  * Fan one DOM node out to several refs — a forwarded `ref` prop plus one or more internal
185
234
  * refs — as a single ref callback. Skips `null`/`undefined` entries, so an optional
@@ -210,4 +259,4 @@ declare const FLOATING: {
210
259
  */
211
260
  declare function mergeRefs<T>(...refs: Array<React.Ref<T> | null | undefined>): React.RefCallback<T>;
212
261
 
213
- export { FLOATING, type ProseElement, TIMINGS, cn, mergeRefs, prose, proseClassName };
262
+ export { FLOATING, type ProseDocumentElement, type ProseElement, TIMINGS, cn, mergeRefs, prose, proseClassName, proseDocument, proseDocumentClassName };
package/dist/index.js CHANGED
@@ -4,13 +4,17 @@ import {
4
4
  cn,
5
5
  mergeRefs,
6
6
  prose,
7
- proseClassName
8
- } from "./chunk-R6IZOGT5.js";
7
+ proseClassName,
8
+ proseDocument,
9
+ proseDocumentClassName
10
+ } from "./chunk-DG7GQHEH.js";
9
11
  export {
10
12
  FLOATING,
11
13
  TIMINGS,
12
14
  cn,
13
15
  mergeRefs,
14
16
  prose,
15
- proseClassName
17
+ proseClassName,
18
+ proseDocument,
19
+ proseDocumentClassName
16
20
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vegastack/design",
3
- "version": "0.8.11",
3
+ "version": "0.8.12",
4
4
  "description": "VegaStack design system — cn utility, icon runtime, Tailwind v4 preset, and the vegastack-design CLI (tokens ship separately as @vegastack/design-tokens)",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -70,7 +70,7 @@
70
70
  "test": "node test/compare.test.mjs && node test/check-updates.test.mjs && node test/skills-install.test.mjs && node test/doctor.test.mjs && node --test test/merge-refs.test.mjs test/registry-credentials.test.mjs"
71
71
  },
72
72
  "dependencies": {
73
- "@vegastack/design-tokens": "^0.8.3",
73
+ "@vegastack/design-tokens": "^0.8.12",
74
74
  "clsx": "^2.1.1",
75
75
  "tailwind-merge": "^3.6.0",
76
76
  "tsconfig-paths": "^4.2.0",
@@ -3,7 +3,7 @@
3
3
  <!-- GENERATED — do not hand-edit. Regenerated from the design system's component contract,
4
4
  which is the authority for membership and counts. -->
5
5
 
6
- **160 components**, plus 467 animated-icon items, 15 hooks (`use-animation-replay`, `use-announcer`, `use-async-search`, `use-drag-reorder`, `use-file-drop`, `use-inline-edit`, `use-list-nav`, `use-media-query`, `use-mobile`, `use-modal-inert`, `use-optimistic-action`, `use-overflow`, `use-platform`, `use-tabs-swipe`, `use-view-transition`), 15 starter blocks (`app-shell-01`, `board-01`, `issue-detail-01`, `page-editor-01`, `command-search-01`, `list-page-01`, `library-01`, `login-01`, `notifications-01`, `review-split-01`, `settings-01`, `settings-02`, `status-pages-01`, `email-kit`, `share-01`), 68 chart blocks across 7 families, and 19 data libs (`code-highlight`, `date-time`, `geo-data`, `emoji-data`, `drag-item`, `text-anchor`, `text-anchor-doc`, `text-edit-grammar`, `text-edit-schema`, `text-edit-markdown`, `file-kind`, `upload-progress`, `media-probe`, `page-layout`, `tile-overlay`, `icon-data`, `icon-components`, `picker-search`, `picker-preferences`) — 744 registry items in total.
6
+ **161 components**, plus 467 animated-icon items, 15 hooks (`use-animation-replay`, `use-announcer`, `use-async-search`, `use-drag-reorder`, `use-file-drop`, `use-inline-edit`, `use-list-nav`, `use-media-query`, `use-mobile`, `use-modal-inert`, `use-optimistic-action`, `use-overflow`, `use-platform`, `use-tabs-swipe`, `use-view-transition`), 15 starter blocks (`app-shell-01`, `board-01`, `issue-detail-01`, `page-editor-01`, `command-search-01`, `list-page-01`, `library-01`, `login-01`, `notifications-01`, `review-split-01`, `settings-01`, `settings-02`, `status-pages-01`, `email-kit`, `share-01`), 68 chart blocks across 7 families, and 19 data libs (`code-highlight`, `date-time`, `geo-data`, `emoji-data`, `drag-item`, `text-anchor`, `text-anchor-doc`, `text-edit-grammar`, `text-edit-schema`, `text-edit-markdown`, `file-kind`, `upload-progress`, `media-probe`, `page-layout`, `tile-overlay`, `icon-data`, `icon-components`, `picker-search`, `picker-preferences`) — 745 registry items in total.
7
7
 
8
8
  Install any of them with `shadcn add @vegastack/<name>`. Animated icons install as
9
9
  `@vegastack/icon-<name>`; the bare name is reserved for components, so a component whose name
@@ -82,7 +82,7 @@ starts with `icon-` is a component and never an icon.
82
82
  - **`inline-chip`** — The one inline reference in running text — a person, page, file, task, meeting, customer or project — on the text's baseline at its size, tinted by kind; a person previews avatar, name and email on hover, the rest open on click with ⌘-click for a new tab.
83
83
  - **`item`** — A composable row for list and feed content — media, title, description, actions — with a highlighted flash for a just-changed row.
84
84
  - **`kbd`** — A keyboard-key chip, and a group that lays several of them out inline.
85
- - **`markdown-view`** — Render a markdown string to safe, token-styled HTML — headings (with optional ids), lists, code, blockquotes, links, GFM tables, mention and file chips, callouts and toggles — XSS-safe, no raw HTML.
85
+ - **`markdown-view`** — Render a markdown string to safe, token-styled HTML — headings (with optional ids and copy links), lists, code, blockquotes, links, GFM tables that fade at a scrolling edge, mention and file chips, callouts and toggles — XSS-safe; at the document type scale, a page's read view with comment highlights, an outline, per-reader toggles and find.
86
86
  - **`priority-icon`** — A flag marking priority — urgent, high, medium, low, none — each in a semantic color with filled, outline or dashed fill.
87
87
  - **`relative-time`** — One Intl-based dates & times module — formatRelative, formatDuration, formatDate, formatDateTime, formatDateRange, formatTimeOfDay, formatDueLabel, groupByDay, time-zone cookie + provider — and the RelativeTime, DateTime, Duration and DueLabel components with absolute-time tooltips.
88
88
  - **`status-icon`** — A small workflow status icon in Linear's set — backlog, todo, in progress, in review, done, canceled, duplicate, triage — each a hand-drawn 16-unit glyph in a semantic color.
@@ -165,6 +165,7 @@ starts with `icon-` is a component and never an icon.
165
165
  - **`aspect-ratio`** — Constrains its children to a given width-to-height ratio.
166
166
  - **`board`** — Kanban lanes — full-height lanes that scroll their cards inside, sticky headers with a collapse button left of the ⋯ menu, a subtle top-down fade on each lane, + Add after the last card (the empty lane's action when it has none), Nothing here / Drop here empty zones, per-lane skeletons and load-on-scroll paging; live pointer and touch drag (lift, make room, settle, edge auto-scroll), a keyboard pick-up/move/drop model, a per-card ⋯ menu of the card's own actions, optimistic moves with rollback and a toast, and one lane at a time on a phone.
167
167
  - **`direction`** — Base UI's DirectionProvider and useDirection — the text-direction context components read.
168
+ - **`document-layout`** — A page read as a document — the title area, the text at a reading measure, what follows it, a contents column and a comment margin — on one grid with four tiers by its own width, plus its skeleton and a tier hook.
168
169
  - **`record-layout`** — A record page's main column beside a sticky right rail of cards, with an ⓘ Details sheet in its place on small screens.
169
170
  - **`resizable`** — Accessible resizable panel groups and layouts with keyboard support — horizontal or vertical, nestable, with an optional visible grip.
170
171
  - **`scroll-area`** — Augments native scroll functionality for custom, cross-browser styling — a viewport, an auto-hiding scrollbar, and a corner.