altitude-design 0.2.1 → 0.3.0

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.
Files changed (295) hide show
  1. package/README.md +41 -6
  2. package/dist/adapters/codemirror.cjs +88 -0
  3. package/dist/adapters/codemirror.cjs.map +7 -0
  4. package/dist/adapters/codemirror.js +67 -0
  5. package/dist/adapters/codemirror.js.map +7 -0
  6. package/dist/adapters/react-flow.css +102 -0
  7. package/dist/adapters/tiptap.css +71 -0
  8. package/dist/altitude.css +3121 -244
  9. package/dist/altitude.iife.js +33 -5
  10. package/dist/altitude.no-fonts.css +3121 -244
  11. package/dist/chart-themes.cjs +195 -0
  12. package/dist/chart-themes.cjs.map +7 -0
  13. package/dist/chart-themes.js +165 -0
  14. package/dist/chart-themes.js.map +7 -0
  15. package/dist/cli/altitude.mjs +134 -0
  16. package/dist/guidance/README.md +32 -0
  17. package/dist/guidance/agent-setup.md +22 -0
  18. package/dist/guidance/app-skeleton.md +17 -0
  19. package/dist/guidance/evidence.json +95 -0
  20. package/dist/guidance/index.json +493 -0
  21. package/dist/guidance/llms.txt +20 -0
  22. package/dist/guidance/manifest.json +92 -0
  23. package/dist/guidance/pattern.schema.json +181 -0
  24. package/dist/guidance/patterns/agent-action.json +77 -0
  25. package/dist/guidance/patterns/agent-action.md +39 -0
  26. package/dist/guidance/patterns/assistant-conversation.json +77 -0
  27. package/dist/guidance/patterns/assistant-conversation.md +50 -0
  28. package/dist/guidance/patterns/async-collection.json +71 -0
  29. package/dist/guidance/patterns/async-collection.md +29 -0
  30. package/dist/guidance/patterns/audit-log.json +75 -0
  31. package/dist/guidance/patterns/audit-log.md +27 -0
  32. package/dist/guidance/patterns/auth.json +86 -0
  33. package/dist/guidance/patterns/auth.md +29 -0
  34. package/dist/guidance/patterns/billing.json +80 -0
  35. package/dist/guidance/patterns/billing.md +29 -0
  36. package/dist/guidance/patterns/consequential-action.json +76 -0
  37. package/dist/guidance/patterns/consequential-action.md +27 -0
  38. package/dist/guidance/patterns/developer-settings.json +79 -0
  39. package/dist/guidance/patterns/developer-settings.md +29 -0
  40. package/dist/guidance/patterns/edit-record.json +74 -0
  41. package/dist/guidance/patterns/edit-record.md +51 -0
  42. package/dist/guidance/patterns/import.json +77 -0
  43. package/dist/guidance/patterns/import.md +31 -0
  44. package/dist/guidance/patterns/members.json +77 -0
  45. package/dist/guidance/patterns/members.md +27 -0
  46. package/dist/guidance/patterns/onboarding.json +78 -0
  47. package/dist/guidance/patterns/onboarding.md +31 -0
  48. package/dist/guidance/patterns/review-submit.json +72 -0
  49. package/dist/guidance/patterns/review-submit.md +27 -0
  50. package/dist/guidance/patterns/screen-layout.json +79 -0
  51. package/dist/guidance/patterns/screen-layout.md +40 -0
  52. package/dist/guidance/patterns/settings.json +78 -0
  53. package/dist/guidance/patterns/settings.md +32 -0
  54. package/dist/guidance/patterns/sync.json +77 -0
  55. package/dist/guidance/patterns/sync.md +31 -0
  56. package/dist/guidance/principles.md +23 -0
  57. package/dist/guidance/references/build/checks/agent-action-pattern.mjs +57 -0
  58. package/dist/guidance/references/build/checks/agent-setup.mjs +78 -0
  59. package/dist/guidance/references/build/checks/assistant-conversation-pattern.mjs +49 -0
  60. package/dist/guidance/references/build/checks/audit-log-pattern.mjs +63 -0
  61. package/dist/guidance/references/build/checks/auth-pattern.mjs +67 -0
  62. package/dist/guidance/references/build/checks/billing-pattern.mjs +63 -0
  63. package/dist/guidance/references/build/checks/developer-settings-pattern.mjs +76 -0
  64. package/dist/guidance/references/build/checks/guidance.mjs +71 -0
  65. package/dist/guidance/references/build/checks/import-pattern.mjs +69 -0
  66. package/dist/guidance/references/build/checks/members-pattern.mjs +71 -0
  67. package/dist/guidance/references/build/checks/onboarding-pattern.mjs +54 -0
  68. package/dist/guidance/references/build/checks/pattern-types.mjs +13 -0
  69. package/dist/guidance/references/build/checks/pattern-workflows.mjs +226 -0
  70. package/dist/guidance/references/build/checks/primary-scope.mjs +49 -0
  71. package/dist/guidance/references/build/checks/render-tells.mjs +72 -0
  72. package/dist/guidance/references/build/checks/screen-layout-pattern.mjs +111 -0
  73. package/dist/guidance/references/build/checks/semantics.mjs +72 -0
  74. package/dist/guidance/references/build/checks/settings-pattern.mjs +73 -0
  75. package/dist/guidance/references/build/checks/sync-pattern.mjs +62 -0
  76. package/dist/guidance/references/build/checks/tells-lint.mjs +164 -0
  77. package/dist/guidance/references/build/fixtures/pattern-workflows.tsx +83 -0
  78. package/dist/guidance/references/build/fixtures/patterns/agent-action.jsx +60 -0
  79. package/dist/guidance/references/build/fixtures/patterns/app-skeleton.jsx +94 -0
  80. package/dist/guidance/references/build/fixtures/patterns/assistant-conversation.jsx +79 -0
  81. package/dist/guidance/references/build/fixtures/patterns/audit-log.jsx +81 -0
  82. package/dist/guidance/references/build/fixtures/patterns/auth.jsx +150 -0
  83. package/dist/guidance/references/build/fixtures/patterns/billing.jsx +96 -0
  84. package/dist/guidance/references/build/fixtures/patterns/developer-settings.jsx +95 -0
  85. package/dist/guidance/references/build/fixtures/patterns/import.jsx +102 -0
  86. package/dist/guidance/references/build/fixtures/patterns/members.jsx +106 -0
  87. package/dist/guidance/references/build/fixtures/patterns/onboarding.jsx +70 -0
  88. package/dist/guidance/references/build/fixtures/patterns/screen-layout-decision.jsx +74 -0
  89. package/dist/guidance/references/build/fixtures/patterns/screen-layout-editor.jsx +56 -0
  90. package/dist/guidance/references/build/fixtures/patterns/screen-layout-report.jsx +42 -0
  91. package/dist/guidance/references/build/fixtures/patterns/settings.jsx +73 -0
  92. package/dist/guidance/references/build/fixtures/patterns/sync.jsx +78 -0
  93. package/dist/guidance/references/project/components/src/pattern-async-collection.tsx +57 -0
  94. package/dist/guidance/references/project/components/src/pattern-consequential-action.tsx +77 -0
  95. package/dist/guidance/references/project/components/src/pattern-edit-record.tsx +127 -0
  96. package/dist/guidance/references/project/components/src/pattern-review-submit.tsx +47 -0
  97. package/dist/guidance/references/project/components/src/settings.tsx +79 -0
  98. package/dist/guidance/references/scripts/build-framework-fixture.mjs +20 -0
  99. package/dist/guidance/rules.json +653 -0
  100. package/dist/guidance/visual/Elevation.md +194 -0
  101. package/dist/guidance/visual/Fundamentals.md +83 -0
  102. package/dist/guidance/visual/Research.md +1620 -0
  103. package/dist/index.cjs +18792 -1925
  104. package/dist/index.cjs.map +4 -4
  105. package/dist/index.js +18792 -1925
  106. package/dist/index.js.map +4 -4
  107. package/dist/tokens.css +84 -84
  108. package/dist/tokens.json +301 -128
  109. package/dist/types/adapter-codemirror.d.ts +13 -0
  110. package/dist/types/agent-fleet.d.ts +166 -0
  111. package/dist/types/ai-label.d.ts +30 -0
  112. package/dist/types/app-shell.d.ts +83 -0
  113. package/dist/types/area-chart.d.ts +80 -0
  114. package/dist/types/artifact.d.ts +65 -0
  115. package/dist/types/bar-chart.d.ts +83 -0
  116. package/dist/types/bar-list.d.ts +35 -0
  117. package/dist/types/breadcrumb.d.ts +62 -0
  118. package/dist/types/chart-brush.d.ts +35 -0
  119. package/dist/types/chart-themes.d.ts +229 -0
  120. package/dist/types/chart.d.ts +570 -0
  121. package/dist/types/checklist.d.ts +71 -0
  122. package/dist/types/code-block.d.ts +32 -0
  123. package/dist/types/collections.d.ts +111 -4
  124. package/dist/types/color-picker.d.ts +38 -0
  125. package/dist/types/command.d.ts +6 -3
  126. package/dist/types/comment-thread.d.ts +48 -0
  127. package/dist/types/confirmation.d.ts +60 -0
  128. package/dist/types/context-menu.d.ts +17 -0
  129. package/dist/types/controls.d.ts +100 -17
  130. package/dist/types/conversation.d.ts +130 -0
  131. package/dist/types/copy-button.d.ts +19 -0
  132. package/dist/types/core.d.ts +139 -10
  133. package/dist/types/data-grid.d.ts +76 -0
  134. package/dist/types/date-picker.d.ts +96 -0
  135. package/dist/types/diff-view.d.ts +54 -0
  136. package/dist/types/dot-plot.d.ts +54 -0
  137. package/dist/types/edit-region.d.ts +121 -0
  138. package/dist/types/feature-gate.d.ts +22 -0
  139. package/dist/types/filter-bar.d.ts +65 -0
  140. package/dist/types/formatted-number.d.ts +38 -0
  141. package/dist/types/heatmap.d.ts +64 -0
  142. package/dist/types/in-place.d.ts +24 -0
  143. package/dist/types/index.d.ts +158 -15
  144. package/dist/types/inline-citation.d.ts +35 -0
  145. package/dist/types/inline-edit.d.ts +71 -0
  146. package/dist/types/input-otp.d.ts +37 -0
  147. package/dist/types/item-group.d.ts +104 -0
  148. package/dist/types/line-chart.d.ts +116 -0
  149. package/dist/types/link.d.ts +11 -0
  150. package/dist/types/markdown.d.ts +88 -0
  151. package/dist/types/meter.d.ts +43 -0
  152. package/dist/types/modal-state.d.ts +62 -0
  153. package/dist/types/nav.d.ts +8 -1
  154. package/dist/types/notifications.d.ts +42 -0
  155. package/dist/types/number-input.d.ts +30 -0
  156. package/dist/types/overlays.d.ts +51 -17
  157. package/dist/types/page-header.d.ts +27 -0
  158. package/dist/types/pagination.d.ts +29 -0
  159. package/dist/types/palette.d.ts +64 -0
  160. package/dist/types/password-input.d.ts +22 -0
  161. package/dist/types/pattern-assistant-conversation.d.ts +55 -0
  162. package/dist/types/pattern-async-collection.d.ts +34 -0
  163. package/dist/types/pattern-consequential-action.d.ts +53 -0
  164. package/dist/types/pattern-edit-record.d.ts +72 -0
  165. package/dist/types/pattern-review-submit.d.ts +43 -0
  166. package/dist/types/permission-matrix.d.ts +34 -0
  167. package/dist/types/plan-picker.d.ts +40 -0
  168. package/dist/types/prompt-input.d.ts +106 -0
  169. package/dist/types/property-list.d.ts +67 -0
  170. package/dist/types/question.d.ts +64 -0
  171. package/dist/types/relative-time.d.ts +21 -0
  172. package/dist/types/removal-receipt.d.ts +1180 -0
  173. package/dist/types/resizable.d.ts +48 -0
  174. package/dist/types/roving.d.ts +44 -0
  175. package/dist/types/save-bar.d.ts +38 -0
  176. package/dist/types/saved-views.d.ts +72 -0
  177. package/dist/types/scatter-chart.d.ts +60 -0
  178. package/dist/types/schedule.d.ts +80 -0
  179. package/dist/types/secret-field.d.ts +33 -0
  180. package/dist/types/select.d.ts +44 -2
  181. package/dist/types/separator.d.ts +11 -0
  182. package/dist/types/settings.d.ts +39 -0
  183. package/dist/types/sheet.d.ts +1 -1
  184. package/dist/types/sparkline.d.ts +46 -0
  185. package/dist/types/split-button.d.ts +21 -0
  186. package/dist/types/stat.d.ts +54 -0
  187. package/dist/types/stepper.d.ts +6 -3
  188. package/dist/types/suggestions.d.ts +29 -0
  189. package/dist/types/suspense.d.ts +12 -1
  190. package/dist/types/sync-indicator.d.ts +24 -0
  191. package/dist/types/tag-input.d.ts +65 -0
  192. package/dist/types/terminal.d.ts +33 -0
  193. package/dist/types/thread-list.d.ts +58 -0
  194. package/dist/types/time-input.d.ts +33 -0
  195. package/dist/types/timeline.d.ts +38 -0
  196. package/dist/types/toggle.d.ts +46 -0
  197. package/dist/types/toolbar.d.ts +34 -0
  198. package/dist/types/tour.d.ts +23 -0
  199. package/dist/types/trace.d.ts +65 -0
  200. package/dist/types/tree.d.ts +71 -0
  201. package/dist/types-cjs/adapter-codemirror.d.cts +13 -0
  202. package/dist/types-cjs/agent-fleet.d.cts +166 -0
  203. package/dist/types-cjs/ai-label.d.cts +30 -0
  204. package/dist/types-cjs/app-shell.d.cts +83 -0
  205. package/dist/types-cjs/area-chart.d.cts +80 -0
  206. package/dist/types-cjs/artifact.d.cts +65 -0
  207. package/dist/types-cjs/bar-chart.d.cts +83 -0
  208. package/dist/types-cjs/bar-list.d.cts +35 -0
  209. package/dist/types-cjs/breadcrumb.d.cts +62 -0
  210. package/dist/types-cjs/chart-brush.d.cts +35 -0
  211. package/dist/types-cjs/chart-themes.d.cts +229 -0
  212. package/dist/types-cjs/chart.d.cts +570 -0
  213. package/dist/types-cjs/checklist.d.cts +71 -0
  214. package/dist/types-cjs/code-block.d.cts +32 -0
  215. package/dist/types-cjs/collections.d.cts +246 -0
  216. package/dist/types-cjs/color-picker.d.cts +38 -0
  217. package/dist/types-cjs/command.d.cts +66 -0
  218. package/dist/types-cjs/comment-thread.d.cts +48 -0
  219. package/dist/types-cjs/confirmation.d.cts +60 -0
  220. package/dist/types-cjs/context-menu.d.cts +17 -0
  221. package/dist/types-cjs/controls.d.cts +360 -0
  222. package/dist/types-cjs/conversation.d.cts +130 -0
  223. package/dist/types-cjs/copy-button.d.cts +19 -0
  224. package/dist/types-cjs/core.d.cts +256 -0
  225. package/dist/types-cjs/data-grid.d.cts +76 -0
  226. package/dist/types-cjs/date-picker.d.cts +96 -0
  227. package/dist/types-cjs/diff-view.d.cts +54 -0
  228. package/dist/types-cjs/dot-plot.d.cts +54 -0
  229. package/dist/types-cjs/edit-region.d.cts +121 -0
  230. package/dist/types-cjs/empty.d.cts +24 -0
  231. package/dist/types-cjs/feature-gate.d.cts +22 -0
  232. package/dist/types-cjs/filter-bar.d.cts +65 -0
  233. package/dist/types-cjs/formatted-number.d.cts +38 -0
  234. package/dist/types-cjs/heatmap.d.cts +64 -0
  235. package/dist/types-cjs/in-place.d.cts +24 -0
  236. package/dist/types-cjs/index.d.cts +154 -0
  237. package/dist/types-cjs/inline-citation.d.cts +35 -0
  238. package/dist/types-cjs/inline-edit.d.cts +71 -0
  239. package/dist/types-cjs/input-otp.d.cts +37 -0
  240. package/dist/types-cjs/item-group.d.cts +104 -0
  241. package/dist/types-cjs/line-chart.d.cts +116 -0
  242. package/dist/types-cjs/link.d.cts +11 -0
  243. package/dist/types-cjs/markdown.d.cts +88 -0
  244. package/dist/types-cjs/meter.d.cts +43 -0
  245. package/dist/types-cjs/modal-state.d.cts +62 -0
  246. package/dist/types-cjs/nav.d.cts +25 -0
  247. package/dist/types-cjs/notifications.d.cts +42 -0
  248. package/dist/types-cjs/number-input.d.cts +30 -0
  249. package/dist/types-cjs/overlays.d.cts +170 -0
  250. package/dist/types-cjs/page-header.d.cts +27 -0
  251. package/dist/types-cjs/pagination.d.cts +29 -0
  252. package/dist/types-cjs/palette.d.cts +64 -0
  253. package/dist/types-cjs/password-input.d.cts +22 -0
  254. package/dist/types-cjs/pattern-assistant-conversation.d.cts +55 -0
  255. package/dist/types-cjs/pattern-async-collection.d.cts +34 -0
  256. package/dist/types-cjs/pattern-consequential-action.d.cts +53 -0
  257. package/dist/types-cjs/pattern-edit-record.d.cts +72 -0
  258. package/dist/types-cjs/pattern-review-submit.d.cts +43 -0
  259. package/dist/types-cjs/permission-matrix.d.cts +34 -0
  260. package/dist/types-cjs/pile.d.cts +27 -0
  261. package/dist/types-cjs/plan-picker.d.cts +40 -0
  262. package/dist/types-cjs/prompt-input.d.cts +106 -0
  263. package/dist/types-cjs/property-list.d.cts +67 -0
  264. package/dist/types-cjs/question.d.cts +64 -0
  265. package/dist/types-cjs/relative-time.d.cts +21 -0
  266. package/dist/types-cjs/removal-receipt.d.cts +1180 -0
  267. package/dist/types-cjs/resizable.d.cts +48 -0
  268. package/dist/types-cjs/roving.d.cts +44 -0
  269. package/dist/types-cjs/save-bar.d.cts +38 -0
  270. package/dist/types-cjs/saved-views.d.cts +72 -0
  271. package/dist/types-cjs/scatter-chart.d.cts +60 -0
  272. package/dist/types-cjs/schedule.d.cts +80 -0
  273. package/dist/types-cjs/secret-field.d.cts +33 -0
  274. package/dist/types-cjs/select.d.cts +109 -0
  275. package/dist/types-cjs/separator.d.cts +11 -0
  276. package/dist/types-cjs/settings.d.cts +39 -0
  277. package/dist/types-cjs/sheet.d.cts +27 -0
  278. package/dist/types-cjs/sparkline.d.cts +46 -0
  279. package/dist/types-cjs/split-button.d.cts +21 -0
  280. package/dist/types-cjs/stat.d.cts +54 -0
  281. package/dist/types-cjs/stepper.d.cts +26 -0
  282. package/dist/types-cjs/suggestions.d.cts +29 -0
  283. package/dist/types-cjs/suspense.d.cts +85 -0
  284. package/dist/types-cjs/sync-indicator.d.cts +24 -0
  285. package/dist/types-cjs/tag-input.d.cts +65 -0
  286. package/dist/types-cjs/terminal.d.cts +33 -0
  287. package/dist/types-cjs/thread-list.d.cts +58 -0
  288. package/dist/types-cjs/time-input.d.cts +33 -0
  289. package/dist/types-cjs/timeline.d.cts +38 -0
  290. package/dist/types-cjs/toggle.d.cts +46 -0
  291. package/dist/types-cjs/toolbar.d.cts +34 -0
  292. package/dist/types-cjs/tour.d.cts +23 -0
  293. package/dist/types-cjs/trace.d.cts +65 -0
  294. package/dist/types-cjs/tree.d.cts +71 -0
  295. package/package.json +89 -9
package/README.md CHANGED
@@ -1,10 +1,10 @@
1
1
  # Altitude
2
2
 
3
- A React component library where **height is the interface**. Its one idea: the ground is the record. Settled content sits on the ground; anything live rises above it; anything waiting to receive sinks below it.
3
+ A design and HCI framework for agent-built React web applications, with a component foundation where **height is the interface**. Its one idea: the ground is the record. Settled content sits on the ground; anything live rises above it; anything waiting to receive sinks below it.
4
4
 
5
5
  - **Site:** https://richlaconte.github.io/altitude/
6
- - **Storybook:** every component, with its guidelines and a live preview in all four schemes: https://richlaconte.github.io/altitude/storybook/
7
- - **The design guide:** [`project/README.md`](https://github.com/richlaconte/altitude/blob/main/project/README.md), then [Elevation](https://github.com/richlaconte/altitude/blob/main/project/Elevation.md), [Motion](https://github.com/richlaconte/altitude/blob/main/project/Motion.md), [Theming](https://github.com/richlaconte/altitude/blob/main/project/Theming.md) and [Research](https://github.com/richlaconte/altitude/blob/main/project/Research.md)
6
+ - **Storybook:** every component, with its guidelines and a live preview in both schemes: https://richlaconte.github.io/altitude/storybook/
7
+ - **The design guide:** [`project/README.md`](https://github.com/richlaconte/altitude/blob/main/project/README.md), then [Elevation](https://github.com/richlaconte/altitude/blob/main/project/Elevation.md), [Motion](https://github.com/richlaconte/altitude/blob/main/project/Motion.md), [Charts](https://github.com/richlaconte/altitude/blob/main/project/Charts.md), [Theming](https://github.com/richlaconte/altitude/blob/main/project/Theming.md), [Fundamentals](https://github.com/richlaconte/altitude/blob/main/project/Fundamentals.md), [Distinctiveness](https://github.com/richlaconte/altitude/blob/main/project/Distinctiveness.md) and [Research](https://github.com/richlaconte/altitude/blob/main/project/Research.md)
8
8
 
9
9
  ## Install
10
10
 
@@ -28,7 +28,7 @@ export function App() {
28
28
  }
29
29
  ```
30
30
 
31
- Render `AltitudeProvider` once around your app. Schemes are `daylight`, `nightfall`, `mesa` and `alpine`; `accent="#0f8a6b"` swaps in your own colour. The components are client components (`"use client"`), so they work in frameworks with server components.
31
+ Render `AltitudeProvider` once around your app. Schemes are `daylight` and `nightfall`; `accent="#0f8a6b"` swaps in your own colour. The components are client components (`"use client"`), so they work in frameworks with server components.
32
32
 
33
33
  | Import | What it is |
34
34
  |---|---|
@@ -52,6 +52,18 @@ site/ the landing page (React, built from the components' own sources into
52
52
 
53
53
  There is one source for each thing. Components live in `project/components/src`, styles in `project/components/bundle.css`, tokens in `project/tokens.json`, and each component's preview in `build/previews.txt`. The npm package, the Storybook stories and the design system's own previews are all generated from those.
54
54
 
55
+ ## Actions in place
56
+
57
+ [Actions in place](project/ActionsInPlace.md) covers single-value editing with `InlineEdit`, direct actions with real recovery, and targeted confirmation with `Dialog background="stationary"`.
58
+
59
+ After `npm run storybook`, open the generated examples:
60
+
61
+ - [Inline editing and its comparison baseline](http://localhost:6006/?path=/story/inputs-inlineedit--preview).
62
+ - [Default and stationary dialog presentation](http://localhost:6006/?path=/story/overlays-dialog--preview).
63
+ - [Act and recover](http://localhost:6006/?path=/story/patterns-actionsinplace--preview). “Open complete Files example” selects the same example's `#files` view.
64
+
65
+ The [validation record](project/ActionsInPlaceValidation.md) separates engineering checks from outstanding human evaluation.
66
+
55
67
  ## Working on it
56
68
 
57
69
  ```sh
@@ -70,7 +82,7 @@ CI fails if `project/` doesn't match its sources, so the design system on claude
70
82
 
71
83
  ## What happens on push
72
84
 
73
- Every push and pull request runs the checks: the bundle and previews are rebuilt and must match what's committed, every preview is rendered in all four schemes with no errors, the interaction checks run, the sources type-check against React 19, and the package and Storybook are built.
85
+ Every push and pull request runs the checks: the bundle and previews are rebuilt and must match what's committed, every preview is rendered in both schemes with no errors, the interaction checks run, the sources type-check against React 19, and the package and Storybook are built.
74
86
 
75
87
  A push to `main` then also:
76
88
 
@@ -79,7 +91,7 @@ A push to `main` then also:
79
91
 
80
92
  ## Found a bug, or need something it doesn't do?
81
93
 
82
- Open an issue: **https://github.com/richlaconte/altitude/issues/new/choose**. There are templates for a bug, a new feature for an existing component, and a new component, and [CONTRIBUTING.md](https://github.com/richlaconte/altitude/blob/main/CONTRIBUTING.md) says what makes each one useful.
94
+ Open an issue: **https://github.com/richlaconte/altitude/issues/new/choose**. There are templates for a bug, a new feature for an existing component, and a new component, and [CONTRIBUTING.md](https://github.com/richlaconte/altitude/blob/main/CONTRIBUTING.md) says what makes each one useful, and how work is organised (milestones, priorities, the `ready` label and claiming an issue with a draft pull request).
83
95
 
84
96
  **If you're an agent using this package** in someone else's project, you're welcome to report problems with it here:
85
97
 
@@ -93,3 +105,26 @@ The full guidance for agents is in [AGENTS.md](https://github.com/richlaconte/al
93
105
  ## License
94
106
 
95
107
  [MIT](https://github.com/richlaconte/altitude/blob/main/LICENSE)
108
+
109
+ ## Design and HCI framework
110
+
111
+ Altitude now joins its component library with task guidance and small workflow APIs for forms, data and processes. The four initial patterns are **edit record**, **async collection**, **consequential action**, and **review and submit**. They are experimental: engineering fixtures cover their contracts; user-effectiveness studies remain outstanding.
112
+
113
+ ```sh
114
+ npm install altitude-design
115
+ npx altitude patterns "edit settings"
116
+ npx altitude init --client codex # preview exact changes
117
+ npx altitude init --client codex --apply # apply after reviewing the preview
118
+ # Claude Code: --client claude. Both: --client all.
119
+ npx altitude doctor --json
120
+ ```
121
+
122
+ Setup preserves existing instructions and adds a small versioned pointer to the installed guidance. It never runs on package installation. Preview removal with `npx altitude init --client codex --remove`, then add `--apply` to remove only its managed content. Edited blocks are preserved and require reconciliation. Codex uses a nonempty root `AGENTS.override.md` when present; otherwise `AGENTS.md`. Claude Code uses `CLAUDE.md`. Restart the client after setup. See [setup details](docs/framework/AGENT-SETUP.md).
123
+
124
+ The compact entry is `node_modules/altitude-design/dist/guidance/README.md`; the public `altitude-design/guidance` export resolves its versioned JSON index, and `altitude-design/guidance/*` exposes focused resources. `altitude explain ALT-EDIT-001` explains a rule, its scope, evidence and verification. Guidance is local and version matched; no hosted service or MCP connection is required.
125
+
126
+ Import `useEditRecord`, `ErrorSummary`, `WorkflowStatus`, `useAsyncCollection`, `useConsequentialAction` and `useReviewSubmit` from the existing `altitude-design` entry. They share the existing provider/context. [Task contracts and examples](project/framework/README.md) explain application adapters and the corresponding [interactive previews](https://richlaconte.github.io/altitude/storybook/?path=/story/patterns-editrecord--preview).
127
+
128
+ Framework behavior protects drafts, coordinates applicable states, guards duplicate dispatch and stale responses, and supports accessible error navigation and status feedback. Applications still supply truthful persistence, permissions, business rules, query/history policy, durable recovery and actual undo. `doctor` diagnoses installation and setup; it does not certify accessibility or usability. [Manual review](docs/framework/MANUAL-VALIDATION.md), [migration notes](docs/framework/RELEASE-NOTES.md) and the [evaluation protocol](evals/framework/README.md) state the remaining work.
129
+
130
+ Run `npm run build && npm run check:framework` for deterministic semantics, workflow, guidance and packed-package consumer checks. Run agent comparisons separately using the evaluation harness; stochastic model behavior does not gate ordinary CI.
@@ -0,0 +1,88 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // project/components/src/adapter-codemirror.tsx
21
+ var adapter_codemirror_exports = {};
22
+ __export(adapter_codemirror_exports, {
23
+ altitudeEditorTheme: () => altitudeEditorTheme,
24
+ altitudeHighlightStyle: () => altitudeHighlightStyle,
25
+ altitudeTheme: () => altitudeTheme
26
+ });
27
+ module.exports = __toCommonJS(adapter_codemirror_exports);
28
+ var import_view = require("@codemirror/view");
29
+ var import_language = require("@codemirror/language");
30
+ var import_highlight = require("@lezer/highlight");
31
+ var wall = "inset 0 4px 0 0 var(--alt-wall-in), inset 0 7px 3px -2px var(--alt-cast), 0 1px 0 0 var(--alt-lip)";
32
+ var altitudeEditorTheme = import_view.EditorView.theme({
33
+ "&": {
34
+ color: "var(--ink)",
35
+ backgroundColor: "var(--surface-well)",
36
+ border: "1px solid var(--line-control)",
37
+ borderRadius: "var(--radius-md)",
38
+ boxShadow: wall,
39
+ outline: "1px solid transparent"
40
+ },
41
+ "&:hover": { borderColor: "var(--ink-muted)" },
42
+ "&.cm-focused": { outline: "1px solid transparent", backgroundColor: "var(--surface-raised)" },
43
+ "&:has(.cm-content:focus-visible)": { borderColor: "var(--alt-rim-held)", outlineColor: "var(--alt-rim-held)" },
44
+ ".cm-scroller": { fontFamily: "var(--font-mono)", fontSize: "13px", lineHeight: "20px", paddingTop: "4px" },
45
+ ".cm-content": { caretColor: "var(--ink)", padding: "var(--space-2) 0" },
46
+ ".cm-line": { padding: "0 var(--space-3)" },
47
+ ".cm-cursor, .cm-dropCursor": { borderLeftColor: "var(--ink)", borderLeftWidth: "2px" },
48
+ ".cm-gutters": { backgroundColor: "transparent", color: "var(--ink-muted)", border: "none", borderRight: "1px solid var(--line)" },
49
+ ".cm-lineNumbers .cm-gutterElement": { padding: "0 var(--space-2) 0 var(--space-3)" },
50
+ ".cm-activeLine": { backgroundColor: "color-mix(in oklab, var(--accent-soft) 60%, transparent)" },
51
+ ".cm-activeLineGutter": { backgroundColor: "transparent", color: "var(--ink)" },
52
+ "&.cm-focused > .cm-scroller > .cm-selectionLayer .cm-selectionBackground, .cm-selectionBackground, .cm-content ::selection": { backgroundColor: "color-mix(in oklab, var(--accent-ink) 24%, transparent)" },
53
+ ".cm-matchingBracket, &.cm-focused .cm-matchingBracket": { backgroundColor: "transparent", outline: "1px solid var(--accent-ink)", borderRadius: "2px" },
54
+ ".cm-searchMatch": { backgroundColor: "color-mix(in oklab, var(--caution) 22%, transparent)", outline: "1px solid var(--caution)" },
55
+ ".cm-placeholder": { color: "var(--ink-muted)" },
56
+ ".cm-lintRange-error": { backgroundImage: "none", textDecoration: "underline wavy var(--critical)", textUnderlineOffset: "3px" },
57
+ ".cm-lintRange-warning": { backgroundImage: "none", textDecoration: "underline wavy var(--caution)", textUnderlineOffset: "3px" },
58
+ ".cm-lint-marker": { width: "12px", height: "12px", borderRadius: "3px", backgroundImage: "none !important" },
59
+ ".cm-lint-marker-error": { backgroundColor: "var(--critical-soft)", boxShadow: "var(--trench), inset 0 0 0 1px var(--critical)" },
60
+ ".cm-lint-marker-warning": { backgroundColor: "var(--caution-soft)", boxShadow: "inset 0 0 0 1px var(--caution)" },
61
+ ".cm-diagnostic": { padding: "var(--space-1) var(--space-3)", font: "500 13px/18px var(--font-sans)", color: "var(--ink)" },
62
+ ".cm-diagnostic-error": { borderLeft: "3px solid var(--critical)" },
63
+ ".cm-diagnostic-warning": { borderLeft: "3px solid var(--caution)" },
64
+ ".cm-tooltip": { border: "none", borderRadius: "var(--radius-md)", backgroundColor: "var(--surface-floating)", color: "var(--ink)", boxShadow: "var(--elev-3)", overflow: "hidden" },
65
+ ".cm-tooltip-autocomplete > ul": { fontFamily: "var(--font-mono)", fontSize: "13px" },
66
+ ".cm-tooltip-autocomplete > ul > li": { padding: "4px var(--space-2)" },
67
+ ".cm-tooltip-autocomplete > ul > li[aria-selected]": { backgroundColor: "var(--accent-soft)", color: "var(--ink)" },
68
+ ".cm-panels": { backgroundColor: "var(--surface-ground)", color: "var(--ink)" },
69
+ ".cm-panels.cm-panels-bottom": { borderTop: "1px solid var(--line)" },
70
+ ".cm-panels.cm-panels-top": { borderBottom: "1px solid var(--line)" },
71
+ ".cm-foldPlaceholder": { backgroundColor: "var(--surface-raised)", border: "1px solid var(--line)", color: "var(--ink-muted)" },
72
+ // Nothing here moves, so reduced motion needs no rule: the editor changes state without transitions.
73
+ "@media (forced-colors: active)": { ".cm-lint-marker-error": { border: "2px dashed CanvasText" }, ".cm-tooltip": { border: "1px solid CanvasText" } }
74
+ });
75
+ var altitudeHighlightStyle = import_language.HighlightStyle.define([
76
+ { tag: [import_highlight.tags.keyword, import_highlight.tags.operatorKeyword, import_highlight.tags.modifier, import_highlight.tags.controlKeyword], color: "var(--accent-ink)", fontWeight: "600" },
77
+ { tag: [import_highlight.tags.number, import_highlight.tags.bool, import_highlight.tags.null, import_highlight.tags.atom], color: "var(--accent-ink)" },
78
+ { tag: [import_highlight.tags.string, import_highlight.tags.special(import_highlight.tags.string), import_highlight.tags.regexp], color: "var(--ink)" },
79
+ { tag: [import_highlight.tags.propertyName, import_highlight.tags.attributeName, import_highlight.tags.definition(import_highlight.tags.variableName), import_highlight.tags.function(import_highlight.tags.variableName)], color: "var(--ink)", fontWeight: "550" },
80
+ { tag: [import_highlight.tags.comment, import_highlight.tags.lineComment, import_highlight.tags.blockComment, import_highlight.tags.docComment], color: "var(--ink-muted)", fontStyle: "italic" },
81
+ { tag: [import_highlight.tags.punctuation, import_highlight.tags.bracket, import_highlight.tags.separator, import_highlight.tags.operator], color: "var(--ink-muted)" },
82
+ { tag: [import_highlight.tags.typeName, import_highlight.tags.className, import_highlight.tags.tagName], color: "var(--accent-ink)" },
83
+ { tag: import_highlight.tags.invalid, color: "var(--critical)" }
84
+ ]);
85
+ function altitudeTheme() {
86
+ return [altitudeEditorTheme, (0, import_language.syntaxHighlighting)(altitudeHighlightStyle)];
87
+ }
88
+ //# sourceMappingURL=codemirror.cjs.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../project/components/src/adapter-codemirror.tsx"],
4
+ "sourcesContent": ["import { EditorView } from '@codemirror/view';\nimport { HighlightStyle, syntaxHighlighting } from '@codemirror/language';\nimport { tags as t } from '@lezer/highlight';\nimport type { Extension } from '@codemirror/state';\n\n/* \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 CodeMirror adapter \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n\n/*\n * altitude-design/adapters/codemirror: Altitude readings for a CodeMirror 6 editor. Every value is one of the scheme's\n * custom properties, so the editor follows the active scheme, a custom accent and contrast=\"more\" without re-creating\n * it. It imports only CodeMirror (@codemirror/view, @codemirror/language, @lezer/highlight), which your app installs.\n */\nconst wall = 'inset 0 4px 0 0 var(--alt-wall-in), inset 0 7px 3px -2px var(--alt-cast), 0 1px 0 0 var(--alt-lip)';\n\n/**\n * The editor is an opening: a well with its inside wall, the floor lit while focused and a 2px neutral rim for keyboard\n * focus. Gutter and lines are ground; the active line is a tint, never a height; the selection is accent. Lint errors\n * sink their gutter marker into a trench on critical-soft and say the problem in words. Tooltips and completion lists\n * float at level 3.\n */\nexport const altitudeEditorTheme: Extension = EditorView.theme({\n '&': { color: 'var(--ink)', backgroundColor: 'var(--surface-well)', border: '1px solid var(--line-control)', borderRadius: 'var(--radius-md)',\n boxShadow: wall, outline: '1px solid transparent' },\n '&:hover': { borderColor: 'var(--ink-muted)' },\n '&.cm-focused': { outline: '1px solid transparent', backgroundColor: 'var(--surface-raised)' },\n '&:has(.cm-content:focus-visible)': { borderColor: 'var(--alt-rim-held)', outlineColor: 'var(--alt-rim-held)' },\n '.cm-scroller': { fontFamily: 'var(--font-mono)', fontSize: '13px', lineHeight: '20px', paddingTop: '4px' },\n '.cm-content': { caretColor: 'var(--ink)', padding: 'var(--space-2) 0' },\n '.cm-line': { padding: '0 var(--space-3)' },\n '.cm-cursor, .cm-dropCursor': { borderLeftColor: 'var(--ink)', borderLeftWidth: '2px' },\n '.cm-gutters': { backgroundColor: 'transparent', color: 'var(--ink-muted)', border: 'none', borderRight: '1px solid var(--line)' },\n '.cm-lineNumbers .cm-gutterElement': { padding: '0 var(--space-2) 0 var(--space-3)' },\n '.cm-activeLine': { backgroundColor: 'color-mix(in oklab, var(--accent-soft) 60%, transparent)' },\n '.cm-activeLineGutter': { backgroundColor: 'transparent', color: 'var(--ink)' },\n '&.cm-focused > .cm-scroller > .cm-selectionLayer .cm-selectionBackground, .cm-selectionBackground, .cm-content ::selection': { backgroundColor: 'color-mix(in oklab, var(--accent-ink) 24%, transparent)' },\n '.cm-matchingBracket, &.cm-focused .cm-matchingBracket': { backgroundColor: 'transparent', outline: '1px solid var(--accent-ink)', borderRadius: '2px' },\n '.cm-searchMatch': { backgroundColor: 'color-mix(in oklab, var(--caution) 22%, transparent)', outline: '1px solid var(--caution)' },\n '.cm-placeholder': { color: 'var(--ink-muted)' },\n '.cm-lintRange-error': { backgroundImage: 'none', textDecoration: 'underline wavy var(--critical)', textUnderlineOffset: '3px' },\n '.cm-lintRange-warning': { backgroundImage: 'none', textDecoration: 'underline wavy var(--caution)', textUnderlineOffset: '3px' },\n '.cm-lint-marker': { width: '12px', height: '12px', borderRadius: '3px', backgroundImage: 'none !important' },\n '.cm-lint-marker-error': { backgroundColor: 'var(--critical-soft)', boxShadow: 'var(--trench), inset 0 0 0 1px var(--critical)' },\n '.cm-lint-marker-warning': { backgroundColor: 'var(--caution-soft)', boxShadow: 'inset 0 0 0 1px var(--caution)' },\n '.cm-diagnostic': { padding: 'var(--space-1) var(--space-3)', font: '500 13px/18px var(--font-sans)', color: 'var(--ink)' },\n '.cm-diagnostic-error': { borderLeft: '3px solid var(--critical)' },\n '.cm-diagnostic-warning': { borderLeft: '3px solid var(--caution)' },\n '.cm-tooltip': { border: 'none', borderRadius: 'var(--radius-md)', backgroundColor: 'var(--surface-floating)', color: 'var(--ink)', boxShadow: 'var(--elev-3)', overflow: 'hidden' },\n '.cm-tooltip-autocomplete > ul': { fontFamily: 'var(--font-mono)', fontSize: '13px' },\n '.cm-tooltip-autocomplete > ul > li': { padding: '4px var(--space-2)' },\n '.cm-tooltip-autocomplete > ul > li[aria-selected]': { backgroundColor: 'var(--accent-soft)', color: 'var(--ink)' },\n '.cm-panels': { backgroundColor: 'var(--surface-ground)', color: 'var(--ink)' },\n '.cm-panels.cm-panels-bottom': { borderTop: '1px solid var(--line)' },\n '.cm-panels.cm-panels-top': { borderBottom: '1px solid var(--line)' },\n '.cm-foldPlaceholder': { backgroundColor: 'var(--surface-raised)', border: '1px solid var(--line)', color: 'var(--ink-muted)' },\n // Nothing here moves, so reduced motion needs no rule: the editor changes state without transitions.\n '@media (forced-colors: active)': { '.cm-lint-marker-error': { border: '2px dashed CanvasText' }, '.cm-tooltip': { border: '1px solid CanvasText' } },\n});\n\n/** Syntax in ink, ink-muted and accent-ink only: code is text to read, not data to compare, so no data-* hues. */\nexport const altitudeHighlightStyle: HighlightStyle = HighlightStyle.define([\n { tag: [t.keyword, t.operatorKeyword, t.modifier, t.controlKeyword], color: 'var(--accent-ink)', fontWeight: '600' },\n { tag: [t.number, t.bool, t.null, t.atom], color: 'var(--accent-ink)' },\n { tag: [t.string, t.special(t.string), t.regexp], color: 'var(--ink)' },\n { tag: [t.propertyName, t.attributeName, t.definition(t.variableName), t.function(t.variableName)], color: 'var(--ink)', fontWeight: '550' },\n { tag: [t.comment, t.lineComment, t.blockComment, t.docComment], color: 'var(--ink-muted)', fontStyle: 'italic' },\n { tag: [t.punctuation, t.bracket, t.separator, t.operator], color: 'var(--ink-muted)' },\n { tag: [t.typeName, t.className, t.tagName], color: 'var(--accent-ink)' },\n { tag: t.invalid, color: 'var(--critical)' },\n]);\n\n/** The whole adapter: `new EditorView({ extensions: [altitudeTheme(), \u2026] })`. */\nexport function altitudeTheme(): Extension {\n return [altitudeEditorTheme, syntaxHighlighting(altitudeHighlightStyle)];\n}\n"],
5
+ "mappings": "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",
6
+ "names": ["t"]
7
+ }
@@ -0,0 +1,67 @@
1
+ // project/components/src/adapter-codemirror.tsx
2
+ import { EditorView } from "@codemirror/view";
3
+ import { HighlightStyle, syntaxHighlighting } from "@codemirror/language";
4
+ import { tags as t } from "@lezer/highlight";
5
+ var wall = "inset 0 4px 0 0 var(--alt-wall-in), inset 0 7px 3px -2px var(--alt-cast), 0 1px 0 0 var(--alt-lip)";
6
+ var altitudeEditorTheme = EditorView.theme({
7
+ "&": {
8
+ color: "var(--ink)",
9
+ backgroundColor: "var(--surface-well)",
10
+ border: "1px solid var(--line-control)",
11
+ borderRadius: "var(--radius-md)",
12
+ boxShadow: wall,
13
+ outline: "1px solid transparent"
14
+ },
15
+ "&:hover": { borderColor: "var(--ink-muted)" },
16
+ "&.cm-focused": { outline: "1px solid transparent", backgroundColor: "var(--surface-raised)" },
17
+ "&:has(.cm-content:focus-visible)": { borderColor: "var(--alt-rim-held)", outlineColor: "var(--alt-rim-held)" },
18
+ ".cm-scroller": { fontFamily: "var(--font-mono)", fontSize: "13px", lineHeight: "20px", paddingTop: "4px" },
19
+ ".cm-content": { caretColor: "var(--ink)", padding: "var(--space-2) 0" },
20
+ ".cm-line": { padding: "0 var(--space-3)" },
21
+ ".cm-cursor, .cm-dropCursor": { borderLeftColor: "var(--ink)", borderLeftWidth: "2px" },
22
+ ".cm-gutters": { backgroundColor: "transparent", color: "var(--ink-muted)", border: "none", borderRight: "1px solid var(--line)" },
23
+ ".cm-lineNumbers .cm-gutterElement": { padding: "0 var(--space-2) 0 var(--space-3)" },
24
+ ".cm-activeLine": { backgroundColor: "color-mix(in oklab, var(--accent-soft) 60%, transparent)" },
25
+ ".cm-activeLineGutter": { backgroundColor: "transparent", color: "var(--ink)" },
26
+ "&.cm-focused > .cm-scroller > .cm-selectionLayer .cm-selectionBackground, .cm-selectionBackground, .cm-content ::selection": { backgroundColor: "color-mix(in oklab, var(--accent-ink) 24%, transparent)" },
27
+ ".cm-matchingBracket, &.cm-focused .cm-matchingBracket": { backgroundColor: "transparent", outline: "1px solid var(--accent-ink)", borderRadius: "2px" },
28
+ ".cm-searchMatch": { backgroundColor: "color-mix(in oklab, var(--caution) 22%, transparent)", outline: "1px solid var(--caution)" },
29
+ ".cm-placeholder": { color: "var(--ink-muted)" },
30
+ ".cm-lintRange-error": { backgroundImage: "none", textDecoration: "underline wavy var(--critical)", textUnderlineOffset: "3px" },
31
+ ".cm-lintRange-warning": { backgroundImage: "none", textDecoration: "underline wavy var(--caution)", textUnderlineOffset: "3px" },
32
+ ".cm-lint-marker": { width: "12px", height: "12px", borderRadius: "3px", backgroundImage: "none !important" },
33
+ ".cm-lint-marker-error": { backgroundColor: "var(--critical-soft)", boxShadow: "var(--trench), inset 0 0 0 1px var(--critical)" },
34
+ ".cm-lint-marker-warning": { backgroundColor: "var(--caution-soft)", boxShadow: "inset 0 0 0 1px var(--caution)" },
35
+ ".cm-diagnostic": { padding: "var(--space-1) var(--space-3)", font: "500 13px/18px var(--font-sans)", color: "var(--ink)" },
36
+ ".cm-diagnostic-error": { borderLeft: "3px solid var(--critical)" },
37
+ ".cm-diagnostic-warning": { borderLeft: "3px solid var(--caution)" },
38
+ ".cm-tooltip": { border: "none", borderRadius: "var(--radius-md)", backgroundColor: "var(--surface-floating)", color: "var(--ink)", boxShadow: "var(--elev-3)", overflow: "hidden" },
39
+ ".cm-tooltip-autocomplete > ul": { fontFamily: "var(--font-mono)", fontSize: "13px" },
40
+ ".cm-tooltip-autocomplete > ul > li": { padding: "4px var(--space-2)" },
41
+ ".cm-tooltip-autocomplete > ul > li[aria-selected]": { backgroundColor: "var(--accent-soft)", color: "var(--ink)" },
42
+ ".cm-panels": { backgroundColor: "var(--surface-ground)", color: "var(--ink)" },
43
+ ".cm-panels.cm-panels-bottom": { borderTop: "1px solid var(--line)" },
44
+ ".cm-panels.cm-panels-top": { borderBottom: "1px solid var(--line)" },
45
+ ".cm-foldPlaceholder": { backgroundColor: "var(--surface-raised)", border: "1px solid var(--line)", color: "var(--ink-muted)" },
46
+ // Nothing here moves, so reduced motion needs no rule: the editor changes state without transitions.
47
+ "@media (forced-colors: active)": { ".cm-lint-marker-error": { border: "2px dashed CanvasText" }, ".cm-tooltip": { border: "1px solid CanvasText" } }
48
+ });
49
+ var altitudeHighlightStyle = HighlightStyle.define([
50
+ { tag: [t.keyword, t.operatorKeyword, t.modifier, t.controlKeyword], color: "var(--accent-ink)", fontWeight: "600" },
51
+ { tag: [t.number, t.bool, t.null, t.atom], color: "var(--accent-ink)" },
52
+ { tag: [t.string, t.special(t.string), t.regexp], color: "var(--ink)" },
53
+ { tag: [t.propertyName, t.attributeName, t.definition(t.variableName), t.function(t.variableName)], color: "var(--ink)", fontWeight: "550" },
54
+ { tag: [t.comment, t.lineComment, t.blockComment, t.docComment], color: "var(--ink-muted)", fontStyle: "italic" },
55
+ { tag: [t.punctuation, t.bracket, t.separator, t.operator], color: "var(--ink-muted)" },
56
+ { tag: [t.typeName, t.className, t.tagName], color: "var(--accent-ink)" },
57
+ { tag: t.invalid, color: "var(--critical)" }
58
+ ]);
59
+ function altitudeTheme() {
60
+ return [altitudeEditorTheme, syntaxHighlighting(altitudeHighlightStyle)];
61
+ }
62
+ export {
63
+ altitudeEditorTheme,
64
+ altitudeHighlightStyle,
65
+ altitudeTheme
66
+ };
67
+ //# sourceMappingURL=codemirror.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../project/components/src/adapter-codemirror.tsx"],
4
+ "sourcesContent": ["import { EditorView } from '@codemirror/view';\nimport { HighlightStyle, syntaxHighlighting } from '@codemirror/language';\nimport { tags as t } from '@lezer/highlight';\nimport type { Extension } from '@codemirror/state';\n\n/* \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 CodeMirror adapter \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n\n/*\n * altitude-design/adapters/codemirror: Altitude readings for a CodeMirror 6 editor. Every value is one of the scheme's\n * custom properties, so the editor follows the active scheme, a custom accent and contrast=\"more\" without re-creating\n * it. It imports only CodeMirror (@codemirror/view, @codemirror/language, @lezer/highlight), which your app installs.\n */\nconst wall = 'inset 0 4px 0 0 var(--alt-wall-in), inset 0 7px 3px -2px var(--alt-cast), 0 1px 0 0 var(--alt-lip)';\n\n/**\n * The editor is an opening: a well with its inside wall, the floor lit while focused and a 2px neutral rim for keyboard\n * focus. Gutter and lines are ground; the active line is a tint, never a height; the selection is accent. Lint errors\n * sink their gutter marker into a trench on critical-soft and say the problem in words. Tooltips and completion lists\n * float at level 3.\n */\nexport const altitudeEditorTheme: Extension = EditorView.theme({\n '&': { color: 'var(--ink)', backgroundColor: 'var(--surface-well)', border: '1px solid var(--line-control)', borderRadius: 'var(--radius-md)',\n boxShadow: wall, outline: '1px solid transparent' },\n '&:hover': { borderColor: 'var(--ink-muted)' },\n '&.cm-focused': { outline: '1px solid transparent', backgroundColor: 'var(--surface-raised)' },\n '&:has(.cm-content:focus-visible)': { borderColor: 'var(--alt-rim-held)', outlineColor: 'var(--alt-rim-held)' },\n '.cm-scroller': { fontFamily: 'var(--font-mono)', fontSize: '13px', lineHeight: '20px', paddingTop: '4px' },\n '.cm-content': { caretColor: 'var(--ink)', padding: 'var(--space-2) 0' },\n '.cm-line': { padding: '0 var(--space-3)' },\n '.cm-cursor, .cm-dropCursor': { borderLeftColor: 'var(--ink)', borderLeftWidth: '2px' },\n '.cm-gutters': { backgroundColor: 'transparent', color: 'var(--ink-muted)', border: 'none', borderRight: '1px solid var(--line)' },\n '.cm-lineNumbers .cm-gutterElement': { padding: '0 var(--space-2) 0 var(--space-3)' },\n '.cm-activeLine': { backgroundColor: 'color-mix(in oklab, var(--accent-soft) 60%, transparent)' },\n '.cm-activeLineGutter': { backgroundColor: 'transparent', color: 'var(--ink)' },\n '&.cm-focused > .cm-scroller > .cm-selectionLayer .cm-selectionBackground, .cm-selectionBackground, .cm-content ::selection': { backgroundColor: 'color-mix(in oklab, var(--accent-ink) 24%, transparent)' },\n '.cm-matchingBracket, &.cm-focused .cm-matchingBracket': { backgroundColor: 'transparent', outline: '1px solid var(--accent-ink)', borderRadius: '2px' },\n '.cm-searchMatch': { backgroundColor: 'color-mix(in oklab, var(--caution) 22%, transparent)', outline: '1px solid var(--caution)' },\n '.cm-placeholder': { color: 'var(--ink-muted)' },\n '.cm-lintRange-error': { backgroundImage: 'none', textDecoration: 'underline wavy var(--critical)', textUnderlineOffset: '3px' },\n '.cm-lintRange-warning': { backgroundImage: 'none', textDecoration: 'underline wavy var(--caution)', textUnderlineOffset: '3px' },\n '.cm-lint-marker': { width: '12px', height: '12px', borderRadius: '3px', backgroundImage: 'none !important' },\n '.cm-lint-marker-error': { backgroundColor: 'var(--critical-soft)', boxShadow: 'var(--trench), inset 0 0 0 1px var(--critical)' },\n '.cm-lint-marker-warning': { backgroundColor: 'var(--caution-soft)', boxShadow: 'inset 0 0 0 1px var(--caution)' },\n '.cm-diagnostic': { padding: 'var(--space-1) var(--space-3)', font: '500 13px/18px var(--font-sans)', color: 'var(--ink)' },\n '.cm-diagnostic-error': { borderLeft: '3px solid var(--critical)' },\n '.cm-diagnostic-warning': { borderLeft: '3px solid var(--caution)' },\n '.cm-tooltip': { border: 'none', borderRadius: 'var(--radius-md)', backgroundColor: 'var(--surface-floating)', color: 'var(--ink)', boxShadow: 'var(--elev-3)', overflow: 'hidden' },\n '.cm-tooltip-autocomplete > ul': { fontFamily: 'var(--font-mono)', fontSize: '13px' },\n '.cm-tooltip-autocomplete > ul > li': { padding: '4px var(--space-2)' },\n '.cm-tooltip-autocomplete > ul > li[aria-selected]': { backgroundColor: 'var(--accent-soft)', color: 'var(--ink)' },\n '.cm-panels': { backgroundColor: 'var(--surface-ground)', color: 'var(--ink)' },\n '.cm-panels.cm-panels-bottom': { borderTop: '1px solid var(--line)' },\n '.cm-panels.cm-panels-top': { borderBottom: '1px solid var(--line)' },\n '.cm-foldPlaceholder': { backgroundColor: 'var(--surface-raised)', border: '1px solid var(--line)', color: 'var(--ink-muted)' },\n // Nothing here moves, so reduced motion needs no rule: the editor changes state without transitions.\n '@media (forced-colors: active)': { '.cm-lint-marker-error': { border: '2px dashed CanvasText' }, '.cm-tooltip': { border: '1px solid CanvasText' } },\n});\n\n/** Syntax in ink, ink-muted and accent-ink only: code is text to read, not data to compare, so no data-* hues. */\nexport const altitudeHighlightStyle: HighlightStyle = HighlightStyle.define([\n { tag: [t.keyword, t.operatorKeyword, t.modifier, t.controlKeyword], color: 'var(--accent-ink)', fontWeight: '600' },\n { tag: [t.number, t.bool, t.null, t.atom], color: 'var(--accent-ink)' },\n { tag: [t.string, t.special(t.string), t.regexp], color: 'var(--ink)' },\n { tag: [t.propertyName, t.attributeName, t.definition(t.variableName), t.function(t.variableName)], color: 'var(--ink)', fontWeight: '550' },\n { tag: [t.comment, t.lineComment, t.blockComment, t.docComment], color: 'var(--ink-muted)', fontStyle: 'italic' },\n { tag: [t.punctuation, t.bracket, t.separator, t.operator], color: 'var(--ink-muted)' },\n { tag: [t.typeName, t.className, t.tagName], color: 'var(--accent-ink)' },\n { tag: t.invalid, color: 'var(--critical)' },\n]);\n\n/** The whole adapter: `new EditorView({ extensions: [altitudeTheme(), \u2026] })`. */\nexport function altitudeTheme(): Extension {\n return [altitudeEditorTheme, syntaxHighlighting(altitudeHighlightStyle)];\n}\n"],
5
+ "mappings": "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",
6
+ "names": []
7
+ }
@@ -0,0 +1,102 @@
1
+ /* altitude-design/adapters/react-flow.css: Altitude readings for a React Flow (@xyflow/react 12) node-and-edge canvas.
2
+ Import it after altitude.css and after React Flow's own stylesheet (base.css or style.css). It sets React Flow's
3
+ --xy-* properties from the active scheme and styles its elements; it imports nothing.
4
+ - The canvas is ground, with a dot grid in line.
5
+ - Nodes are Cards at level 1; a node that can be selected lifts one level when pointed at; a dragged node is in your
6
+ hand at level 3. Selection is a rim, never extra height.
7
+ - Ports (handles) are small openings that deepen under an edge being drawn, and take the accent rim where it can
8
+ land. The edge being drawn is a dashed line-control stroke; edges are line-control, a selected edge accent-ink.
9
+ - Give a node className "alt-node-pending" while its work runs (it hovers, as a pending write) or "alt-node-failed"
10
+ when it failed (it drops into a trench). Say the state in the node's words too.
11
+ - The minimap is a well with a raised lens (the ChartBrush build); controls are a raised toolbar.
12
+ React Flow's keyboard support and ARIA are untouched. ── */
13
+ .react-flow {
14
+ --xy-background-color: var(--surface-ground);
15
+ --xy-background-pattern-dots-color: var(--line-control);
16
+ --xy-background-pattern-color: var(--line-control);
17
+ --xy-node-color: var(--ink);
18
+ --xy-node-background-color: var(--surface-raised);
19
+ --xy-node-border: 0;
20
+ --xy-node-border-radius: var(--radius-lg);
21
+ --xy-node-boxshadow-hover: var(--elev-2);
22
+ --xy-node-boxshadow-selected: var(--elev-1), 0 0 0 2px var(--accent-ink);
23
+ --xy-node-group-background-color: color-mix(in oklab, var(--surface-well) 60%, transparent);
24
+ --xy-edge-stroke: var(--line-control);
25
+ --xy-edge-stroke-width: 1.5;
26
+ --xy-edge-stroke-selected: var(--accent-ink);
27
+ --xy-connectionline-stroke: var(--ink-muted);
28
+ --xy-connectionline-stroke-width: 1.5;
29
+ --xy-edge-label-background-color: var(--surface-ground);
30
+ --xy-edge-label-color: var(--ink-muted);
31
+ --xy-handle-background-color: var(--surface-well);
32
+ --xy-handle-border-color: var(--line-control);
33
+ --xy-selection-background-color: color-mix(in oklab, var(--accent-soft) 50%, transparent);
34
+ --xy-selection-border: 1px dashed var(--accent-ink);
35
+ --xy-minimap-background-color: var(--surface-well);
36
+ --xy-minimap-mask-background-color: color-mix(in oklab, var(--surface-well) 72%, transparent);
37
+ --xy-minimap-mask-stroke-color: var(--line-control);
38
+ --xy-minimap-mask-stroke-width: 1;
39
+ --xy-minimap-node-background-color: var(--line-control);
40
+ --xy-controls-button-background-color: var(--surface-raised);
41
+ --xy-controls-button-background-color-hover: var(--surface-lifted);
42
+ --xy-controls-button-color: var(--ink);
43
+ --xy-controls-button-color-hover: var(--ink);
44
+ --xy-controls-button-border-color: var(--line);
45
+ --xy-controls-box-shadow: var(--elev-1);
46
+ --xy-attribution-background-color: transparent;
47
+ color: var(--ink); font-family: var(--font-sans);
48
+ }
49
+
50
+ /* Nodes: Cards at level 1. */
51
+ .react-flow .react-flow__node-default, .react-flow .react-flow__node-input, .react-flow .react-flow__node-output, .react-flow .alt-node {
52
+ padding: var(--space-2) var(--space-3); border: 0; border-radius: var(--radius-lg); background: var(--surface-raised); color: var(--ink);
53
+ max-width: 220px; box-shadow: var(--elev-1); font: 500 13px/18px var(--font-sans); text-align: start; overflow-wrap: break-word;
54
+ transition: box-shadow var(--dur-travel-1) var(--ease-rise), background-color var(--dur-travel-1) var(--ease-rise);
55
+ }
56
+ .react-flow .react-flow__node.selectable:hover:not(.dragging) { box-shadow: var(--elev-2); }
57
+ .react-flow .react-flow__node.selectable.selected, .react-flow .react-flow__node.selectable.selected:hover:not(.dragging) { box-shadow: var(--elev-1), 0 0 0 2px var(--accent-ink); }
58
+ .react-flow .react-flow__node.selectable:focus-visible { outline: 2px solid var(--alt-rim-held); outline-offset: 2px; box-shadow: var(--elev-1); }
59
+ /* Possession: a dragged node is in your hand. */
60
+ .react-flow .react-flow__node.dragging { box-shadow: var(--elev-3); cursor: grabbing; }
61
+ /* Status: running hovers as a pending write; failed drops into a trench. */
62
+ .react-flow .react-flow__node.alt-node-pending { box-shadow: var(--elev-2); animation: alt-flow-hover var(--dur-hover) ease-in-out var(--dur-grace) infinite alternate both; cursor: progress; }
63
+ @keyframes alt-flow-hover { from { box-shadow: var(--elev-2); } to { box-shadow: var(--elev-3); } }
64
+ .react-flow .react-flow__node.alt-node-failed { background: var(--critical-soft); box-shadow: var(--trench), inset 0 0 0 1px var(--critical); }
65
+
66
+ /* Ports: small openings that deepen to receive an edge. */
67
+ .react-flow .react-flow__handle {
68
+ width: 10px; height: 10px; border: 1px solid var(--line-control); border-radius: 50%; background: var(--surface-well);
69
+ box-shadow: inset 0 1.5px 0 0 var(--alt-wall-in); transition: box-shadow var(--dur-travel-1) var(--ease-settle), background-color var(--dur-travel-1);
70
+ }
71
+ .react-flow .react-flow__handle.connectionindicator:hover, .react-flow .react-flow__handle.connectingfrom { box-shadow: inset 0 3px 0 0 var(--alt-wall-in); }
72
+ .react-flow .react-flow__handle.connectingto { background: var(--surface-trench); box-shadow: var(--trench); }
73
+ .react-flow .react-flow__handle.connectingto.valid { border-color: var(--accent-ink); box-shadow: var(--trench), 0 0 0 2px var(--accent-ink); }
74
+
75
+ /* Edges */
76
+ .react-flow .react-flow__connection-path { stroke-dasharray: 5 4; }
77
+ .react-flow .react-flow__edge-text { font: 500 12px/16px var(--font-sans); fill: var(--ink-muted); }
78
+ .react-flow .react-flow__edge-textbg { fill: var(--surface-ground); }
79
+ .react-flow .react-flow__edge.alt-edge-failed .react-flow__edge-path { stroke: var(--critical); stroke-dasharray: 4 3; }
80
+
81
+ /* Minimap: a well with a raised lens. Controls: a raised toolbar. */
82
+ .react-flow .react-flow__minimap { border-radius: var(--radius-md); box-shadow: inset 0 2px 0 0 var(--alt-wall-in), 0 0 0 1px var(--line-control); overflow: hidden; }
83
+ .react-flow .react-flow__controls { border-radius: var(--radius-md); overflow: hidden; box-shadow: var(--elev-1); }
84
+ .react-flow .react-flow__controls-button { display: grid; place-items: center; width: 28px; height: 28px; padding: 0; border: 0; border-bottom: 1px solid var(--line); background: var(--surface-raised); color: var(--ink); cursor: pointer; }
85
+ .react-flow .react-flow__controls-button:last-child { border-bottom: 0; }
86
+ .react-flow .react-flow__controls-button:hover { background: var(--surface-lifted); }
87
+ .react-flow .react-flow__controls-button svg { width: 12px; height: 12px; }
88
+ .react-flow .react-flow__controls-button svg { fill: currentColor; }
89
+ .react-flow .react-flow__controls-button:focus-visible { outline: 2px solid var(--alt-rim-held); outline-offset: -2px; }
90
+ .react-flow .react-flow__attribution a { color: var(--ink-muted); }
91
+
92
+ @media (prefers-reduced-motion: reduce) { .react-flow .react-flow__node, .react-flow .react-flow__handle { transition: none; } .react-flow .react-flow__node.alt-node-pending { animation: none; } }
93
+ [data-motion="reduced"] .react-flow .react-flow__node, [data-motion="reduced"] .react-flow .react-flow__handle { transition: none; }
94
+ [data-motion="reduced"] .react-flow .react-flow__node.alt-node-pending { animation: none; }
95
+ @media (forced-colors: active) {
96
+ .react-flow .react-flow__node { border: 1px solid CanvasText; }
97
+ .react-flow .react-flow__node.selected { outline: 2px solid Highlight; }
98
+ .react-flow .react-flow__node.alt-node-pending { border-style: dotted; border-width: 2px; }
99
+ .react-flow .react-flow__node.alt-node-failed { border: 2px dashed CanvasText; }
100
+ .react-flow .react-flow__handle { border-color: CanvasText; }
101
+ .react-flow .react-flow__edge-path, .react-flow .react-flow__connection-path { stroke: CanvasText; }
102
+ }
@@ -0,0 +1,71 @@
1
+ /* altitude-design/adapters/tiptap.css: Altitude readings for a Tiptap (ProseMirror) rich text editor.
2
+ Import it after altitude.css. It styles Tiptap's own elements; it doesn't import Tiptap, which your app installs.
3
+ - The editor is an opening, built like Textarea: an empty editor is a well showing its inside wall; once it holds
4
+ content the floor rises flush; focus lights the floor, and keyboard focus adds the 2px neutral rim.
5
+ - Content follows Altitude's type: links are .alt-link, inline code a mono plate, code blocks CodeBlock's ground,
6
+ mentions a flush Tag plate.
7
+ - The formatting bar is yours to render with Toolbar and ToolbarToggle (latched toggles). The mention list is yours
8
+ to render too: give it class "alt-rte-mentions" (role listbox, options with aria-selected) and it floats at level 3
9
+ like Combobox's list.
10
+ Tiptap's keyboard support and ARIA are untouched. ── */
11
+ .tiptap {
12
+ --w: 4px; --n: 0; --wc: var(--alt-wall-in); --wd: calc(var(--w) + var(--n) * 2px);
13
+ position: relative; min-height: 120px; padding: calc(var(--space-2) + var(--wd) * 0.5) var(--space-3) var(--space-2);
14
+ border: 1px solid var(--line-control); border-radius: var(--radius-md); background: var(--surface-well); color: var(--ink);
15
+ font: 400 15px/23px var(--font-sans); overflow-wrap: break-word; cursor: text;
16
+ box-shadow: inset 0 var(--wd) 0 0 var(--wc), inset 0 calc(var(--wd) + 3px) 3px -2px var(--alt-cast), 0 1px 0 0 var(--alt-lip);
17
+ outline: 1px solid transparent; outline-offset: 0;
18
+ transition: background-color var(--dur-travel-2) var(--ease-rise), box-shadow var(--dur-travel-2) var(--ease-settle), border-color var(--dur-travel-1) var(--ease-rise),
19
+ outline-color var(--dur-travel-1) var(--ease-rise), padding var(--dur-travel-2) var(--ease-settle);
20
+ }
21
+ .tiptap:hover { border-color: var(--ink-muted); }
22
+ /* Filled: anything but a single empty paragraph. The floor rises flush with the page. */
23
+ .tiptap:not(:has(> p:only-child > br.ProseMirror-trailingBreak:only-child)):not(:has(> p:only-child:empty)) { --w: 0px; background: var(--surface-raised); }
24
+ .tiptap.ProseMirror-focused, .tiptap:focus { background: var(--surface-raised); --n: var(--alt-travel); }
25
+ .tiptap:focus-visible { border-color: var(--alt-rim-held); outline-color: var(--alt-rim-held); }
26
+ .tiptap[contenteditable="false"] { --w: 0px; --n: 0; background: var(--surface-ground); border-color: var(--line); cursor: default; }
27
+ .tiptap[aria-invalid="true"] { --w: 6px; --n: 0; --wc: color-mix(in oklab, var(--critical-soft), var(--critical) 34%); background: var(--critical-soft); border-color: var(--critical); }
28
+
29
+ /* Placeholder (Tiptap's Placeholder extension): ink-muted, never the value. */
30
+ .tiptap p.is-editor-empty:first-child::before { content: attr(data-placeholder); float: left; height: 0; color: var(--ink-muted); pointer-events: none; }
31
+
32
+ /* Content */
33
+ .tiptap > :first-child { margin-top: 0; }
34
+ .tiptap > :last-child { margin-bottom: 0; }
35
+ .tiptap p { margin: 0 0 var(--space-2); }
36
+ .tiptap h1, .tiptap h2, .tiptap h3 { margin: var(--space-4) 0 var(--space-2); font-weight: 600; letter-spacing: -0.01em; }
37
+ .tiptap h1 { font-size: 21px; line-height: 28px; } .tiptap h2 { font-size: 18px; line-height: 25px; } .tiptap h3 { font-size: 16px; line-height: 23px; }
38
+ .tiptap ul, .tiptap ol { margin: 0 0 var(--space-2); padding-inline-start: 22px; }
39
+ .tiptap li > p { margin: 0; }
40
+ .tiptap li::marker { color: var(--ink-muted); }
41
+ .tiptap blockquote { margin: 0 0 var(--space-2); padding-inline-start: var(--space-3); border-inline-start: 2px solid var(--line-control); color: var(--ink-muted); }
42
+ .tiptap hr { margin: var(--space-3) 0; border: 0; border-top: 1px solid var(--line); }
43
+ .tiptap a { color: var(--accent-ink); text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: 0.2em; }
44
+ .tiptap code { padding: 1px 5px; border-radius: var(--radius-xs); background: var(--surface-well); box-shadow: inset 0 0 0 1px var(--line); font: 500 0.88em/1 var(--font-mono); }
45
+ .tiptap pre { margin: 0 0 var(--space-2); padding: var(--space-3) var(--space-4); border: 1px solid var(--line); border-radius: var(--radius-lg); background: var(--surface-ground); overflow-x: auto; }
46
+ .tiptap pre code { padding: 0; background: none; box-shadow: none; font: 400 13px/20px var(--font-mono); }
47
+ .tiptap strong { font-weight: 600; }
48
+ .tiptap ::selection { background: var(--accent-soft); }
49
+ .tiptap .mention, .tiptap [data-type="mention"] {
50
+ display: inline-flex; align-items: center; height: 22px; padding: 0 6px; border-radius: var(--radius-sm); vertical-align: baseline;
51
+ background: color-mix(in oklab, var(--surface-ground), var(--surface-well) 70%); color: var(--ink); font: 550 0.9em/1 var(--font-sans);
52
+ box-shadow: inset 0 1px 1.5px color-mix(in oklab, var(--ink) 16%, transparent), inset 0 0 0 1px color-mix(in oklab, var(--ink) 9%, transparent);
53
+ }
54
+ .tiptap .ProseMirror-selectednode { outline: 2px solid var(--accent-ink); outline-offset: 1px; }
55
+ .tiptap .ProseMirror-gapcursor::after { border-top-color: var(--ink); }
56
+
57
+ /* The mention list: your markup, floating at level 3 like Combobox's list. */
58
+ .alt-rte-mentions { min-width: 200px; max-height: 260px; padding: var(--space-1); overflow-y: auto; border-radius: var(--radius-lg); background: var(--surface-floating); box-shadow: var(--elev-3); }
59
+ .alt-rte-mentions [role="option"] { display: flex; align-items: center; gap: 8px; min-height: 34px; padding: 0 10px; border-radius: var(--radius-sm); font: 500 14px/20px var(--font-sans); color: var(--ink); cursor: pointer; }
60
+ .alt-rte-mentions [role="option"][aria-selected="true"] { background: var(--accent-soft); }
61
+
62
+ @media (prefers-reduced-motion: reduce) { .tiptap { transition: none; } }
63
+ [data-motion="reduced"] .tiptap { transition: none; }
64
+ @media (forced-colors: active) {
65
+ .tiptap { border: 1px solid CanvasText; }
66
+ .tiptap:has(> p:only-child > br.ProseMirror-trailingBreak:only-child) { border-style: dashed; }
67
+ .tiptap:focus-visible { outline: 2px solid Highlight; }
68
+ .tiptap .mention, .tiptap [data-type="mention"] { border: 1px solid CanvasText; }
69
+ .alt-rte-mentions { border: 1px solid CanvasText; }
70
+ .alt-rte-mentions [role="option"][aria-selected="true"] { outline: 2px solid Highlight; outline-offset: -2px; }
71
+ }