@kitnai/chat 0.6.0 → 0.8.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 (211) hide show
  1. package/README.md +9 -9
  2. package/dist/custom-elements.json +1676 -881
  3. package/dist/kitn-chat.es.js +36 -36
  4. package/dist/llms/llms-full.txt +316 -155
  5. package/dist/llms/llms.txt +18 -18
  6. package/dist/schemas/card-envelope.schema.json +14 -0
  7. package/dist/schemas/card-event.schema.json +12 -0
  8. package/dist/schemas/confirm.schema.json +65 -0
  9. package/dist/schemas/embed.schema.json +65 -0
  10. package/dist/schemas/form.result.schema.json +7 -0
  11. package/dist/schemas/form.schema.json +33 -0
  12. package/dist/schemas/link.schema.json +56 -0
  13. package/dist/schemas/task-list.result.schema.json +16 -0
  14. package/dist/schemas/task-list.schema.json +78 -0
  15. package/dist/theme.tokens.css +65 -65
  16. package/dist/tsx-B8rCNbgL.js +1 -0
  17. package/dist/typescript-RycA9KXf.js +1 -0
  18. package/frameworks/react/index.tsx +382 -193
  19. package/frameworks/react/runtime.tsx +2 -2
  20. package/llms-full.txt +316 -155
  21. package/llms.txt +18 -18
  22. package/package.json +5 -2
  23. package/src/components/artifact.stories.tsx +138 -0
  24. package/src/components/artifact.tsx +581 -0
  25. package/src/components/attachments.stories.tsx +7 -8
  26. package/src/components/attachments.tsx +2 -2
  27. package/src/components/card.tsx +110 -0
  28. package/src/components/chain-of-thought.stories.tsx +7 -8
  29. package/src/components/chat-container.stories.tsx +7 -8
  30. package/src/components/chat-container.tsx +4 -0
  31. package/src/components/checkpoint.stories.tsx +7 -8
  32. package/src/components/code-block.stories.tsx +8 -9
  33. package/src/components/component-meta.json +3411 -0
  34. package/src/components/confirm-card.stories.tsx +74 -0
  35. package/src/components/confirm-card.tsx +299 -0
  36. package/src/components/context.stories.tsx +7 -8
  37. package/src/components/conversation-item.stories.tsx +7 -8
  38. package/src/components/conversation-item.tsx +2 -2
  39. package/src/components/conversation-list.stories.tsx +7 -8
  40. package/src/components/conversation-list.tsx +1 -1
  41. package/src/components/embed.tsx +196 -0
  42. package/src/components/empty.stories.tsx +8 -9
  43. package/src/components/feedback-bar.stories.tsx +7 -8
  44. package/src/components/file-tree.stories.tsx +73 -0
  45. package/src/components/file-tree.tsx +383 -0
  46. package/src/components/file-upload.stories.tsx +7 -8
  47. package/src/components/form-widgets.tsx +461 -0
  48. package/src/components/form.tsx +796 -0
  49. package/src/components/image.stories.tsx +7 -8
  50. package/src/components/link-card.tsx +194 -0
  51. package/src/components/loader.stories.tsx +7 -8
  52. package/src/components/markdown.stories.tsx +7 -8
  53. package/src/components/message-narrow.stories.tsx +12 -13
  54. package/src/components/message-skills.stories.tsx +16 -17
  55. package/src/components/message.stories.tsx +17 -18
  56. package/src/components/model-switcher.stories.tsx +7 -8
  57. package/src/components/prompt-input.stories.tsx +8 -9
  58. package/src/components/prompt-suggestion.stories.tsx +7 -8
  59. package/src/components/prompt-suggestion.tsx +3 -3
  60. package/src/components/reasoning.stories.tsx +7 -8
  61. package/src/components/scroll-button.stories.tsx +7 -8
  62. package/src/components/slash-command.stories.tsx +8 -9
  63. package/src/components/slash-command.tsx +2 -2
  64. package/src/components/source.stories.tsx +7 -8
  65. package/src/components/source.tsx +1 -1
  66. package/src/components/task-list-card.stories.tsx +78 -0
  67. package/src/components/task-list-card.tsx +388 -0
  68. package/src/components/text-shimmer.stories.tsx +7 -8
  69. package/src/components/thinking-bar.stories.tsx +7 -8
  70. package/src/components/tool.stories.tsx +7 -8
  71. package/src/components/tool.tsx +2 -2
  72. package/src/components/voice-input.stories.tsx +7 -8
  73. package/src/elements/artifact.stories.tsx +291 -0
  74. package/src/elements/artifact.tsx +72 -0
  75. package/src/elements/{kitn-attachments.stories.tsx → attachments.stories.tsx} +11 -11
  76. package/src/elements/attachments.tsx +4 -4
  77. package/src/elements/card.stories.tsx +118 -0
  78. package/src/elements/card.tsx +40 -0
  79. package/src/elements/catalog.stories.tsx +491 -0
  80. package/src/elements/{kitn-chain-of-thought.stories.tsx → chain-of-thought.stories.tsx} +13 -13
  81. package/src/elements/chain-of-thought.tsx +3 -3
  82. package/src/elements/{kitn-chat-scope-picker.stories.tsx → chat-scope-picker.stories.tsx} +10 -10
  83. package/src/elements/chat-scope-picker.tsx +4 -4
  84. package/src/elements/{kitn-chat-workspace.stories.tsx → chat-workspace.stories.tsx} +71 -29
  85. package/src/elements/chat-workspace.tsx +29 -3
  86. package/src/elements/{kitn-chat.stories.tsx → chat.stories.tsx} +61 -16
  87. package/src/elements/chat.tsx +23 -2
  88. package/src/elements/{kitn-checkpoint.stories.tsx → checkpoint.stories.tsx} +11 -11
  89. package/src/elements/checkpoint.tsx +4 -4
  90. package/src/elements/{kitn-code-block.stories.tsx → code-block.stories.tsx} +10 -10
  91. package/src/elements/code-block.tsx +3 -3
  92. package/src/elements/compiled.css +1 -1
  93. package/src/elements/composed-shell.stories.tsx +316 -0
  94. package/src/elements/confirm-card.stories.tsx +186 -0
  95. package/src/elements/confirm-card.tsx +45 -0
  96. package/src/elements/{kitn-context-meter.stories.tsx → context-meter.stories.tsx} +10 -10
  97. package/src/elements/context-meter.tsx +3 -3
  98. package/src/elements/{kitn-conversation-list.stories.tsx → conversation-list.stories.tsx} +35 -22
  99. package/src/elements/conversation-list.tsx +11 -2
  100. package/src/elements/css.ts +1 -1
  101. package/src/elements/define.tsx +10 -10
  102. package/src/elements/element-meta.json +2649 -0
  103. package/src/elements/element-types.d.ts +251 -125
  104. package/src/elements/embed.stories.tsx +197 -0
  105. package/src/elements/embed.tsx +35 -0
  106. package/src/elements/{kitn-empty.stories.tsx → empty.stories.tsx} +12 -12
  107. package/src/elements/empty.tsx +3 -3
  108. package/src/elements/{kitn-feedback-bar.stories.tsx → feedback-bar.stories.tsx} +11 -11
  109. package/src/elements/feedback-bar.tsx +4 -4
  110. package/src/elements/file-tree.stories.tsx +133 -0
  111. package/src/elements/file-tree.tsx +52 -0
  112. package/src/elements/{kitn-file-upload.stories.tsx → file-upload.stories.tsx} +12 -12
  113. package/src/elements/file-upload.tsx +4 -4
  114. package/src/elements/form.stories.tsx +204 -0
  115. package/src/elements/form.tsx +37 -0
  116. package/src/elements/{kitn-image.stories.tsx → image.stories.tsx} +10 -10
  117. package/src/elements/image.tsx +3 -3
  118. package/src/elements/link-card.stories.tsx +193 -0
  119. package/src/elements/link-card.tsx +34 -0
  120. package/src/elements/{kitn-loader.stories.tsx → loader.stories.tsx} +11 -11
  121. package/src/elements/loader.tsx +3 -3
  122. package/src/elements/{kitn-markdown.stories.tsx → markdown.stories.tsx} +10 -10
  123. package/src/elements/markdown.tsx +3 -3
  124. package/src/elements/{kitn-message-skills.stories.tsx → message-skills.stories.tsx} +10 -10
  125. package/src/elements/message-skills.tsx +3 -3
  126. package/src/elements/{kitn-message.stories.tsx → message.stories.tsx} +12 -12
  127. package/src/elements/message.tsx +5 -5
  128. package/src/elements/{kitn-model-switcher.stories.tsx → model-switcher.stories.tsx} +10 -10
  129. package/src/elements/model-switcher.tsx +5 -5
  130. package/src/elements/{kitn-prompt-input.stories.tsx → prompt-input.stories.tsx} +41 -19
  131. package/src/elements/prompt-input.tsx +5 -5
  132. package/src/elements/{kitn-prompt-suggestions.stories.tsx → prompt-suggestions.stories.tsx} +13 -13
  133. package/src/elements/prompt-suggestions.tsx +4 -4
  134. package/src/elements/{kitn-reasoning.stories.tsx → reasoning.stories.tsx} +10 -10
  135. package/src/elements/reasoning.tsx +4 -4
  136. package/src/elements/register.ts +11 -1
  137. package/src/elements/resizable.stories.tsx +200 -0
  138. package/src/elements/resizable.tsx +264 -0
  139. package/src/elements/{kitn-response-stream.stories.tsx → response-stream.stories.tsx} +10 -10
  140. package/src/elements/response-stream.tsx +4 -4
  141. package/src/elements/{kitn-source-list.stories.tsx → source-list.stories.tsx} +11 -11
  142. package/src/elements/{kitn-source.stories.tsx → source.stories.tsx} +12 -12
  143. package/src/elements/source.tsx +5 -5
  144. package/src/elements/styles.css +140 -1
  145. package/src/elements/task-list-card.stories.tsx +194 -0
  146. package/src/elements/task-list-card.tsx +40 -0
  147. package/src/elements/{kitn-text-shimmer.stories.tsx → text-shimmer.stories.tsx} +10 -10
  148. package/src/elements/text-shimmer.tsx +3 -3
  149. package/src/elements/{kitn-thinking-bar.stories.tsx → thinking-bar.stories.tsx} +11 -11
  150. package/src/elements/thinking-bar.tsx +5 -5
  151. package/src/elements/{kitn-tool.stories.tsx → tool.stories.tsx} +10 -10
  152. package/src/elements/tool.tsx +3 -3
  153. package/src/elements/{kitn-voice-input.stories.tsx → voice-input.stories.tsx} +10 -10
  154. package/src/elements/voice-input.tsx +4 -4
  155. package/src/index.ts +94 -2
  156. package/src/primitives/card-contract.ts +60 -0
  157. package/src/primitives/card-host.tsx +35 -0
  158. package/src/primitives/card-routing.ts +79 -0
  159. package/src/primitives/card-schemas/card-envelope.schema.json +14 -0
  160. package/src/primitives/card-schemas/card-event.schema.json +12 -0
  161. package/src/primitives/card-schemas/confirm.schema.json +65 -0
  162. package/src/primitives/card-schemas/embed.schema.json +65 -0
  163. package/src/primitives/card-schemas/form.result.schema.json +7 -0
  164. package/src/primitives/card-schemas/form.schema.json +33 -0
  165. package/src/primitives/card-schemas/link.schema.json +56 -0
  166. package/src/primitives/card-schemas/task-list.result.schema.json +16 -0
  167. package/src/primitives/card-schemas/task-list.schema.json +78 -0
  168. package/src/primitives/card-validate.ts +95 -0
  169. package/src/primitives/embed-providers.ts +254 -0
  170. package/src/primitives/highlighter.ts +4 -0
  171. package/src/primitives/link-preview.ts +87 -0
  172. package/src/primitives/pdf-preview.ts +121 -0
  173. package/src/stories/chat-panel-layout.stories.tsx +2 -1
  174. package/src/stories/chat-scene.tsx +22 -21
  175. package/src/stories/checkpoint-restore.stories.tsx +10 -10
  176. package/src/stories/conversation-with-reasoning.stories.tsx +4 -4
  177. package/src/stories/conversation-with-sources.stories.tsx +7 -7
  178. package/src/stories/docs/Accessibility.mdx +2 -2
  179. package/src/stories/docs/ForAIAgents.mdx +3 -3
  180. package/src/stories/docs/GettingStarted.mdx +2 -2
  181. package/src/stories/docs/Installation.mdx +2 -2
  182. package/src/stories/docs/Integrations.mdx +29 -29
  183. package/src/stories/docs/Introduction.mdx +3 -3
  184. package/src/stories/docs/Theming.mdx +2 -2
  185. package/src/stories/docs/element-controls.ts +60 -0
  186. package/src/stories/docs/theme-editor/theme-editor.tsx +1 -0
  187. package/src/stories/examples/ChoosingComponents.mdx +94 -0
  188. package/src/stories/examples/sample-data.ts +79 -0
  189. package/src/stories/message-actions.stories.tsx +13 -13
  190. package/src/stories/pattern-centered-conversation.stories.tsx +3 -3
  191. package/src/stories/pattern-docked-widget.stories.tsx +1 -1
  192. package/src/stories/pattern-empty-state.stories.tsx +3 -3
  193. package/src/stories/prompt-input-variants.stories.tsx +13 -13
  194. package/src/stories/streaming-response.stories.tsx +3 -3
  195. package/src/stories/typography.stories.tsx +4 -4
  196. package/src/ui/avatar.stories.tsx +7 -8
  197. package/src/ui/badge.stories.tsx +7 -8
  198. package/src/ui/button.stories.tsx +8 -9
  199. package/src/ui/button.tsx +1 -0
  200. package/src/ui/collapsible.stories.tsx +6 -7
  201. package/src/ui/dropdown.stories.tsx +6 -7
  202. package/src/ui/hover-card.stories.tsx +6 -7
  203. package/src/ui/resizable.stories.tsx +74 -9
  204. package/src/ui/resizable.tsx +351 -71
  205. package/src/ui/scroll-area.stories.tsx +6 -7
  206. package/src/ui/scroll-area.tsx +3 -1
  207. package/src/ui/separator.stories.tsx +7 -8
  208. package/src/ui/skeleton.stories.tsx +7 -8
  209. package/src/ui/textarea.stories.tsx +6 -7
  210. package/src/ui/tooltip.stories.tsx +8 -9
  211. package/theme.css +65 -65
@@ -1,7 +1,7 @@
1
1
  <!-- AUTO-GENERATED by scripts/gen-llms.mjs — do not edit by hand. Run `npm run build`. -->
2
2
  # @kitnai/chat
3
3
 
4
- > Framework-agnostic, Shadow-DOM web components for building AI chat interfaces — works in React, Vue, Angular, Svelte, or plain HTML. 28 `kitn-*` custom elements: streaming responses, markdown + code rendering, reasoning/tool panels, attachments, conversation sidebar, voice input. Zero framework dependency for consumers; the SolidJS runtime it is authored in is bundled in, so the host needs nothing.
4
+ > Framework-agnostic, Shadow-DOM web components for building AI chat interfaces — works in React, Vue, Angular, Svelte, or plain HTML. 38 `kitn-*` custom elements: streaming responses, markdown + code rendering, reasoning/tool panels, attachments, conversation sidebar, voice input. Zero framework dependency for consumers; the SolidJS runtime it is authored in is bundled in, so the host needs nothing.
5
5
 
6
6
  ## Install
7
7
 
@@ -16,11 +16,11 @@ npm install solid-js
16
16
  This is the single most common mistake. Arrays and objects (`messages`, `models`, `context`, `suggestions`, `slashCommands`, …) MUST be assigned as JavaScript properties on the element. They CANNOT be passed as HTML attributes — an HTML attribute is always a string and will be ignored or mis-parsed.
17
17
 
18
18
  ```js
19
- const chat = document.querySelector('kitn-chat');
19
+ const chat = document.querySelector('kc-chat');
20
20
  chat.messages = [{ id: '1', role: 'assistant', content: 'Hi!' }]; // ✅ property
21
21
  ```
22
22
  ```html
23
- <kitn-chat messages="[...]"></kitn-chat> <!-- ❌ never works -->
23
+ <kc-chat messages="[...]"></kc-chat> <!-- ❌ never works -->
24
24
  ```
25
25
 
26
26
  Only scalar values (string/number/boolean) work as attributes (e.g. `placeholder`, `loading`, `theme`).
@@ -30,12 +30,12 @@ Only scalar values (string/number/boolean) work as attributes (e.g. `placeholder
30
30
  **Layer 1 — batteries-included web components** (`import '@kitnai/chat/elements'`):
31
31
  Drop an element into any framework (React, Vue, plain HTML). Data in via JS properties; interactions out via non-bubbling CustomEvents.
32
32
 
33
- - `<kitn-chat>` — full chat UI (message list + prompt input). The primary starting point.
34
- - `<kitn-conversation-list>` — sidebar conversation browser with group support.
35
- - `<kitn-prompt-input>` — standalone composer with send button.
33
+ - `<kc-chat>` — full chat UI (message list + prompt input). The primary starting point.
34
+ - `<kc-conversations>` — sidebar conversation browser with group support.
35
+ - `<kc-prompt-input>` — standalone composer with send button.
36
36
 
37
37
  **Layer 2 — composable primitives** (`import { … } from '@kitnai/chat'`):
38
- All 28 elements are also exported individually. Use them for custom layouts or features `<kitn-chat>` does not expose (ChainOfThought, FeedbackBar, ThinkingBar, VoiceInput, …). Your bundler tree-shakes the rest.
38
+ All 38 elements are also exported individually. Use them for custom layouts or features `<kc-chat>` does not expose (ChainOfThought, FeedbackBar, ThinkingBar, VoiceInput, …). Your bundler tree-shakes the rest.
39
39
 
40
40
  ## Key rules for the web components
41
41
 
@@ -43,9 +43,9 @@ All 28 elements are also exported individually. Use them for custom layouts or f
43
43
  2. **Events are non-bubbling `CustomEvent`s** — listen directly on the element:
44
44
  `chat.addEventListener('submit', (e) => console.log(e.detail.value))`
45
45
  3. **`theme` attribute** (`'light' | 'dark' | 'auto'`) works on every element. Default `auto` follows `prefers-color-scheme`.
46
- 4. **Theming via CSS custom properties** — override `--kitn-color-*` tokens on `:root`; they pierce Shadow DOM.
46
+ 4. **Theming via CSS custom properties** — override `--kc-color-*` tokens on `:root`; they pierce Shadow DOM.
47
47
 
48
- ## ChatMessage schema (required for `<kitn-chat>`)
48
+ ## ChatMessage schema (required for `<kc-chat>`)
49
49
 
50
50
  ```ts
51
51
  interface ChatMessage {
@@ -64,31 +64,31 @@ interface ChatMessage {
64
64
  **Plain HTML / CDN**
65
65
  ```html
66
66
  <script type="module" src="https://unpkg.com/@kitnai/chat/elements"></script>
67
- <kitn-chat style="display:block;height:100vh"></kitn-chat>
67
+ <kc-chat style="display:block;height:100vh"></kc-chat>
68
68
  <script type="module">
69
- const chat = document.querySelector('kitn-chat');
69
+ const chat = document.querySelector('kc-chat');
70
70
  chat.messages = [];
71
71
  </script>
72
72
  ```
73
73
 
74
74
  **React** — typed wrappers auto-set properties and expose `on<Event>` props:
75
75
  ```tsx
76
- import { KitnChat } from '@kitnai/chat/react';
77
- <KitnChat messages={messages} onSubmit={(e) => send(e.detail.value)} />
76
+ import { KcChat } from '@kitnai/chat/react';
77
+ <KcChat messages={messages} onSubmit={(e) => send(e.detail.value)} />
78
78
  ```
79
79
 
80
80
  **Vue** — use the element directly; pass arrays via `.prop`:
81
81
  ```vue
82
- <kitn-chat :messages.prop="messages" @submit="send" />
82
+ <kc-chat :messages.prop="messages" @submit="send" />
83
83
  ```
84
84
 
85
85
  ## Theming
86
86
 
87
87
  ```css
88
88
  :root {
89
- --kitn-color-background: #0f0f0f;
90
- --kitn-color-primary: #7c3aed;
91
- --kitn-color-muted: #1e1e1e;
89
+ --kc-color-background: #0f0f0f;
90
+ --kc-color-primary: #7c3aed;
91
+ --kc-color-muted: #1e1e1e;
92
92
  }
93
93
  ```
94
94
 
@@ -97,7 +97,7 @@ For Tailwind builds: `@import "@kitnai/chat/theme.css"` in your CSS.
97
97
 
98
98
  ## Docs
99
99
 
100
- - Full element reference (all 28 elements, every prop/event): ./llms-full.txt — https://kitn.dev/llms-full.txt
100
+ - Full element reference (all 38 elements, every prop/event): ./llms-full.txt — https://kitn.dev/llms-full.txt
101
101
  - Machine-readable Custom Elements Manifest: https://unpkg.com/@kitnai/chat/dist/custom-elements.json
102
102
  - Working examples: https://github.com/kitn-ai/chat/tree/main/examples
103
103
  - Storybook: https://storybook.kitn.dev
@@ -0,0 +1,14 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://kitn.ai/schemas/card/card-envelope.schema.json",
4
+ "title": "CardEnvelope",
5
+ "description": "A card the agent/server asks the chat to render. `data` validates against the per-type schema.",
6
+ "type": "object",
7
+ "required": ["type", "id", "data"],
8
+ "properties": {
9
+ "type": { "type": "string", "minLength": 1 },
10
+ "id": { "type": "string", "minLength": 1 },
11
+ "data": {},
12
+ "title": { "type": "string" }
13
+ }
14
+ }
@@ -0,0 +1,12 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://kitn.ai/schemas/card/card-event.schema.json",
4
+ "title": "CardEvent",
5
+ "description": "An event a card emits up to the host. `kind` discriminates the payload.",
6
+ "type": "object",
7
+ "required": ["kind"],
8
+ "properties": {
9
+ "kind": { "enum": ["ready", "submit-data", "action", "send-prompt", "open", "resize", "state", "dismiss", "error"] },
10
+ "cardId": { "type": "string" }
11
+ }
12
+ }
@@ -0,0 +1,65 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://kitn.ai/schemas/card/confirm.schema.json",
4
+ "title": "ConfirmCardData",
5
+ "description": "Data payload for a `confirm` card (CardEnvelope.data when type='confirm').",
6
+ "type": "object",
7
+ "required": ["actions"],
8
+ "properties": {
9
+ "heading": {
10
+ "type": "string",
11
+ "description": "Optional in-body heading. Distinct from CardEnvelope.title (the card chrome title)."
12
+ },
13
+ "body": {
14
+ "type": "string",
15
+ "description": "Body text. Plain text in v1 (rendered safely; no HTML injection)."
16
+ },
17
+ "tone": {
18
+ "type": "string",
19
+ "enum": ["default", "warning", "danger"],
20
+ "default": "default",
21
+ "description": "Overall card tone; 'danger' adds a warning icon + accent for destructive approvals.",
22
+ "x-kc-control": "tone"
23
+ },
24
+ "actions": {
25
+ "type": "array",
26
+ "minItems": 1,
27
+ "maxItems": 4,
28
+ "description": "The choice set. Rendered as buttons in order; max 4 keeps it a decision, not a menu.",
29
+ "items": {
30
+ "type": "object",
31
+ "required": ["id", "label"],
32
+ "properties": {
33
+ "id": {
34
+ "type": "string",
35
+ "minLength": 1,
36
+ "description": "Emitted as CardEvent.action. Must be unique within `actions`.",
37
+ "x-kc-unique": true
38
+ },
39
+ "label": { "type": "string", "minLength": 1, "description": "Visible button label." },
40
+ "style": {
41
+ "type": "string",
42
+ "enum": ["primary", "default", "destructive"],
43
+ "default": "default",
44
+ "description": "Button emphasis. 'destructive' = red/danger; 'primary' = filled accent.",
45
+ "x-kc-control": "button-style"
46
+ },
47
+ "payload": {
48
+ "description": "Optional opaque payload echoed back in CardEvent.payload (any JSON)."
49
+ },
50
+ "default": {
51
+ "type": "boolean",
52
+ "default": false,
53
+ "description": "If true, this action is the keyboard default (Enter) and gets initial focus. At most one should be true; the card uses the first if several are.",
54
+ "x-kc-default-action": true
55
+ }
56
+ }
57
+ }
58
+ },
59
+ "dismissible": {
60
+ "type": "boolean",
61
+ "default": false,
62
+ "description": "Show a close affordance that emits the `dismiss` verb."
63
+ }
64
+ }
65
+ }
@@ -0,0 +1,65 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://kitn.ai/schemas/card/embed.schema.json",
4
+ "title": "EmbedCardData",
5
+ "description": "Lazy media-embed payload (YouTube / Vimeo / generic player URL).",
6
+ "type": "object",
7
+ "x-kc-card-type": "embed",
8
+ "x-kc-contract-version": "1",
9
+ "required": ["provider"],
10
+ "additionalProperties": false,
11
+ "properties": {
12
+ "provider": {
13
+ "type": "string",
14
+ "enum": ["youtube", "vimeo", "generic"],
15
+ "description": "Media provider. 'generic' frames `url` directly (must be an https embeddable player URL whose origin is app-allowlisted).",
16
+ "x-kc-control": "select"
17
+ },
18
+ "id": {
19
+ "type": "string",
20
+ "description": "Provider video id (required for youtube/vimeo when `url` is absent). e.g. 'dQw4w9WgXcQ'.",
21
+ "maxLength": 64,
22
+ "pattern": "^[A-Za-z0-9_-]+$"
23
+ },
24
+ "url": {
25
+ "type": "string",
26
+ "format": "uri",
27
+ "description": "Full media/watch URL. For youtube/vimeo it is parsed to an id; for 'generic' it is the embeddable player src (https only).",
28
+ "x-kc-format": "url"
29
+ },
30
+ "title": {
31
+ "type": "string",
32
+ "description": "Accessible title for the player iframe + the poster label. Strongly recommended for a11y.",
33
+ "maxLength": 300
34
+ },
35
+ "poster": {
36
+ "type": "string",
37
+ "format": "uri",
38
+ "description": "Thumbnail shown before play. When omitted, youtube/vimeo derive a default thumbnail; 'generic' shows a neutral play placeholder.",
39
+ "x-kc-format": "url"
40
+ },
41
+ "start": {
42
+ "type": "integer",
43
+ "minimum": 0,
44
+ "description": "Optional start offset in seconds.",
45
+ "x-kc-unit": "seconds"
46
+ },
47
+ "aspectRatio": {
48
+ "type": "string",
49
+ "enum": ["16:9", "4:3", "1:1", "9:16"],
50
+ "default": "16:9",
51
+ "description": "Player box aspect ratio (CSS aspect-ratio).",
52
+ "x-kc-control": "select"
53
+ }
54
+ },
55
+ "allOf": [
56
+ {
57
+ "if": { "properties": { "provider": { "const": "generic" } } },
58
+ "then": { "required": ["url"] }
59
+ },
60
+ {
61
+ "if": { "properties": { "provider": { "enum": ["youtube", "vimeo"] } } },
62
+ "then": { "anyOf": [{ "required": ["id"] }, { "required": ["url"] }] }
63
+ }
64
+ ]
65
+ }
@@ -0,0 +1,7 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://kitn.ai/schemas/card/form.result.schema.json",
4
+ "title": "kc-form submit-data payload",
5
+ "description": "The CardEvent {kind:'submit-data'} `data` for a form card: an object that validates against the form-definition schema that was sent down in CardEnvelope.data. Standard JSON Schema validation (type/enum/required/min-max/length/pattern) holds. Optional empty strings are omitted.",
6
+ "type": "object"
7
+ }
@@ -0,0 +1,33 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://kitn.ai/schemas/card/form.schema.json",
4
+ "title": "kc-form data (a form definition)",
5
+ "description": "The CardEnvelope.data for a card of type 'form': a JSON Schema (type:'object') describing the fields kc-form renders, plus optional x-kc-* UI hints. The same schema validates the submission.",
6
+ "type": "object",
7
+ "required": ["type", "properties"],
8
+ "properties": {
9
+ "type": { "const": "object" },
10
+ "title": { "type": "string" },
11
+ "description": { "type": "string" },
12
+ "required": { "type": "array", "items": { "type": "string" } },
13
+ "properties": {
14
+ "type": "object"
15
+ },
16
+ "x-kc-order": { "type": "array", "items": { "type": "string" } },
17
+ "x-kc-inlineMax": { "type": "integer", "minimum": 1 },
18
+ "x-kc-submitLabel": { "type": "string" },
19
+ "x-kc-dismissible": { "type": "boolean" },
20
+ "x-kc-actions": {
21
+ "type": "array",
22
+ "items": {
23
+ "type": "object",
24
+ "required": ["id", "label"],
25
+ "properties": {
26
+ "id": { "type": "string" },
27
+ "label": { "type": "string" },
28
+ "variant": { "enum": ["default", "ghost", "outline"] }
29
+ }
30
+ }
31
+ }
32
+ }
33
+ }
@@ -0,0 +1,56 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://kitn.ai/schemas/card/link.schema.json",
4
+ "title": "LinkCardData",
5
+ "description": "Rich link / Open-Graph preview payload. The card renders from this; it never fetches.",
6
+ "type": "object",
7
+ "x-kc-card-type": "link",
8
+ "x-kc-contract-version": "1",
9
+ "required": ["url"],
10
+ "additionalProperties": false,
11
+ "properties": {
12
+ "url": {
13
+ "type": "string",
14
+ "format": "uri",
15
+ "description": "Canonical destination. Opened via the contract `open` verb (target 'tab').",
16
+ "x-kc-format": "url"
17
+ },
18
+ "title": {
19
+ "type": "string",
20
+ "description": "OG title (og:title). Falls back to the domain when absent.",
21
+ "maxLength": 300
22
+ },
23
+ "description": {
24
+ "type": "string",
25
+ "description": "OG description (og:description). Clamped to 3 lines in the UI.",
26
+ "maxLength": 1000
27
+ },
28
+ "image": {
29
+ "type": "string",
30
+ "format": "uri",
31
+ "description": "Preview image (og:image). Optional; the card degrades gracefully when missing or it fails to load.",
32
+ "x-kc-format": "url"
33
+ },
34
+ "imageAlt": {
35
+ "type": "string",
36
+ "description": "Alt text for the preview image. Defaults to the title (or empty = decorative) when omitted.",
37
+ "maxLength": 300
38
+ },
39
+ "favicon": {
40
+ "type": "string",
41
+ "format": "uri",
42
+ "description": "Site favicon shown next to the domain.",
43
+ "x-kc-format": "url"
44
+ },
45
+ "domain": {
46
+ "type": "string",
47
+ "description": "Display domain (e.g. 'example.com'). Derived from `url` when omitted.",
48
+ "maxLength": 253
49
+ },
50
+ "siteName": {
51
+ "type": "string",
52
+ "description": "OG site name (og:site_name). Shown in place of the domain when present.",
53
+ "maxLength": 200
54
+ }
55
+ }
56
+ }
@@ -0,0 +1,16 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://kitn.ai/schemas/card/task-list.result.schema.json",
4
+ "title": "TaskListCardResult",
5
+ "description": "Payload of CardEvent { kind: 'submit-data' } from a task-list card.",
6
+ "type": "object",
7
+ "required": ["selected"],
8
+ "properties": {
9
+ "selected": {
10
+ "type": "array",
11
+ "description": "Ids of the checked tasks, in the order they appear in `tasks`. Subset of the input task ids.",
12
+ "items": { "type": "string", "minLength": 1 },
13
+ "uniqueItems": true
14
+ }
15
+ }
16
+ }
@@ -0,0 +1,78 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://kitn.ai/schemas/card/task-list.schema.json",
4
+ "title": "TaskListCardData",
5
+ "description": "Data payload for a `task-list` card (CardEnvelope.data when type='task-list').",
6
+ "type": "object",
7
+ "required": ["tasks"],
8
+ "properties": {
9
+ "mode": {
10
+ "type": "string",
11
+ "enum": ["select"],
12
+ "default": "select",
13
+ "description": "v1 supports only 'select' (toggle + confirm). 'progress' (live AG-UI status) is a future enum value; restricting it now keeps the wire forward-compatible.",
14
+ "x-kc-mode": true
15
+ },
16
+ "heading": {
17
+ "type": "string",
18
+ "description": "Optional in-body heading; distinct from CardEnvelope.title."
19
+ },
20
+ "tasks": {
21
+ "type": "array",
22
+ "minItems": 1,
23
+ "description": "The selectable rows, rendered in order.",
24
+ "items": {
25
+ "type": "object",
26
+ "required": ["id", "label"],
27
+ "properties": {
28
+ "id": {
29
+ "type": "string",
30
+ "minLength": 1,
31
+ "description": "Stable id; the selected ids are returned in the result. Unique within `tasks`.",
32
+ "x-kc-unique": true
33
+ },
34
+ "label": { "type": "string", "minLength": 1, "description": "Row label." },
35
+ "description": { "type": "string", "description": "Optional secondary line under the label." },
36
+ "checked": {
37
+ "type": "boolean",
38
+ "default": false,
39
+ "description": "Initial checked state of the row."
40
+ },
41
+ "disabled": {
42
+ "type": "boolean",
43
+ "default": false,
44
+ "description": "Row is shown but not toggleable (and excluded from select-all)."
45
+ }
46
+ }
47
+ }
48
+ },
49
+ "selectAll": {
50
+ "type": "boolean",
51
+ "default": false,
52
+ "description": "Render a master select-all checkbox above the list.",
53
+ "x-kc-control": "select-all"
54
+ },
55
+ "confirmLabel": {
56
+ "type": "string",
57
+ "default": "Confirm",
58
+ "description": "Label for the confirm button."
59
+ },
60
+ "allowEmpty": {
61
+ "type": "boolean",
62
+ "default": false,
63
+ "description": "If true, confirm is enabled with zero selected (emits { selected: [] }). If false, confirm is disabled until >=1 selected."
64
+ },
65
+ "min": {
66
+ "type": "integer",
67
+ "minimum": 0,
68
+ "description": "Optional minimum number that must be selected to confirm.",
69
+ "x-kc-select-min": true
70
+ },
71
+ "max": {
72
+ "type": "integer",
73
+ "minimum": 1,
74
+ "description": "Optional maximum selectable; further toggles are blocked once reached.",
75
+ "x-kc-select-max": true
76
+ }
77
+ }
78
+ }
@@ -3,64 +3,64 @@
3
3
  are self-themed and don't need this; it themes host-page chrome / rebrands). */
4
4
 
5
5
  :root {
6
- --color-background: var(--kitn-color-background, hsl(0 0% 100%));
7
- --color-foreground: var(--kitn-color-foreground, hsl(240 10% 3.9%));
8
- --color-card: var(--kitn-color-card, hsl(0 0% 100%));
9
- --color-card-foreground: var(--kitn-color-card-foreground, hsl(240 10% 3.9%));
10
- --color-popover: var(--kitn-color-popover, hsl(0 0% 100%));
11
- --color-popover-foreground: var(--kitn-color-popover-foreground, hsl(240 10% 3.9%));
12
- --color-primary: var(--kitn-color-primary, hsl(240 5.9% 10%));
13
- --color-primary-foreground: var(--kitn-color-primary-foreground, hsl(0 0% 98%));
14
- --color-secondary: var(--kitn-color-secondary, hsl(240 4.8% 95.9%));
15
- --color-secondary-foreground: var(--kitn-color-secondary-foreground, hsl(240 5.9% 10%));
16
- --color-muted: var(--kitn-color-muted, hsl(240 4.8% 95.9%));
17
- --color-muted-foreground: var(--kitn-color-muted-foreground, hsl(240 3.8% 43%));
18
- --color-accent: var(--kitn-color-accent, hsl(240 4.8% 95.9%));
19
- --color-accent-foreground: var(--kitn-color-accent-foreground, hsl(240 5.9% 10%));
20
- --color-destructive: var(--kitn-color-destructive, hsl(0 84.2% 60.2%));
21
- --color-destructive-foreground: var(--kitn-color-destructive-foreground, hsl(0 0% 98%));
22
- --color-border: var(--kitn-color-border, hsl(240 5.9% 90%));
23
- --color-input: var(--kitn-color-input, hsl(240 5.9% 90%));
6
+ --color-background: var(--kc-color-background, hsl(0 0% 100%));
7
+ --color-foreground: var(--kc-color-foreground, hsl(240 10% 3.9%));
8
+ --color-card: var(--kc-color-card, hsl(0 0% 100%));
9
+ --color-card-foreground: var(--kc-color-card-foreground, hsl(240 10% 3.9%));
10
+ --color-popover: var(--kc-color-popover, hsl(0 0% 100%));
11
+ --color-popover-foreground: var(--kc-color-popover-foreground, hsl(240 10% 3.9%));
12
+ --color-primary: var(--kc-color-primary, hsl(240 5.9% 10%));
13
+ --color-primary-foreground: var(--kc-color-primary-foreground, hsl(0 0% 98%));
14
+ --color-secondary: var(--kc-color-secondary, hsl(240 4.8% 95.9%));
15
+ --color-secondary-foreground: var(--kc-color-secondary-foreground, hsl(240 5.9% 10%));
16
+ --color-muted: var(--kc-color-muted, hsl(240 4.8% 95.9%));
17
+ --color-muted-foreground: var(--kc-color-muted-foreground, hsl(240 3.8% 43%));
18
+ --color-accent: var(--kc-color-accent, hsl(240 4.8% 95.9%));
19
+ --color-accent-foreground: var(--kc-color-accent-foreground, hsl(240 5.9% 10%));
20
+ --color-destructive: var(--kc-color-destructive, hsl(0 72% 45%));
21
+ --color-destructive-foreground: var(--kc-color-destructive-foreground, hsl(0 0% 98%));
22
+ --color-border: var(--kc-color-border, hsl(240 5.9% 90%));
23
+ --color-input: var(--kc-color-input, hsl(240 5.9% 90%));
24
24
  /* Focus ring — a deliberate blue (not a neutral) so keyboard focus is always
25
25
  obvious and on-brand in both modes. Light uses a strong blue; dark uses a
26
26
  brighter one for contrast on dark surfaces. Both clear WCAG 2.1 non-text
27
- contrast (≥3:1) against the kit's backgrounds. Override via --kitn-color-ring. */
28
- --color-ring: var(--kitn-color-ring, hsl(217 91% 53%));
27
+ contrast (≥3:1) against the kit's backgrounds. Override via --kc-color-ring. */
28
+ --color-ring: var(--kc-color-ring, hsl(217 91% 53%));
29
29
  /* Custom scrollbars — thin, rounded, subtle; thumb strengthens on hover. A
30
30
  consistent cross-platform look (the kit styles its OWN scroll regions inside
31
31
  the shadow root; the track stays transparent so nothing is forced where no
32
- scrollbar is needed). Override via --kitn-color-scrollbar-thumb(-hover). */
33
- --color-scrollbar-thumb: var(--kitn-color-scrollbar-thumb, hsl(240 5% 80%));
34
- --color-scrollbar-thumb-hover: var(--kitn-color-scrollbar-thumb-hover, hsl(240 4% 64%));
35
- --color-sidebar: var(--kitn-color-sidebar, hsl(0 0% 100%));
32
+ scrollbar is needed). Override via --kc-color-scrollbar-thumb(-hover). */
33
+ --color-scrollbar-thumb: var(--kc-color-scrollbar-thumb, hsl(240 5% 80%));
34
+ --color-scrollbar-thumb-hover: var(--kc-color-scrollbar-thumb-hover, hsl(240 4% 64%));
35
+ --color-sidebar: var(--kc-color-sidebar, hsl(0 0% 100%));
36
36
  /* Inline `code` accent. Blue text on a translucent blue chip. */
37
- --color-code-foreground: var(--kitn-color-code-foreground, hsl(224.3 76.3% 48%));
37
+ --color-code-foreground: var(--kc-color-code-foreground, hsl(224.3 76.3% 48%));
38
38
  /* Tool/status chip hues. Each chip is hue text over a 15% translucent fill of
39
39
  the SAME hue (set in tool.tsx). The bare hue is too light to reach WCAG AA
40
40
  (4.5:1) on the faint fill in LIGHT mode, so the light values are darkened;
41
41
  dark mode keeps brighter hues for AA on the dark fill. Override via
42
- --kitn-color-tool-* to retheme. */
43
- --color-tool-blue: var(--kitn-color-tool-blue, hsl(217 91% 38%));
44
- --color-tool-amber: var(--kitn-color-tool-amber, hsl(38 92% 28%));
45
- --color-tool-green: var(--kitn-color-tool-green, hsl(142 71% 26%));
46
- --color-tool-red: var(--kitn-color-tool-red, hsl(0 72% 42%));
47
- --radius: var(--kitn-radius, 0.6rem);
42
+ --kc-color-tool-* to retheme. */
43
+ --color-tool-blue: var(--kc-color-tool-blue, hsl(217 91% 38%));
44
+ --color-tool-amber: var(--kc-color-tool-amber, hsl(38 92% 28%));
45
+ --color-tool-green: var(--kc-color-tool-green, hsl(142 71% 26%));
46
+ --color-tool-red: var(--kc-color-tool-red, hsl(0 72% 42%));
47
+ --radius: var(--kc-radius, 0.6rem);
48
48
  --radius-sm: calc(var(--radius) - 4px);
49
49
  --radius-md: calc(var(--radius) - 2px);
50
50
  --radius-lg: var(--radius);
51
51
  --radius-xl: calc(var(--radius) + 4px);
52
52
  /* Typography scale — semantic sizes shared by all components. Each generates a
53
53
  Tailwind utility (text-caption / text-meta / text-body / text-title). To
54
- restyle the kit's typography, override the namespaced --kitn-text-* token on
55
- :root (e.g. `--kitn-text-body: 0.9375rem`) — it pierces the Shadow DOM via the
56
- var() fallback, exactly like the --kitn-color-* tokens. The bare --text-*
54
+ restyle the kit's typography, override the namespaced --kc-text-* token on
55
+ :root (e.g. `--kc-text-body: 0.9375rem`) — it pierces the Shadow DOM via the
56
+ var() fallback, exactly like the --kc-color-* tokens. The bare --text-*
57
57
  names stay internal so a host's own --text-* can't collide. (Message/markdown/
58
58
  input reading size also scales with the `proseSize` prop; these tokens cover
59
59
  the fixed chrome & controls.) */
60
- --text-caption: var(--kitn-text-caption, 0.6875rem); --text-caption--line-height: 1rem; /* 11px — micro labels, badges, sub-counts */
61
- --text-meta: var(--kitn-text-meta, 0.75rem); --text-meta--line-height: 1.1rem; /* 12px — controls, toggles, switchers, captions */
62
- --text-body: var(--kitn-text-body, 0.875rem); --text-body--line-height: 1.45rem; /* 14px — primary reading text */
63
- --text-title: var(--kitn-text-title, 1rem); --text-title--line-height: 1.5rem; /* 16px — emphasis / headers */
60
+ --text-caption: var(--kc-text-caption, 0.6875rem); --text-caption--line-height: 1rem; /* 11px — micro labels, badges, sub-counts */
61
+ --text-meta: var(--kc-text-meta, 0.75rem); --text-meta--line-height: 1.1rem; /* 12px — controls, toggles, switchers, captions */
62
+ --text-body: var(--kc-text-body, 0.875rem); --text-body--line-height: 1.45rem; /* 14px — primary reading text */
63
+ --text-title: var(--kc-text-title, 1rem); --text-title--line-height: 1.5rem; /* 16px — emphasis / headers */
64
64
  }
65
65
 
66
66
  @keyframes typing { 0%,100% { transform: translateY(0); opacity: .5 } 50% { transform: translateY(-2px); opacity: 1 } }
@@ -78,35 +78,35 @@
78
78
  @keyframes collapsible-down { from { height: 0; opacity: 0 } to { height: var(--kb-collapsible-content-height); opacity: 1 } }
79
79
  @keyframes collapsible-up { from { height: var(--kb-collapsible-content-height); opacity: 1 } to { height: 0; opacity: 0 } }
80
80
  .dark {
81
- --color-background: var(--kitn-color-background, hsl(50 2% 9%));
82
- --color-foreground: var(--kitn-color-foreground, hsl(0 0% 98%));
83
- --color-card: var(--kitn-color-card, hsl(45 4% 12%));
84
- --color-card-foreground: var(--kitn-color-card-foreground, hsl(0 0% 98%));
85
- --color-popover: var(--kitn-color-popover, hsl(45 4% 12%));
86
- --color-popover-foreground: var(--kitn-color-popover-foreground, hsl(0 0% 98%));
87
- --color-primary: var(--kitn-color-primary, hsl(0 0% 98%));
88
- --color-primary-foreground: var(--kitn-color-primary-foreground, hsl(45 4% 11%));
89
- --color-secondary: var(--kitn-color-secondary, hsl(45 4% 17%));
90
- --color-secondary-foreground: var(--kitn-color-secondary-foreground, hsl(0 0% 98%));
91
- --color-muted: var(--kitn-color-muted, hsl(45 4% 17%));
92
- --color-muted-foreground: var(--kitn-color-muted-foreground, hsl(45 4% 64%));
93
- --color-accent: var(--kitn-color-accent, hsl(45 4% 17%));
94
- --color-accent-foreground: var(--kitn-color-accent-foreground, hsl(0 0% 98%));
95
- --color-destructive: var(--kitn-color-destructive, hsl(0 62.8% 30.6%));
96
- --color-destructive-foreground: var(--kitn-color-destructive-foreground, hsl(0 0% 98%));
97
- --color-border: var(--kitn-color-border, hsl(45 4% 17%));
98
- --color-input: var(--kitn-color-input, hsl(45 4% 17%));
99
- --color-ring: var(--kitn-color-ring, hsl(217 91% 68%));
100
- --color-scrollbar-thumb: var(--kitn-color-scrollbar-thumb, hsl(45 3% 30%));
101
- --color-scrollbar-thumb-hover: var(--kitn-color-scrollbar-thumb-hover, hsl(45 3% 42%));
102
- --color-sidebar: var(--kitn-color-sidebar, hsl(50 2% 7%));
103
- --color-code-foreground: var(--kitn-color-code-foreground, hsl(213 94% 78%));
81
+ --color-background: var(--kc-color-background, hsl(50 2% 9%));
82
+ --color-foreground: var(--kc-color-foreground, hsl(0 0% 98%));
83
+ --color-card: var(--kc-color-card, hsl(45 4% 12%));
84
+ --color-card-foreground: var(--kc-color-card-foreground, hsl(0 0% 98%));
85
+ --color-popover: var(--kc-color-popover, hsl(45 4% 12%));
86
+ --color-popover-foreground: var(--kc-color-popover-foreground, hsl(0 0% 98%));
87
+ --color-primary: var(--kc-color-primary, hsl(0 0% 98%));
88
+ --color-primary-foreground: var(--kc-color-primary-foreground, hsl(45 4% 11%));
89
+ --color-secondary: var(--kc-color-secondary, hsl(45 4% 17%));
90
+ --color-secondary-foreground: var(--kc-color-secondary-foreground, hsl(0 0% 98%));
91
+ --color-muted: var(--kc-color-muted, hsl(45 4% 17%));
92
+ --color-muted-foreground: var(--kc-color-muted-foreground, hsl(45 4% 64%));
93
+ --color-accent: var(--kc-color-accent, hsl(45 4% 17%));
94
+ --color-accent-foreground: var(--kc-color-accent-foreground, hsl(0 0% 98%));
95
+ --color-destructive: var(--kc-color-destructive, hsl(0 62.8% 30.6%));
96
+ --color-destructive-foreground: var(--kc-color-destructive-foreground, hsl(0 0% 98%));
97
+ --color-border: var(--kc-color-border, hsl(45 4% 17%));
98
+ --color-input: var(--kc-color-input, hsl(45 4% 17%));
99
+ --color-ring: var(--kc-color-ring, hsl(217 91% 68%));
100
+ --color-scrollbar-thumb: var(--kc-color-scrollbar-thumb, hsl(45 3% 30%));
101
+ --color-scrollbar-thumb-hover: var(--kc-color-scrollbar-thumb-hover, hsl(45 3% 42%));
102
+ --color-sidebar: var(--kc-color-sidebar, hsl(50 2% 7%));
103
+ --color-code-foreground: var(--kc-color-code-foreground, hsl(213 94% 78%));
104
104
 
105
105
  /* Tool/status chip hues — dark mode. Brighter hues reach AA on the dark fill. */
106
- --color-tool-blue: var(--kitn-color-tool-blue, hsl(217 91% 70%));
107
- --color-tool-amber: var(--kitn-color-tool-amber, hsl(38 92% 50%));
108
- --color-tool-green: var(--kitn-color-tool-green, hsl(142 71% 45%));
109
- --color-tool-red: var(--kitn-color-tool-red, hsl(0 84% 70%));
106
+ --color-tool-blue: var(--kc-color-tool-blue, hsl(217 91% 70%));
107
+ --color-tool-amber: var(--kc-color-tool-amber, hsl(38 92% 50%));
108
+ --color-tool-green: var(--kc-color-tool-green, hsl(142 71% 45%));
109
+ --color-tool-red: var(--kc-color-tool-red, hsl(0 84% 70%));
110
110
  }
111
111
 
112
112
  /* Self-contained markdown styling — replaces the typography plugin's `prose`.