@cardstack/boxel-cli 0.11.0-unstable.1 → 0.11.0-unstable.3

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 (177) hide show
  1. package/bundled-realms/pretui/components/agent-mark.gts +98 -0
  2. package/bundled-realms/pretui/components/agent-question.gts +340 -37
  3. package/bundled-realms/pretui/components/answer-footer.gts +249 -0
  4. package/bundled-realms/pretui/components/card-embed.gts +523 -0
  5. package/bundled-realms/pretui/components/card-pills.gts +725 -0
  6. package/bundled-realms/pretui/components/code-block.gts +87 -45
  7. package/bundled-realms/pretui/components/collapsed-turn.gts +133 -12
  8. package/bundled-realms/pretui/components/compaction-chip.gts +81 -67
  9. package/bundled-realms/pretui/components/composer-cap.gts +516 -0
  10. package/bundled-realms/pretui/components/context-ring.gts +108 -0
  11. package/bundled-realms/pretui/components/diff-block.gts +1002 -31
  12. package/bundled-realms/pretui/components/diff-stat.gts +102 -0
  13. package/bundled-realms/pretui/components/jump-chip.gts +86 -53
  14. package/bundled-realms/pretui/components/markdown-stream.gts +799 -0
  15. package/bundled-realms/pretui/components/markdown-surface.gts +71 -0
  16. package/bundled-realms/pretui/components/plan-mark.gts +147 -0
  17. package/bundled-realms/pretui/components/prose.gts +185 -8
  18. package/bundled-realms/pretui/components/prose.md +6 -8
  19. package/bundled-realms/pretui/components/quick-look.gts +377 -0
  20. package/bundled-realms/pretui/components/reactions.gts +136 -0
  21. package/bundled-realms/pretui/components/recommendation.gts +67 -36
  22. package/bundled-realms/pretui/components/result-card.gts +58 -22
  23. package/bundled-realms/pretui/components/segmented-control.gts +13 -8
  24. package/bundled-realms/pretui/components/session-prep.gts +12 -11
  25. package/bundled-realms/pretui/components/sliding-highlight.gts +8 -3
  26. package/bundled-realms/pretui/components/speaker-label.gts +132 -0
  27. package/bundled-realms/pretui/components/state-glyph.gts +121 -0
  28. package/bundled-realms/pretui/components/step-list.gts +62 -60
  29. package/bundled-realms/pretui/components/stick-to-bottom.gts +1150 -0
  30. package/bundled-realms/pretui/components/system-line.gts +143 -0
  31. package/bundled-realms/pretui/components/task-checklist.gts +184 -0
  32. package/bundled-realms/pretui/components/thinking.gts +63 -94
  33. package/bundled-realms/pretui/components/tool-change-table.gts +285 -0
  34. package/bundled-realms/pretui/components/tool-gate.gts +462 -0
  35. package/bundled-realms/pretui/components/tool-group.gts +920 -0
  36. package/bundled-realms/pretui/components/tool-icon.ts +64 -0
  37. package/bundled-realms/pretui/components/tool-meta.gts +82 -0
  38. package/bundled-realms/pretui/components/tool-plan.gts +197 -0
  39. package/bundled-realms/pretui/components/tool-row.gts +2087 -0
  40. package/bundled-realms/pretui/components/turn-changes.gts +227 -0
  41. package/bundled-realms/pretui/components/user-bubble.gts +575 -0
  42. package/bundled-realms/pretui/components/work-item.gts +185 -48
  43. package/bundled-realms/pretui/docs/scroll-anchoring-protocol.md +136 -0
  44. package/bundled-realms/pretui/internal/markdown-projection.ts +438 -0
  45. package/bundled-realms/pretui/internal/mount-queue.ts +79 -0
  46. package/bundled-realms/pretui/internal/tool-phrases.ts +168 -0
  47. package/bundled-realms/pretui/package.json +2 -1
  48. package/bundled-test-harness/assets/{ai-module-creation-test-beRNwH-e.js → ai-module-creation-test-B6FQKqIl.js} +1 -1
  49. package/bundled-test-harness/assets/{app-QAuw0l8v.js → app-KpPqdyX3.js} +4 -4
  50. package/bundled-test-harness/assets/{binary-upload-dedupe-test-bI8T0QLl.js → binary-upload-dedupe-test-DN00y1tM.js} +1 -1
  51. package/bundled-test-harness/assets/{can-invoke-test-DVaU_yRT.js → can-invoke-test-Bl-EUFM3.js} +1 -1
  52. package/bundled-test-harness/assets/{card-chooser-paging-test-DnxMnXKR.js → card-chooser-paging-test-BNuZRHX3.js} +1 -1
  53. package/bundled-test-harness/assets/{card-chooser-test-DUSnLr-u.js → card-chooser-test-wKfPOOT4.js} +1 -1
  54. package/bundled-test-harness/assets/{card-def-field-def-relationships-test-GBUr3tFK.js → card-def-field-def-relationships-test-CduQ6zan.js} +1 -1
  55. package/bundled-test-harness/assets/{card-delete-test-CQveO1VC.js → card-delete-test-DKxolj5o.js} +1 -1
  56. package/bundled-test-harness/assets/{check-correctness-test-D2M2p66N.js → check-correctness-test-B-kgHztp.js} +1 -1
  57. package/bundled-test-harness/assets/choreo-BEHW-NOc.js +2 -0
  58. package/bundled-test-harness/assets/{choreo-CJfBb_EY.js → choreo-C2cpCfhA.js} +164 -13
  59. package/bundled-test-harness/assets/{choreo-feature-reel-test-D2OrygZv.js → choreo-feature-reel-test-CPI_6nkT.js} +2 -2
  60. package/bundled-test-harness/assets/{choreo-gallery-w07xqtO-.js → choreo-gallery-BxA9cyzF.js} +3 -3
  61. package/bundled-test-harness/assets/{choreo-gallery-build-order-test-yQg4JER6.js → choreo-gallery-build-order-test-CLVoseAJ.js} +1 -1
  62. package/bundled-test-harness/assets/{choreo-gallery-compositor-test-C2THCXJN.js → choreo-gallery-compositor-test-BpT5Ia6B.js} +1 -1
  63. package/bundled-test-harness/assets/{choreo-gallery-cover-test-D4T_Tk4s.js → choreo-gallery-cover-test-DL_fdSsh.js} +1 -1
  64. package/bundled-test-harness/assets/{choreo-gallery-crossing-stage-test-tHUPJ-Hy.js → choreo-gallery-crossing-stage-test-BcKHhpOK.js} +2 -2
  65. package/bundled-test-harness/assets/{choreo-gallery-demos-alive-test-BOtBOnEZ.js → choreo-gallery-demos-alive-test-KufLhXG8.js} +1 -1
  66. package/bundled-test-harness/assets/{choreo-gallery-drift-test-D_6U1Z2c.js → choreo-gallery-drift-test-Cx58rYIA.js} +1 -1
  67. package/bundled-test-harness/assets/{choreo-gallery-escort-test-DDBU0n4C.js → choreo-gallery-escort-test-Wz-emmID.js} +1 -1
  68. package/bundled-test-harness/assets/{choreo-gallery-films-test-CgW1NSdr.js → choreo-gallery-films-test-BFrVs5WW.js} +2 -2
  69. package/bundled-test-harness/assets/{choreo-gallery-filter-test-DUIsNwdO.js → choreo-gallery-filter-test-DCKQkhwe.js} +1 -1
  70. package/bundled-test-harness/assets/{choreo-gallery-fold-test-Chzlxvdr.js → choreo-gallery-fold-test-UtpDgpG9.js} +1 -1
  71. package/bundled-test-harness/assets/{choreo-gallery-guide-pages-test-DOWnqALT.js → choreo-gallery-guide-pages-test-rXDU9JLM.js} +1 -1
  72. package/bundled-test-harness/assets/{choreo-gallery-guides-test-Dra2J4LJ.js → choreo-gallery-guides-test-DfVFdIuU.js} +3 -3
  73. package/bundled-test-harness/assets/{choreo-gallery-hang-test-zzn1eiB-.js → choreo-gallery-hang-test-Cj7MbkFf.js} +1 -1
  74. package/bundled-test-harness/assets/{choreo-gallery-highlight-test-CW99hncQ.js → choreo-gallery-highlight-test-D6CF3IYZ.js} +2 -2
  75. package/bundled-test-harness/assets/{choreo-gallery-inline-edit-test-CYFm1kUz.js → choreo-gallery-inline-edit-test-LfHWsbqc.js} +1 -1
  76. package/bundled-test-harness/assets/{choreo-gallery-interruption-test-CYIBrKV9.js → choreo-gallery-interruption-test-CvQQAgTp.js} +2 -2
  77. package/bundled-test-harness/assets/{choreo-gallery-lone-stack-test-DL8R3SG7.js → choreo-gallery-lone-stack-test-D7Zci7fm.js} +1 -1
  78. package/bundled-test-harness/assets/{choreo-gallery-navigation-test-Dcv04kDx.js → choreo-gallery-navigation-test-DB1EnBEW.js} +1 -1
  79. package/bundled-test-harness/assets/{choreo-gallery-playhead-transport-test-Cfz7GsXl.js → choreo-gallery-playhead-transport-test-CtBlc6AJ.js} +1 -1
  80. package/bundled-test-harness/assets/{choreo-gallery-poplayout-subtree-test-CwoklBkW.js → choreo-gallery-poplayout-subtree-test-BQbmjsvI.js} +1 -1
  81. package/bundled-test-harness/assets/{choreo-gallery-presence-modes-test-BDCIZzJ0.js → choreo-gallery-presence-modes-test-CIdXVG1K.js} +1 -1
  82. package/bundled-test-harness/assets/{choreo-gallery-presentation-test-DlyiHwFf.js → choreo-gallery-presentation-test-C_rPFp29.js} +1 -1
  83. package/bundled-test-harness/assets/{choreo-gallery-reduced-motion-test-DVz5SKNR.js → choreo-gallery-reduced-motion-test-CH5w8Lw-.js} +2 -2
  84. package/bundled-test-harness/assets/{choreo-gallery-sheet-standalone-test-CpD_-BvS.js → choreo-gallery-sheet-standalone-test-CDgI4mGX.js} +1 -1
  85. package/bundled-test-harness/assets/{choreo-gallery-sheet-test-BjvAKHDL.js → choreo-gallery-sheet-test-5lsFX7Rk.js} +1 -1
  86. package/bundled-test-harness/assets/{choreo-gallery-site-test-oq_7y_PN.js → choreo-gallery-site-test-DbMa2xeC.js} +2 -2
  87. package/bundled-test-harness/assets/{choreo-gallery-stage-Bzr4_8Xd.js → choreo-gallery-stage-b3Sk86hp.js} +2 -2
  88. package/bundled-test-harness/assets/{choreo-gallery-stage-keyboard-test-a83d2euJ.js → choreo-gallery-stage-keyboard-test-ds6fT5Eg.js} +1 -1
  89. package/bundled-test-harness/assets/{choreo-gallery-stages-test-C9Sl1kH6.js → choreo-gallery-stages-test-ahioKCct.js} +2 -2
  90. package/bundled-test-harness/assets/{choreo-gallery-subdivision-test-BVVnkOwk.js → choreo-gallery-subdivision-test-g7anTDhT.js} +1 -1
  91. package/bundled-test-harness/assets/{choreo-gallery-table-plan-test-B0YdYEA0.js → choreo-gallery-table-plan-test-Bozc4uUf.js} +1 -1
  92. package/bundled-test-harness/assets/{choreo-gallery-theater-test-BLA147xw.js → choreo-gallery-theater-test-kE535d-b.js} +3 -3
  93. package/bundled-test-harness/assets/{choreo-gallery-tuning-test-DSXiNzCh.js → choreo-gallery-tuning-test-6rHkQBnZ.js} +1 -1
  94. package/bundled-test-harness/assets/{choreo-gallery-widget-room-test-BI574PdO.js → choreo-gallery-widget-room-test-0Vq-uTo1.js} +2 -2
  95. package/bundled-test-harness/assets/{choreo-gallery-wires-test-B6Mz2WZl.js → choreo-gallery-wires-test-CdtnAWYO.js} +1 -1
  96. package/bundled-test-harness/assets/clip-BLfuHi8g.js +2 -0
  97. package/bundled-test-harness/assets/{clip-C_pXjVvY.js → clip-q1QE5f73.js} +1 -1
  98. package/bundled-test-harness/assets/{codeblocks-test-AdolhdCA.js → codeblocks-test-BDD7qK_V.js} +1 -1
  99. package/bundled-test-harness/assets/{compaction-test-DvyAQq56.js → compaction-test-BweolkhG.js} +1 -1
  100. package/bundled-test-harness/assets/{container-DIF_9lZ9.css → container-B5B6u-xm.css} +29 -22
  101. package/bundled-test-harness/assets/{container-DvvqmNpg.js → container-BnJjIM6J.js} +9 -6
  102. package/bundled-test-harness/assets/{create-listing-modal-test-D95JfQab.js → create-listing-modal-test-FvcAKpIa.js} +1 -1
  103. package/bundled-test-harness/assets/{debug-message-test-BcNtj7Wr.js → debug-message-test-CJ18Evt7.js} +1 -1
  104. package/bundled-test-harness/assets/{externals-6ZWftYIb.js → externals-BWjhmCD4.js} +12 -12
  105. package/bundled-test-harness/assets/{fallback-banner-live-delete-test-5lnN1pv2.js → fallback-banner-live-delete-test-C2H3BrT-.js} +1 -1
  106. package/bundled-test-harness/assets/{fallback-banner-test-DFb_m_Kq.js → fallback-banner-test-C10aYjkj.js} +1 -1
  107. package/bundled-test-harness/assets/{fallback-models-test-p3YIwj1L.js → fallback-models-test-BxoPiaGF.js} +1 -1
  108. package/bundled-test-harness/assets/{file-attachment-test-CmyjNWRR.js → file-attachment-test-DeKyzYaz.js} +1 -1
  109. package/bundled-test-harness/assets/film-B68PjRlr.js +2 -0
  110. package/bundled-test-harness/assets/{film-D7vtJO5q.js → film-CeUpnHN_.js} +6 -6
  111. package/bundled-test-harness/assets/{film-DN0A8JHx.js → film-DBZqyqW4.js} +6 -6
  112. package/bundled-test-harness/assets/{general-test-CX-TFDuX.js → general-test-BewzrpoB.js} +1 -1
  113. package/bundled-test-harness/assets/{glimmer-motion-and-choreo-in-cards-test-BHte2t9G.js → glimmer-motion-and-choreo-in-cards-test-HA-INN3d.js} +14 -14
  114. package/bundled-test-harness/assets/{glimmer-motion-and-choreo-test-BPNVeIio.js → glimmer-motion-and-choreo-test-BZ0ZuuAw.js} +3 -3
  115. package/bundled-test-harness/assets/{index-query-engine-test-Dz7Q4Xmk.js → index-query-engine-test-BtI8Y2LR.js} +1 -1
  116. package/bundled-test-harness/assets/{instance-filter-matcher-test-BoLU3bVg.js → instance-filter-matcher-test-BHXHGHjE.js} +1 -1
  117. package/bundled-test-harness/assets/{main-Dlgp8c7v.js → main-CqAHZ2kK.js} +1 -1
  118. package/bundled-test-harness/assets/{message-tool-test-CfjRSJvt.js → message-tool-test-NMaPJFsd.js} +1 -1
  119. package/bundled-test-harness/assets/{model-cost-tier-test-mZG84Uso.js → model-cost-tier-test-BgbfN2LH.js} +1 -1
  120. package/bundled-test-harness/assets/{operation-lowering-test-B0KpI1xu.js → operation-lowering-test-C4IaOjsA.js} +1 -1
  121. package/bundled-test-harness/assets/{operator-mode-card-chooser-test-KWS8lq16.js → operator-mode-card-chooser-test-Bwe47Rn7.js} +1 -1
  122. package/bundled-test-harness/assets/{operator-mode-links-test-CViFt0Ws.js → operator-mode-links-test-BU4jkC-B.js} +1 -1
  123. package/bundled-test-harness/assets/{operator-mode-test-D0gZM2yw.js → operator-mode-test-Bh0rGM9z.js} +1 -1
  124. package/bundled-test-harness/assets/{operator-mode-ui-test-CEvHJ9DS.js → operator-mode-ui-test-whgUw0ju.js} +1 -1
  125. package/bundled-test-harness/assets/{overlay-menu-items-test-Pw80RXsr.js → overlay-menu-items-test-Cwn1vr8q.js} +1 -1
  126. package/bundled-test-harness/assets/{overlays-BnOM360u.js → overlays-BOzLbVDK.js} +1 -1
  127. package/bundled-test-harness/assets/{overlays-kBVfa4i8.js → overlays-C_PuGDGh.js} +1 -1
  128. package/bundled-test-harness/assets/{past-sessions-test-CW0-Bjav.js → past-sessions-test-Bh24N-Kz.js} +1 -1
  129. package/bundled-test-harness/assets/{permission-checking-realm-test-D5uXQypS.js → permission-checking-realm-test-DKnnAy0f.js} +1 -1
  130. package/bundled-test-harness/assets/{plate-CFvCDv2t.js → plate-BL7UtyKE.js} +1 -1
  131. package/bundled-test-harness/assets/plate-CqG3igCJ.js +2 -0
  132. package/bundled-test-harness/assets/player-BJfsgdSI.js +2 -0
  133. package/bundled-test-harness/assets/{player-DzuYjrTU.js → player-Da_CIsp_.js} +1 -1
  134. package/bundled-test-harness/assets/{realm-config-policy-standing-test-Btatheni.js → realm-config-policy-standing-test-DngdYypq.js} +1 -1
  135. package/bundled-test-harness/assets/{realm-config-routing-rule-edit-test-Dh5zW13o.js → realm-config-routing-rule-edit-test-_rkFU8SN.js} +1 -1
  136. package/bundled-test-harness/assets/{realm-config-settings-test-BJa8gv_C.js → realm-config-settings-test-CR9NH0Zn.js} +1 -1
  137. package/bundled-test-harness/assets/{reasoning-test-2Zp37cQB.js → reasoning-test-0lH10kRl.js} +1 -1
  138. package/bundled-test-harness/assets/{room-message-test-BsrON13e.js → room-message-test-C-PddE4Y.js} +1 -1
  139. package/bundled-test-harness/assets/{run-BMyvn_UL.js → run-D4n4LPcK.js} +96 -6
  140. package/bundled-test-harness/assets/{run-realm-code-BxktQf6R.js → run-realm-code-C8N7DtN-.js} +1 -1
  141. package/bundled-test-harness/assets/{run-realm-code-test-7grpTos-.js → run-realm-code-test-DBdp147q.js} +1 -1
  142. package/bundled-test-harness/assets/{schema-generation-test-CM9ggQji.js → schema-generation-test-CB1Hb7GQ.js} +1 -1
  143. package/bundled-test-harness/assets/{scrolling-test-BER00htB.js → scrolling-test-3PhVin8h.js} +1 -1
  144. package/bundled-test-harness/assets/{searchable-option-test-BBr5BPow.js → searchable-option-test-BAdOiL4U.js} +1 -1
  145. package/bundled-test-harness/assets/{sending-test-BJGobs2E.js → sending-test-KSmu1tSJ.js} +1 -1
  146. package/bundled-test-harness/assets/{skills-test-GPOsHRN6.js → skills-test-D-dlcFpd.js} +1 -1
  147. package/bundled-test-harness/assets/{src-Df148w_b.js → src-B_DEhPze.js} +4 -4
  148. package/bundled-test-harness/assets/{src-Cf2wv-Le.js → src-BoTgwqUA.js} +2 -2
  149. package/bundled-test-harness/assets/{store-test-QvvHimzH.js → store-test-CEW7xQjZ.js} +1 -1
  150. package/bundled-test-harness/assets/{test-support-rNHuieEc.js → test-support-FXDPpIl3.js} +1 -1
  151. package/bundled-test-harness/assets/{test-support-C6N_2X-l.js → test-support-VX6ukQNR.js} +1 -1
  152. package/bundled-test-harness/assets/{tests-CmsQ-Z_3.js → tests-QYqqa6nv.js} +84 -84
  153. package/bundled-test-harness/assets/{text-input-validator-test-CYYH2N0L.js → text-input-validator-test-D8iNOWep.js} +1 -1
  154. package/bundled-test-harness/assets/{titles-B1pTaIfP.js → titles-DFJj5O0E.js} +1 -1
  155. package/bundled-test-harness/assets/titles-xGlgu7ys.js +2 -0
  156. package/bundled-test-harness/assets/{to-device-streaming-test-Ctqa0bVp.js → to-device-streaming-test-trCX-505.js} +1 -1
  157. package/bundled-test-harness/assets/{token-usage-test-BQVbK3X0.js → token-usage-test-C6sULooH.js} +1 -1
  158. package/bundled-test-harness/assets/{tools-DU8Rc15s.js → tools-UJfD-_al.js} +1 -1
  159. package/bundled-test-harness/assets/{tools-test-B13yvEKE.js → tools-test-Brav31AV.js} +1 -1
  160. package/bundled-test-harness/assets/{worker-DHBEBihX.js → worker-9ph9_Lpv.js} +31 -26
  161. package/bundled-test-harness/index.html +8 -8
  162. package/bundled-test-harness/tests/index.html +8 -8
  163. package/bundled-types/choreo/beacons.ts +16 -4
  164. package/bundled-types/choreo/changeset.ts +25 -5
  165. package/bundled-types/choreo/choreo.gts +245 -3
  166. package/bundled-types/choreo/far.ts +39 -0
  167. package/bundled-types/choreo/index.ts +2 -0
  168. package/bundled-types/choreo/run.ts +104 -1
  169. package/bundled-types/host-app/lib/realm-runner/worker.ts +8 -51
  170. package/bundled-types/runtime-common/realm-runner-script.d.ts +3 -0
  171. package/package.json +1 -1
  172. package/bundled-test-harness/assets/choreo-B3Z9QhDH.js +0 -2
  173. package/bundled-test-harness/assets/clip-BjcXuTwN.js +0 -2
  174. package/bundled-test-harness/assets/film-DMDPP7ma.js +0 -2
  175. package/bundled-test-harness/assets/plate-66qnQ-M9.js +0 -2
  176. package/bundled-test-harness/assets/player-pygg1PwA.js +0 -2
  177. package/bundled-test-harness/assets/titles-Ccpcl-jq.js +0 -2
@@ -0,0 +1,71 @@
1
+ // Pretui — MarkdownSurface: an answer's typography, for markdown however it
2
+ // was rendered.
3
+ import type { TemplateOnlyComponent } from '@ember/component/template-only';
4
+ import { Prose } from './prose';
5
+
6
+ export interface MarkdownSurfaceSignature {
7
+ Blocks: { default: [] };
8
+ Element: HTMLDivElement;
9
+ }
10
+
11
+ // The reading voice an assistant's answer takes on top of Prose: reading
12
+ // type at full ink, the heading ladder, code at the data size, tables at the
13
+ // reading size with caption headers, and the reading measure per text block
14
+ // rather than on the whole answer. MarkdownStream renders inside it while an
15
+ // answer streams; a host that renders a finished answer another way (say, to
16
+ // mount the cards it names) wraps that markup in it, so the swap moves no
17
+ // pixel. Prose owns every rule on the markup; this surface only sets Prose's
18
+ // `--pretui-prose-*` knobs, so the two cannot disagree.
19
+ export const MarkdownSurface: TemplateOnlyComponent<MarkdownSurfaceSignature> =
20
+ <template>
21
+ <div
22
+ class='pretui-md-surface'
23
+ data-test-pretui-markdown-surface
24
+ ...attributes
25
+ >
26
+ <Prose class='pretui-md-surface-prose'>{{yield}}</Prose>
27
+ </div>
28
+ <style scoped>
29
+ @layer PretComponent, PretComposite;
30
+ @layer PretComposite {
31
+ .pretui-md-surface {
32
+ /* the whole answer is as wide as the panel, so code and tables
33
+ can use it; the line length is capped per text block instead */
34
+ --pretui-prose-measure: none;
35
+ --pretui-prose-block-measure: 68ch;
36
+ --pretui-prose-leading: var(--boxel-body-line-height);
37
+ /* the heading ladder: h1 at the small heading size, h2 at reading
38
+ size, h3 at UI size in tracked caps; all 600 */
39
+ --pretui-prose-heading-gap: var(--boxel-sp-xs);
40
+ --pretui-prose-h1-size: var(--boxel-font-size-sm);
41
+ --pretui-prose-h1-leading: var(--boxel-line-height-sm);
42
+ --pretui-prose-h2-size: var(--boxel-body-font-size);
43
+ --pretui-prose-h2-leading: var(--boxel-body-line-height);
44
+ --pretui-prose-h3-size: var(--boxel-ui-label-font-size);
45
+ --pretui-prose-h3-leading: var(--boxel-ui-label-line-height);
46
+ --pretui-prose-h3-tracking: 0.04em;
47
+ --pretui-prose-h3-case: uppercase;
48
+ --pretui-prose-h4-size: var(--boxel-ui-label-font-size);
49
+ --pretui-prose-h4-leading: var(--boxel-ui-label-line-height);
50
+ /* code is a pasteable string: mono at the data size */
51
+ --pretui-prose-code-size: var(--boxel-font-size-xs);
52
+ --pretui-prose-pre-size: var(--boxel-font-size-xs);
53
+ --pretui-prose-pre-leading: var(--boxel-line-height-xs);
54
+ /* table cells read at reading size; headers are caption in
55
+ tracked caps, the only other tracked caps an answer has */
56
+ --pretui-prose-table-size: var(--boxel-body-font-size);
57
+ --pretui-prose-table-leading: var(--boxel-body-line-height);
58
+ --pretui-prose-th-size: var(--boxel-caption-font-size);
59
+ --pretui-prose-th-leading: var(--boxel-caption-line-height);
60
+ --pretui-prose-th-tracking: 0.04em;
61
+ --pretui-prose-th-case: uppercase;
62
+ --pretui-prose-th-align: bottom;
63
+ --pretui-prose-th-ink: var(--muted-foreground);
64
+ min-width: 0;
65
+ font-size: var(--boxel-body-font-size);
66
+ line-height: var(--boxel-body-line-height);
67
+ color: var(--foreground);
68
+ }
69
+ }
70
+ </style>
71
+ </template>;
@@ -0,0 +1,147 @@
1
+ // Pretui — PlanMark: a plan step's state as a mark: a soft tick, a thin turning ring, a dashed circle.
2
+ import Component from '@glimmer/component';
3
+ import Check from '@cardstack/boxel-icons/check';
4
+ import X from '@cardstack/boxel-icons/x';
5
+ import Minus from '@cardstack/boxel-icons/minus';
6
+
7
+ export type PlanMarkState = 'done' | 'current' | 'next' | 'failed' | 'skipped';
8
+
9
+ export interface PlanMarkSignature {
10
+ Args: {
11
+ state: PlanMarkState;
12
+ /** px. Default 16 */
13
+ size?: number;
14
+ };
15
+ Element: HTMLSpanElement;
16
+ }
17
+
18
+ /**
19
+ * The marks a checklist reads by shape before words: done is a thin tick
20
+ * in a soft tint of the success colour, the step under way a ring that turns (still under reduced
21
+ * motion), what comes next a dashed circle, a failed step a soft tinted disc
22
+ * with a cross, a skipped one a hollow disc with a dash. Decorative: the
23
+ * list says each state in words.
24
+ */
25
+ export class PlanMark extends Component<PlanMarkSignature> {
26
+ get size(): string {
27
+ return String(this.args.size ?? 16);
28
+ }
29
+ get inner(): string {
30
+ return String(Math.round((this.args.size ?? 16) * 0.62));
31
+ }
32
+ <template>
33
+ <span
34
+ class='pretui-planmark'
35
+ data-state={{@state}}
36
+ aria-hidden='true'
37
+ data-test-pretui-plan-mark={{@state}}
38
+ ...attributes
39
+ >
40
+ <svg
41
+ class='pretui-planmark-ring'
42
+ viewBox='0 0 16 16'
43
+ width={{this.size}}
44
+ height={{this.size}}
45
+ >
46
+ <circle cx='8' cy='8' r='6.75' />
47
+ </svg>
48
+ {{#if (this.is @state 'done')}}
49
+ <Check
50
+ class='pretui-planmark-icon'
51
+ width={{this.inner}}
52
+ height={{this.inner}}
53
+ />
54
+ {{else if (this.is @state 'failed')}}
55
+ <X
56
+ class='pretui-planmark-icon'
57
+ width={{this.inner}}
58
+ height={{this.inner}}
59
+ />
60
+ {{else if (this.is @state 'skipped')}}
61
+ <Minus
62
+ class='pretui-planmark-icon'
63
+ width={{this.inner}}
64
+ height={{this.inner}}
65
+ />
66
+ {{/if}}
67
+ </span>
68
+ <style scoped>
69
+ @layer PretComponent {
70
+ .pretui-planmark {
71
+ position: relative;
72
+ display: inline-grid;
73
+ place-items: center;
74
+ flex: none;
75
+ color: var(--pretui-planmark-ink, var(--muted-foreground));
76
+ vertical-align: -0.2em;
77
+ }
78
+ .pretui-planmark > * {
79
+ grid-area: 1 / 1;
80
+ }
81
+ .pretui-planmark-ring {
82
+ display: block;
83
+ overflow: visible;
84
+ }
85
+ .pretui-planmark-ring circle {
86
+ fill: none;
87
+ stroke: currentColor;
88
+ stroke-width: 1.25;
89
+ }
90
+ /* done and failed: a soft tint of the state behind a thin mark, the
91
+ old glyph's weight in the new shape */
92
+ .pretui-planmark[data-state='done'] {
93
+ color: var(--success-ink);
94
+ }
95
+ .pretui-planmark[data-state='done'] .pretui-planmark-ring circle,
96
+ .pretui-planmark[data-state='failed'] .pretui-planmark-ring circle {
97
+ fill: color-mix(in oklch, currentColor 16%, transparent);
98
+ stroke: color-mix(in oklch, currentColor 40%, transparent);
99
+ }
100
+ .pretui-planmark[data-state='done'] .pretui-planmark-icon,
101
+ .pretui-planmark[data-state='failed'] .pretui-planmark-icon {
102
+ stroke-width: 2.5;
103
+ }
104
+ .pretui-planmark[data-state='failed'] {
105
+ color: var(--destructive-ink);
106
+ }
107
+ /* what comes next: a dashed circle, quieter */
108
+ .pretui-planmark[data-state='next'] {
109
+ color: var(--subtle-foreground);
110
+ }
111
+ .pretui-planmark[data-state='next'] .pretui-planmark-ring circle {
112
+ stroke-dasharray: 2.2 2.3;
113
+ }
114
+ .pretui-planmark[data-state='skipped'] {
115
+ color: var(--subtle-foreground);
116
+ }
117
+ .pretui-planmark[data-state='skipped'] .pretui-planmark-icon {
118
+ stroke-width: 2.25;
119
+ }
120
+ .pretui-planmark[data-state='current'] {
121
+ color: var(--success-ink);
122
+ }
123
+ /* under way: a ring with a gap that turns */
124
+ .pretui-planmark[data-state='current'] .pretui-planmark-ring circle {
125
+ stroke-width: 1.5;
126
+ stroke-dasharray: 28 14.4;
127
+ stroke-linecap: round;
128
+ }
129
+ .pretui-planmark[data-state='current'] .pretui-planmark-ring {
130
+ animation: pretui-planmark-turn 1.4s linear infinite;
131
+ }
132
+ @keyframes pretui-planmark-turn {
133
+ to {
134
+ transform: rotate(1turn);
135
+ }
136
+ }
137
+ @media (prefers-reduced-motion: reduce) {
138
+ .pretui-planmark[data-state='current'] .pretui-planmark-ring {
139
+ animation: none;
140
+ }
141
+ }
142
+ }
143
+ </style>
144
+ </template>
145
+
146
+ is = (a: string, b: string) => a === b;
147
+ }
@@ -6,26 +6,203 @@ export interface ProseSignature {
6
6
  Element: HTMLDivElement;
7
7
  }
8
8
 
9
- // The typographic reading surface — styles inline code per Law 3's quieter cousin.
9
+ // The typographic reading surface — styles inline code per Law 3's quieter
10
+ // cousin, and every block a markdown render produces: headings, lists, quotes,
11
+ // links, tables, preformatted code and rules. The content is markup Prose did
12
+ // not render, so every rule reaches it through :deep().
13
+ //
14
+ // A surface that needs another voice (MarkdownSurface, for an assistant's
15
+ // answer) sets these knobs on an ancestor rather than restyling the markup,
16
+ // so there is one set of rules and the two cannot drift apart:
17
+ // --pretui-prose-measure the whole surface's max width (62ch)
18
+ // --pretui-prose-block-measure each text block's max width (none)
19
+ // --pretui-prose-leading body line height (the body role's)
20
+ // --pretui-prose-heading-gap space under a heading (--boxel-sp-2xs)
21
+ // --pretui-prose-h1-size … -h4-size heading sizes; h4 also sizes h5, h6
22
+ // --pretui-prose-h1-leading … -h4-leading heading line heights (1.25)
23
+ // --pretui-prose-h3-tracking, --pretui-prose-h3-case h3 letter spacing
24
+ // and text transform (normal, none)
25
+ // --pretui-prose-code-size inline code size (0.92em)
26
+ // --pretui-prose-pre-size, --pretui-prose-pre-leading code blocks
27
+ // --pretui-prose-table-size, --pretui-prose-table-leading tables
28
+ // --pretui-prose-th-size, -th-leading, -th-tracking, -th-case, -th-ink,
29
+ // -th-align table headers
10
30
  export const Prose: TemplateOnlyComponent<ProseSignature> = <template>
11
31
  <div class='pretui-prose' data-test-pretui-prose ...attributes>{{yield}}</div>
12
32
  <style scoped>
13
33
  @layer PretComponent {
14
34
  .pretui-prose {
15
- max-width: 62ch;
16
- line-height: calc(var(--leading-body, 24px) / var(--text-body, 15px));
35
+ max-width: var(--pretui-prose-measure, 62ch);
36
+ line-height: var(
37
+ --pretui-prose-leading,
38
+ var(--boxel-body-line-height)
39
+ );
40
+ overflow-wrap: break-word;
17
41
  }
18
42
  .pretui-prose :deep(p) {
19
- margin: 0 0 var(--space-4, 11px);
43
+ margin: 0 0 var(--boxel-sp-sm);
44
+ text-wrap: pretty;
45
+ }
46
+ .pretui-prose
47
+ :deep(:is(p, ul, ol, dl, blockquote, h1, h2, h3, h4, h5, h6)) {
48
+ max-inline-size: var(--pretui-prose-block-measure, none);
20
49
  }
21
50
  .pretui-prose :deep(code) {
22
51
  font-family: var(--font-mono);
23
- font-size: 0.92em;
24
- background: var(--inset, var(--boxel-100));
25
- padding: 1px 5px;
26
- border-radius: 5px;
52
+ font-size: var(--pretui-prose-code-size, 0.92em);
53
+ background-color: var(--inset);
54
+ padding: var(--boxel-sp-6xs) var(--boxel-sp-3xs);
55
+ border-radius: var(--boxel-border-radius-xs);
27
56
  box-shadow: var(--pretui-shadow-hairline, 0 0 0 1px var(--border));
28
57
  }
58
+
59
+ /* Headings: a step scale off the body size, tight leading, balanced
60
+ wrap. Real heading styles remove the temptation to fake a heading
61
+ with a bold paragraph, which loses the document's structure. */
62
+ .pretui-prose :deep(:is(h1, h2, h3, h4, h5, h6)) {
63
+ margin: var(--boxel-sp-lg) 0
64
+ var(--pretui-prose-heading-gap, var(--boxel-sp-2xs));
65
+ font-weight: 600;
66
+ letter-spacing: normal;
67
+ text-transform: none;
68
+ text-wrap: balance;
69
+ color: var(--foreground);
70
+ }
71
+ .pretui-prose :deep(h1) {
72
+ font-size: var(--pretui-prose-h1-size, 1.6em);
73
+ line-height: var(--pretui-prose-h1-leading, 1.25);
74
+ }
75
+ .pretui-prose :deep(h2) {
76
+ font-size: var(--pretui-prose-h2-size, 1.35em);
77
+ line-height: var(--pretui-prose-h2-leading, 1.25);
78
+ }
79
+ .pretui-prose :deep(h3) {
80
+ font-size: var(--pretui-prose-h3-size, 1.15em);
81
+ line-height: var(--pretui-prose-h3-leading, 1.25);
82
+ letter-spacing: var(--pretui-prose-h3-tracking, normal);
83
+ text-transform: var(--pretui-prose-h3-case, none);
84
+ }
85
+ .pretui-prose :deep(:is(h4, h5, h6)) {
86
+ font-size: var(--pretui-prose-h4-size, 1em);
87
+ line-height: var(--pretui-prose-h4-leading, 1.25);
88
+ }
89
+
90
+ /* Lists on the spacing scale, nested lists without extra gap. */
91
+ .pretui-prose :deep(ul),
92
+ .pretui-prose :deep(ol) {
93
+ margin: 0 0 var(--boxel-sp-sm);
94
+ padding-inline-start: 1.4em;
95
+ }
96
+ .pretui-prose :deep(li) {
97
+ margin: 0.2em 0;
98
+ }
99
+ .pretui-prose :deep(li > ul),
100
+ .pretui-prose :deep(li > ol) {
101
+ margin-block: 0.2em 0;
102
+ }
103
+ .pretui-prose :deep(li::marker) {
104
+ color: var(--muted-foreground);
105
+ }
106
+ .pretui-prose :deep(li > p) {
107
+ margin: 0;
108
+ }
109
+
110
+ /* Links: the primary hue's ink, which the theme guarantees as text,
111
+ underlined so a link is not told apart by colour alone (WCAG
112
+ 1.4.1). */
113
+ .pretui-prose :deep(a) {
114
+ /* a link is words in the sentence: it wraps like them, even where
115
+ a host's reset makes anchors inline-block */
116
+ display: inline;
117
+ color: var(--primary-ink);
118
+ text-decoration: underline;
119
+ text-decoration-thickness: 1px;
120
+ text-underline-offset: 0.18em;
121
+ }
122
+ .pretui-prose :deep(a:hover) {
123
+ text-decoration-thickness: 2px;
124
+ }
125
+ .pretui-prose :deep(a:focus-visible) {
126
+ outline: 2px solid var(--ring);
127
+ outline-offset: 2px;
128
+ border-radius: var(--boxel-border-radius-2xs);
129
+ }
130
+
131
+ .pretui-prose :deep(blockquote) {
132
+ margin: 0 0 var(--boxel-sp-sm);
133
+ padding: 0 0 0 var(--boxel-sp-sm);
134
+ box-shadow: inset 2px 0 0 var(--border);
135
+ color: var(--muted-foreground);
136
+ }
137
+
138
+ /* Preformatted blocks scroll inside themselves; the page never does. */
139
+ .pretui-prose :deep(pre) {
140
+ margin: 0 0 var(--boxel-sp-sm);
141
+ padding: var(--boxel-sp-2xs) var(--boxel-sp-sm);
142
+ overflow-x: auto;
143
+ border-radius: var(--boxel-border-radius-sm);
144
+ background-color: var(--inset);
145
+ box-shadow: var(--pretui-shadow-hairline, 0 0 0 1px var(--border));
146
+ font-size: var(--pretui-prose-pre-size, 0.9em);
147
+ line-height: var(--pretui-prose-pre-leading, 1.5);
148
+ }
149
+ .pretui-prose :deep(pre code) {
150
+ background-color: transparent;
151
+ padding: 0;
152
+ border-radius: 0;
153
+ box-shadow: none;
154
+ font-size: inherit;
155
+ }
156
+
157
+ /* A table wider than the measure scrolls itself rather than the page. */
158
+ .pretui-prose :deep(table) {
159
+ display: block;
160
+ max-width: 100%;
161
+ overflow-x: auto;
162
+ margin: 0 0 var(--boxel-sp-sm);
163
+ border-collapse: collapse;
164
+ font-size: var(--pretui-prose-table-size, 0.94em);
165
+ line-height: var(--pretui-prose-table-leading, inherit);
166
+ font-variant-numeric: tabular-nums;
167
+ }
168
+ .pretui-prose :deep(th),
169
+ .pretui-prose :deep(td) {
170
+ padding: 0.35em 0.75em;
171
+ text-align: start;
172
+ vertical-align: top;
173
+ box-shadow: inset 0 -1px 0 var(--border);
174
+ }
175
+ .pretui-prose :deep(th) {
176
+ font-size: var(--pretui-prose-th-size, inherit);
177
+ line-height: var(--pretui-prose-th-leading, inherit);
178
+ font-weight: 600;
179
+ letter-spacing: var(--pretui-prose-th-tracking, normal);
180
+ text-transform: var(--pretui-prose-th-case, none);
181
+ vertical-align: var(--pretui-prose-th-align, top);
182
+ color: var(--pretui-prose-th-ink, var(--foreground));
183
+ box-shadow: inset 0 -1px 0 var(--muted-foreground);
184
+ }
185
+
186
+ .pretui-prose :deep(hr) {
187
+ margin: var(--boxel-sp-lg) 0;
188
+ border: 0;
189
+ height: 1px;
190
+ background-color: var(--border);
191
+ }
192
+ .pretui-prose :deep(img) {
193
+ max-width: 100%;
194
+ height: auto;
195
+ border-radius: var(--boxel-border-radius-sm);
196
+ }
197
+
198
+ /* The surface owns its outer edges: no stray margin above the first
199
+ block or below the last. */
200
+ .pretui-prose > :deep(:first-child) {
201
+ margin-block-start: 0;
202
+ }
203
+ .pretui-prose > :deep(:last-child) {
204
+ margin-block-end: 0;
205
+ }
29
206
  }
30
207
  </style>
31
208
  </template>;
@@ -11,11 +11,11 @@ Element: HTMLDivElement
11
11
 
12
12
  No args. Two things happen inside it, and they are both worth stating because they are what you are actually buying.
13
13
 
14
- **`max-width: 62ch`.** The measure — the number of characters per line — is the single largest determinant of whether body copy is comfortable to read, and 62ch sits inside the 45–75 range typography research consistently lands on. Because it is `ch`, it tracks the font actually in use rather than assuming a pixel width. A card that renders prose full-bleed across a 1600px pane is unreadable, and this is the one line that prevents it.
14
+ **`max-width: var(--pretui-prose-measure, 62ch)`.** The measure — the number of characters per line — is the single largest determinant of whether body copy is comfortable to read, and 62ch sits inside the 45–75 range typography research consistently lands on. Because it is `ch`, it tracks the font actually in use rather than assuming a pixel width. A card that renders prose full-bleed across a 1600px pane is unreadable, and this is the one line that prevents it.
15
15
 
16
- **`line-height: calc(var(--leading-body) / var(--text-body))`.** The leading is expressed as a _ratio derived from two absolute tokens_, so a theme sets a body size and a leading in pixels — the way a type scale is actually designed — and the ratio falls out. Setting `line-height` as a bare number would decouple them and let a theme's leading drift when it retunes the size.
16
+ **`line-height: var(--pretui-prose-leading, var(--boxel-body-line-height))`.** The leading is the theme's body role, a unitless ratio, so it scales with the body size the theme sets. A surface that needs a different leading sets the knob instead of overriding the rule.
17
17
 
18
- Paragraph margins (`0 0 var(--space-4)`) and inline `<code>` styling reach the yielded content through `:deep()`, which is the narrow, legitimate use of the escape hatch: the component must style markup it did not render.
18
+ Paragraph margins (`0 0 var(--boxel-sp-sm)`) and inline `<code>` styling reach the yielded content through `:deep()`, which is the narrow, legitimate use of the escape hatch: the component must style markup it did not render.
19
19
 
20
20
  ## Prior art
21
21
 
@@ -34,7 +34,7 @@ No pattern governs it. The relevant criteria are WCAG **1.4.8 Visual Presentatio
34
34
  What is right, and it is genuinely more than most kits:
35
35
 
36
36
  - **`max-width: 62ch` directly serves WCAG 1.4.8**, which asks for no more than 80 characters per line. Comfortably inside it.
37
- - **Leading derived from the type scale** rather than hardcoded means a theme that increases body size gets proportional leading. WCAG **1.4.12** requires content to survive a user stylesheet setting line-height to 1.5× — since the leading here is a ratio on a `div` and paragraph margins are in `--space-4`, user overrides apply cleanly rather than fighting a fixed pixel `line-height`.
37
+ - **Leading from the theme's body role** rather than hardcoded means a theme that changes body size or leading changes it here too. WCAG **1.4.12** requires content to survive a user stylesheet setting line-height to 1.5× — since the leading here is a unitless ratio on a `div` and paragraph margins are in `--boxel-sp-sm`, user overrides apply cleanly rather than fighting a fixed pixel `line-height`.
38
38
  - **Reflow**: `max-width` with no `min-width` means the surface shrinks correctly at 320px.
39
39
 
40
40
  Gaps:
@@ -48,10 +48,8 @@ Gaps:
48
48
 
49
49
  ## Theming
50
50
 
51
- `--leading-body` and `--text-body` (which together produce the line-height ratio), `--space-4` (paragraph spacing), and for inline code: `--font-mono`, `--inset`, `--border`, `--pretui-shadow-hairline`.
51
+ The theme reaches Prose through `--boxel-body-line-height` (leading), `--boxel-sp-sm` (paragraph spacing), `--primary-ink` (links), and for inline code `--font-mono`, `--inset`, `--border` and `--pretui-shadow-hairline`.
52
52
 
53
- The `62ch` measure is fixed and is the one thing a theme most often wants to change — a display-face theme with a wide font may want 58ch, a condensed one 68ch. There is no token for it, so changing the measure means changing the component.
54
-
55
- Because everything else inside is unstyled, **a theme's control over prose is limited to the type scale tokens**; heading, list and link appearance inside a Prose are the browser's, whatever the theme says.
53
+ A surface that embeds Prose tunes it through the `--pretui-prose-*` knobs listed at the top of `prose.gts`: the measure (62ch by default; a display face with a wide font may want 58ch, a condensed one 68ch), the leading, heading sizes, leadings and gap, inline code, code block and table sizes, and table header styles. MarkdownSurface sets only these knobs.
56
54
 
57
55
  The styles sit in `@layer PretComponent`, so a caller's unlayered CSS overrides them without a more specific selector.