@plannotator/ui 0.22.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 (305) hide show
  1. package/README.md +60 -0
  2. package/assets/diff-options.png +0 -0
  3. package/assets/icon-codex.png +0 -0
  4. package/assets/look-flat.png +0 -0
  5. package/assets/look-grid.png +0 -0
  6. package/assets/review-sections.png +0 -0
  7. package/assets/review-tree.png +0 -0
  8. package/assets/workspaces.webp +0 -0
  9. package/components/AISettingsTab.tsx +145 -0
  10. package/components/ActionMenu.tsx +101 -0
  11. package/components/AgentControls.tsx +216 -0
  12. package/components/AgentsTab.tsx +1294 -0
  13. package/components/AnnotationPanel.tsx +731 -0
  14. package/components/AnnotationSidebar.tsx +86 -0
  15. package/components/AnnotationToolbar.tsx +323 -0
  16. package/components/AnnotationToolstrip.tsx +355 -0
  17. package/components/ApproveDropdown.tsx +170 -0
  18. package/components/AttachmentsButton.tsx +410 -0
  19. package/components/BlockRenderer.tsx +163 -0
  20. package/components/BorderTrail.tsx +38 -0
  21. package/components/CodeFilePicker.tsx +64 -0
  22. package/components/CodeFilePopout.tsx +602 -0
  23. package/components/CodePathValidationContext.tsx +14 -0
  24. package/components/CommentPopover.tsx +512 -0
  25. package/components/CompletionOverlay.tsx +99 -0
  26. package/components/ConfirmDialog.tsx +128 -0
  27. package/components/DocBadges.tsx +231 -0
  28. package/components/EditorAnnotationCard.tsx +65 -0
  29. package/components/ExportModal.tsx +565 -0
  30. package/components/FloatingQuickLabelPicker.tsx +144 -0
  31. package/components/GitHubIcon.tsx +16 -0
  32. package/components/GitLabIcon.tsx +30 -0
  33. package/components/GraphvizBlock.tsx +511 -0
  34. package/components/ImageAnnotator/Canvas.tsx +118 -0
  35. package/components/ImageAnnotator/Toolbar.tsx +218 -0
  36. package/components/ImageAnnotator/index.tsx +272 -0
  37. package/components/ImageAnnotator/types.ts +39 -0
  38. package/components/ImageAnnotator/utils.ts +147 -0
  39. package/components/ImageThumbnail.tsx +126 -0
  40. package/components/ImportModal.tsx +146 -0
  41. package/components/InlineMarkdown.tsx +1094 -0
  42. package/components/KeyboardShortcuts.tsx +208 -0
  43. package/components/Landing.tsx +496 -0
  44. package/components/ListItemBody.tsx +62 -0
  45. package/components/ListMarker.tsx +73 -0
  46. package/components/LookAndFeelAnnouncementDialog.tsx +230 -0
  47. package/components/MarkdownEditor.tsx +44 -0
  48. package/components/MenuVersionSection.tsx +91 -0
  49. package/components/MermaidBlock.tsx +579 -0
  50. package/components/ModeToggle.tsx +68 -0
  51. package/components/OpenInAppButton.tsx +299 -0
  52. package/components/OverlayScrollArea.tsx +82 -0
  53. package/components/PermissionModeSetup.tsx +92 -0
  54. package/components/PinpointOverlay.tsx +99 -0
  55. package/components/PlanAIAnnouncementDialog.tsx +187 -0
  56. package/components/PlanHeaderMenu.tsx +299 -0
  57. package/components/PopoutDialog.tsx +91 -0
  58. package/components/Popover.tsx +27 -0
  59. package/components/ProviderIcons.tsx +51 -0
  60. package/components/PullRequestIcon.tsx +12 -0
  61. package/components/QuickLabelDropdown.tsx +63 -0
  62. package/components/RenderedMarkdown.tsx +54 -0
  63. package/components/RepoIcon.tsx +12 -0
  64. package/components/ResizeHandle.tsx +86 -0
  65. package/components/ReviewAgentsIcon.tsx +18 -0
  66. package/components/SearchableSelect.tsx +157 -0
  67. package/components/Settings.tsx +2220 -0
  68. package/components/SparklesIcon.tsx +45 -0
  69. package/components/StickyHeaderLane.tsx +260 -0
  70. package/components/TableOfContents.tsx +157 -0
  71. package/components/TaterSpritePullup.tsx +34 -0
  72. package/components/TaterSpriteRunning.tsx +54 -0
  73. package/components/TaterSpriteSitting.tsx +37 -0
  74. package/components/TextShimmer.tsx +57 -0
  75. package/components/ThemeProvider.tsx +162 -0
  76. package/components/ThemeTab.tsx +139 -0
  77. package/components/ToolbarButtons.tsx +116 -0
  78. package/components/Tooltip.tsx +45 -0
  79. package/components/Viewer.tsx +977 -0
  80. package/components/ai/AIProviderBar.tsx +95 -0
  81. package/components/ai/DocumentAIChatPanel.tsx +313 -0
  82. package/components/blocks/AlertBlock.tsx +58 -0
  83. package/components/blocks/Callout.tsx +60 -0
  84. package/components/blocks/CodeBlock.tsx +75 -0
  85. package/components/blocks/HtmlBlock.tsx +122 -0
  86. package/components/blocks/MathBlock.tsx +36 -0
  87. package/components/blocks/TableBlock.tsx +146 -0
  88. package/components/blocks/TablePopout.tsx +279 -0
  89. package/components/blocks/TableToolbar.tsx +153 -0
  90. package/components/blocks/proseBody.tsx +102 -0
  91. package/components/core/button.tsx +44 -0
  92. package/components/core/textarea.tsx +26 -0
  93. package/components/diagramLanguages.ts +14 -0
  94. package/components/goal-setup/GoalSetupSurface.tsx +1354 -0
  95. package/components/html-viewer/HtmlViewer.tsx +386 -0
  96. package/components/html-viewer/bridge-script.ts +505 -0
  97. package/components/html-viewer/index.ts +1 -0
  98. package/components/html-viewer/useHtmlAnnotation.ts +400 -0
  99. package/components/icons/AgentIcons.tsx +66 -0
  100. package/components/icons/AppIcon.tsx +56 -0
  101. package/components/icons/MessagesIcon.tsx +11 -0
  102. package/components/icons/ObsidianIcons.tsx +208 -0
  103. package/components/icons/app/android-studio.svg +369 -0
  104. package/components/icons/app/antigravity.svg +97 -0
  105. package/components/icons/app/cursor.svg +16 -0
  106. package/components/icons/app/file-explorer.svg +20 -0
  107. package/components/icons/app/finder.png +0 -0
  108. package/components/icons/app/ghostty.svg +13 -0
  109. package/components/icons/app/iterm2.svg +13 -0
  110. package/components/icons/app/powershell.svg +14 -0
  111. package/components/icons/app/sublime-text.svg +17 -0
  112. package/components/icons/app/terminal.png +0 -0
  113. package/components/icons/app/textmate.png +0 -0
  114. package/components/icons/app/vscode.svg +39 -0
  115. package/components/icons/app/warp.png +0 -0
  116. package/components/icons/app/xcode.png +0 -0
  117. package/components/icons/app/zed-dark.svg +15 -0
  118. package/components/icons/app/zed.svg +15 -0
  119. package/components/icons/themeIcons.tsx +47 -0
  120. package/components/mermaidSvg.ts +33 -0
  121. package/components/plan-diff/PlanCleanDiffView.tsx +884 -0
  122. package/components/plan-diff/PlanDiffBadge.tsx +48 -0
  123. package/components/plan-diff/PlanDiffModeSwitcher.tsx +103 -0
  124. package/components/plan-diff/PlanDiffViewer.tsx +214 -0
  125. package/components/plan-diff/PlanRawDiffView.tsx +102 -0
  126. package/components/plan-diff/VSCodeIcon.tsx +132 -0
  127. package/components/settings/HooksTab.tsx +208 -0
  128. package/components/sidebar/ArchiveBrowser.tsx +98 -0
  129. package/components/sidebar/CountBadge.tsx +12 -0
  130. package/components/sidebar/FileBrowser.tsx +498 -0
  131. package/components/sidebar/MessagesBrowser.tsx +109 -0
  132. package/components/sidebar/SidebarContainer.tsx +353 -0
  133. package/components/sidebar/SidebarTabs.tsx +155 -0
  134. package/components/sidebar/VersionBrowser.tsx +141 -0
  135. package/components/types.d.ts +7 -0
  136. package/components/ui/badge.tsx +44 -0
  137. package/components/ui/button.tsx +83 -0
  138. package/components/ui/card.tsx +58 -0
  139. package/components/ui/dialog.tsx +106 -0
  140. package/components/ui/dropdown-menu.tsx +240 -0
  141. package/components/ui/state-pill.tsx +45 -0
  142. package/components/ui/tabs.tsx +46 -0
  143. package/components/ui/textarea.tsx +25 -0
  144. package/config/configStore.ts +214 -0
  145. package/config/index.ts +4 -0
  146. package/config/reviewView.ts +42 -0
  147. package/config/settings.ts +310 -0
  148. package/config/useConfig.ts +20 -0
  149. package/configure.ts +69 -0
  150. package/globals.d.ts +14 -0
  151. package/hooks/pfm/useCodeFilePopout.ts +111 -0
  152. package/hooks/useAIChat.ts +532 -0
  153. package/hooks/useAIProviderConfig.ts +115 -0
  154. package/hooks/useActiveSection.ts +78 -0
  155. package/hooks/useAgentJobs.ts +306 -0
  156. package/hooks/useAgentSettings.ts +579 -0
  157. package/hooks/useAgents.ts +90 -0
  158. package/hooks/useAnnotationDraft.ts +523 -0
  159. package/hooks/useAnnotationHighlighter.ts +1170 -0
  160. package/hooks/useArchive.ts +171 -0
  161. package/hooks/useAutoClose.ts +104 -0
  162. package/hooks/useCodeAnnotationDraft.ts +194 -0
  163. package/hooks/useCodeFilePopout.ts +1 -0
  164. package/hooks/useDismissOnOutsideAndEscape.ts +50 -0
  165. package/hooks/useDraggable.ts +108 -0
  166. package/hooks/useEditorAnnotations.ts +64 -0
  167. package/hooks/useExternalAnnotationHighlights.ts +105 -0
  168. package/hooks/useExternalAnnotations.ts +268 -0
  169. package/hooks/useFileBrowser.ts +402 -0
  170. package/hooks/useInputMethodSwitch.ts +89 -0
  171. package/hooks/useIsMobile.ts +17 -0
  172. package/hooks/useLinkedDoc.ts +494 -0
  173. package/hooks/useOverlayViewport.ts +36 -0
  174. package/hooks/usePinpoint.ts +182 -0
  175. package/hooks/usePlanDiff.ts +176 -0
  176. package/hooks/usePrintMode.ts +27 -0
  177. package/hooks/useResizablePanel.ts +173 -0
  178. package/hooks/useScrollViewport.ts +38 -0
  179. package/hooks/useSharing.ts +441 -0
  180. package/hooks/useSidebar.ts +55 -0
  181. package/hooks/useUpdateCheck.ts +132 -0
  182. package/hooks/useValidatedCodePaths.ts +94 -0
  183. package/icons/GitUser.tsx +17 -0
  184. package/lib/utils.ts +11 -0
  185. package/package.json +117 -0
  186. package/plannotator.webp +0 -0
  187. package/print.css +427 -0
  188. package/shortcuts/code-review/ai.shortcuts.ts +25 -0
  189. package/shortcuts/code-review/allFilesDiff.shortcuts.ts +46 -0
  190. package/shortcuts/code-review/annotationToolbar.shortcuts.ts +30 -0
  191. package/shortcuts/code-review/fileTree.shortcuts.ts +35 -0
  192. package/shortcuts/code-review/prComments.shortcuts.ts +18 -0
  193. package/shortcuts/code-review/suggestionModal.shortcuts.ts +25 -0
  194. package/shortcuts/code-review/tourDialog.shortcuts.ts +18 -0
  195. package/shortcuts/core.ts +399 -0
  196. package/shortcuts/index.ts +21 -0
  197. package/shortcuts/plan-review/annotationPanel.shortcuts.ts +25 -0
  198. package/shortcuts/plan-review/annotationToolbar.shortcuts.ts +39 -0
  199. package/shortcuts/plan-review/commentPopover.shortcuts.ts +21 -0
  200. package/shortcuts/plan-review/goalSetup.shortcuts.ts +10 -0
  201. package/shortcuts/plan-review/imageAnnotator.shortcuts.ts +42 -0
  202. package/shortcuts/plan-review/inputMethod.shortcuts.ts +30 -0
  203. package/shortcuts/plan-review/sidebar.shortcuts.ts +34 -0
  204. package/shortcuts/plan-review/viewer.shortcuts.ts +24 -0
  205. package/shortcuts/runtime.ts +259 -0
  206. package/sprite_package_additional/index.html +34 -0
  207. package/sprite_package_additional/sprite.png +0 -0
  208. package/sprite_package_new/index.html +34 -0
  209. package/sprite_package_new/sprite.png +0 -0
  210. package/sprite_package_pulluphang/index.html +34 -0
  211. package/sprite_package_pulluphang/sprite.png +0 -0
  212. package/styles.css +1 -0
  213. package/theme.css +893 -0
  214. package/themes/adwaita.css +62 -0
  215. package/themes/andromeeda.css +66 -0
  216. package/themes/aurora-x.css +66 -0
  217. package/themes/ayu-dark.css +66 -0
  218. package/themes/caffeine.css +113 -0
  219. package/themes/catppuccin.css +62 -0
  220. package/themes/claude-plus.css +60 -0
  221. package/themes/cursor-hc.css +34 -0
  222. package/themes/cursor-midnight.css +34 -0
  223. package/themes/cursor.css +62 -0
  224. package/themes/dark-plus.css +66 -0
  225. package/themes/doom-64.css +109 -0
  226. package/themes/dracula.css +33 -0
  227. package/themes/everforest-hard.css +62 -0
  228. package/themes/everforest-soft.css +62 -0
  229. package/themes/everforest.css +62 -0
  230. package/themes/github.css +66 -0
  231. package/themes/gruvbox.css +62 -0
  232. package/themes/houston.css +66 -0
  233. package/themes/kanagawa-dragon.css +34 -0
  234. package/themes/kanagawa-lotus.css +34 -0
  235. package/themes/kanagawa-wave.css +34 -0
  236. package/themes/laserwave.css +66 -0
  237. package/themes/material.css +62 -0
  238. package/themes/min.css +66 -0
  239. package/themes/monokai-pro.css +34 -0
  240. package/themes/neutral.css +59 -0
  241. package/themes/night-owl.css +66 -0
  242. package/themes/nord.css +66 -0
  243. package/themes/one-dark-pro.css +66 -0
  244. package/themes/one-light.css +66 -0
  245. package/themes/paulmillr.css +34 -0
  246. package/themes/plannotator.css +60 -0
  247. package/themes/plastic.css +66 -0
  248. package/themes/poimandres.css +66 -0
  249. package/themes/quantum-rose.css +109 -0
  250. package/themes/red.css +66 -0
  251. package/themes/rose-pine.css +62 -0
  252. package/themes/simple.css +124 -0
  253. package/themes/slack.css +66 -0
  254. package/themes/snazzy-light.css +66 -0
  255. package/themes/soft-pop.css +60 -0
  256. package/themes/solar-dusk.css +109 -0
  257. package/themes/solarized.css +66 -0
  258. package/themes/synthwave-84.css +34 -0
  259. package/themes/terminal.css +62 -0
  260. package/themes/tinacious.css +57 -0
  261. package/themes/tokyo-night.css +62 -0
  262. package/themes/vesper.css +62 -0
  263. package/themes/vitesse-black.css +66 -0
  264. package/themes/vitesse.css +62 -0
  265. package/types.ts +264 -0
  266. package/utils/agentSwitch.ts +71 -0
  267. package/utils/aiChatFormat.ts +33 -0
  268. package/utils/aiPrompt.ts +29 -0
  269. package/utils/aiProvider.ts +217 -0
  270. package/utils/anchors.ts +11 -0
  271. package/utils/annotateAgentTerminal.ts +29 -0
  272. package/utils/annotationHelpers.ts +101 -0
  273. package/utils/bear.ts +59 -0
  274. package/utils/blockTargeting.ts +240 -0
  275. package/utils/callback.ts +99 -0
  276. package/utils/commentContent.ts +8 -0
  277. package/utils/defaultNotesApp.ts +20 -0
  278. package/utils/diffFonts.ts +33 -0
  279. package/utils/editorMode.ts +31 -0
  280. package/utils/fileBrowser.ts +40 -0
  281. package/utils/generateId.ts +7 -0
  282. package/utils/generateIdentity.ts +29 -0
  283. package/utils/identity.ts +112 -0
  284. package/utils/inlineTransforms.ts +41 -0
  285. package/utils/inputMethod.ts +17 -0
  286. package/utils/lookAndFeelAnnouncement.ts +18 -0
  287. package/utils/obsidian.ts +201 -0
  288. package/utils/octarine.ts +53 -0
  289. package/utils/parser.ts +991 -0
  290. package/utils/permissionMode.ts +77 -0
  291. package/utils/planAIAnnouncement.ts +17 -0
  292. package/utils/planAgentInstructions.ts +137 -0
  293. package/utils/planDiffEngine.ts +590 -0
  294. package/utils/planSave.ts +49 -0
  295. package/utils/platform.ts +11 -0
  296. package/utils/quickLabels.ts +77 -0
  297. package/utils/reviewAgentInstructions.ts +182 -0
  298. package/utils/sanitizeHtml.ts +45 -0
  299. package/utils/sharing.ts +350 -0
  300. package/utils/slugify.ts +37 -0
  301. package/utils/storage.ts +141 -0
  302. package/utils/themeRegistry.ts +567 -0
  303. package/utils/uiPreferences.ts +34 -0
  304. package/utils/upload.ts +56 -0
  305. package/utils/wideMode.ts +48 -0
package/theme.css ADDED
@@ -0,0 +1,893 @@
1
+ /* Plannotator Theme System — imports all themes, provides Tailwind bridge + base styles */
2
+
3
+ @import "katex/dist/katex.min.css";
4
+
5
+ /* Theme files — each defines .theme-{name} (dark) and .theme-{name}.light */
6
+ @import "./themes/plannotator.css";
7
+ @import "./themes/claude-plus.css";
8
+ @import "./themes/soft-pop.css";
9
+ @import "./themes/adwaita.css";
10
+ @import "./themes/caffeine.css";
11
+ @import "./themes/synthwave-84.css";
12
+ @import "./themes/catppuccin.css";
13
+ @import "./themes/rose-pine.css";
14
+ @import "./themes/monokai-pro.css";
15
+ @import "./themes/doom-64.css";
16
+ @import "./themes/dracula.css";
17
+ @import "./themes/gruvbox.css";
18
+ @import "./themes/kanagawa-dragon.css";
19
+ @import "./themes/kanagawa-lotus.css";
20
+ @import "./themes/kanagawa-wave.css";
21
+ @import "./themes/paulmillr.css";
22
+ @import "./themes/quantum-rose.css";
23
+ @import "./themes/solar-dusk.css";
24
+ @import "./themes/terminal.css";
25
+ @import "./themes/tokyo-night.css";
26
+ @import "./themes/tinacious.css";
27
+ @import "./themes/cursor.css";
28
+ @import "./themes/cursor-hc.css";
29
+ @import "./themes/cursor-midnight.css";
30
+ @import "./themes/everforest.css";
31
+ @import "./themes/everforest-hard.css";
32
+ @import "./themes/everforest-soft.css";
33
+ @import "./themes/nord.css";
34
+ @import "./themes/solarized.css";
35
+ @import "./themes/github.css";
36
+ @import "./themes/one-dark-pro.css";
37
+ @import "./themes/night-owl.css";
38
+ @import "./themes/ayu-dark.css";
39
+ @import "./themes/poimandres.css";
40
+ @import "./themes/material.css";
41
+ @import "./themes/vitesse.css";
42
+ @import "./themes/vesper.css";
43
+ @import "./themes/andromeeda.css";
44
+ @import "./themes/aurora-x.css";
45
+ @import "./themes/dark-plus.css";
46
+ @import "./themes/houston.css";
47
+ @import "./themes/laserwave.css";
48
+ @import "./themes/min.css";
49
+ @import "./themes/one-light.css";
50
+ @import "./themes/plastic.css";
51
+ @import "./themes/red.css";
52
+ @import "./themes/slack.css";
53
+ @import "./themes/snazzy-light.css";
54
+ @import "./themes/vitesse-black.css";
55
+ @import "./themes/simple.css";
56
+ @import "./themes/neutral.css";
57
+ @import "./print.css";
58
+
59
+ /* Tailwind bridge — maps CSS vars to utility classes */
60
+ @theme inline {
61
+ --color-background: var(--background);
62
+ --color-foreground: var(--foreground);
63
+ --color-card: var(--card);
64
+ --color-card-foreground: var(--card-foreground);
65
+ --color-popover: var(--popover);
66
+ --color-popover-foreground: var(--popover-foreground);
67
+ --color-primary: var(--primary);
68
+ --color-primary-foreground: var(--primary-foreground);
69
+ --color-secondary: var(--secondary);
70
+ --color-secondary-foreground: var(--secondary-foreground);
71
+ --color-muted: var(--muted);
72
+ --color-muted-foreground: var(--muted-foreground);
73
+ --color-accent: var(--accent);
74
+ --color-accent-foreground: var(--accent-foreground);
75
+ --color-destructive: var(--destructive);
76
+ --color-destructive-foreground: var(--destructive-foreground);
77
+ --color-success: var(--success);
78
+ --color-success-foreground: var(--success-foreground);
79
+ --color-warning: var(--warning);
80
+ --color-warning-foreground: var(--warning-foreground);
81
+ --color-border: var(--border);
82
+ --color-input: var(--input);
83
+ --color-ring: var(--ring);
84
+ --color-sidebar: var(--sidebar);
85
+ --color-sidebar-foreground: var(--sidebar-foreground);
86
+ --color-sidebar-primary: var(--sidebar-primary);
87
+ --color-sidebar-primary-foreground: var(--sidebar-primary-foreground);
88
+ --color-sidebar-accent: var(--sidebar-accent);
89
+ --color-sidebar-accent-foreground: var(--sidebar-accent-foreground);
90
+ --color-sidebar-border: var(--sidebar-border);
91
+ --color-sidebar-ring: var(--sidebar-ring);
92
+ --color-surface-0: var(--surface-0);
93
+ --color-surface-1: var(--surface-1);
94
+ --color-surface-2: var(--surface-2);
95
+ /* Comment-annotation indicator color. Defaults to each theme's --accent
96
+ * (see :root below); a theme whose accent is a low-contrast neutral (e.g.
97
+ * "simple") overrides --annotation-comment directly. */
98
+ --color-annotation-comment: var(--annotation-comment);
99
+ --font-sans: var(--font-sans);
100
+ --font-mono: var(--font-mono);
101
+ --radius-sm: calc(var(--radius) - 4px);
102
+ --radius-md: calc(var(--radius) - 2px);
103
+ --radius-lg: var(--radius);
104
+ --radius-xl: calc(var(--radius) + 4px);
105
+ }
106
+
107
+ /* Type scale — fonts excluded on purpose (themes own --font-sans/--font-mono) */
108
+ @theme {
109
+ --text-sm: 0.875rem; --text-sm--line-height: 1.45;
110
+ --text-base: 1rem; --text-base--line-height: 1.55;
111
+ --text-lg: 1.0625rem; --text-lg--line-height: 1.45;
112
+ --text-xl: 1.1875rem; --text-xl--line-height: 1.4;
113
+ --text-2xl: 1.375rem; --text-2xl--line-height: 1.3;
114
+ --text-3xl: 1.625rem; --text-3xl--line-height: 1.2;
115
+ --text-4xl: 1.875rem; --text-4xl--line-height: 1.15;
116
+ --text-5xl: 2rem; --text-5xl--line-height: 1.1;
117
+ }
118
+
119
+ /* Base styles — apply regardless of theme */
120
+ @layer base {
121
+ /* Extended tokens — derived from Plannotator's theme vars so they adapt to
122
+ * all themes. These cover gaps between Plannotator's base token set and what
123
+ * the surface/sidebar-aware components expect. Themes that pin explicit
124
+ * values (e.g. "simple") override these. */
125
+ :root {
126
+ --surface-0: color-mix(in oklch, var(--muted) 40%, var(--background));
127
+ --surface-1: var(--muted);
128
+ --surface-2: color-mix(in oklch, var(--muted) 70%, var(--foreground));
129
+ --sidebar: var(--card);
130
+ --sidebar-foreground: var(--foreground);
131
+ --sidebar-primary: var(--primary);
132
+ --sidebar-primary-foreground: var(--primary-foreground);
133
+ --sidebar-accent: var(--muted);
134
+ --sidebar-accent-foreground: var(--foreground);
135
+ --sidebar-border: var(--border);
136
+ --sidebar-ring: var(--ring);
137
+ /* Comment-annotation color follows the theme's accent unless the theme
138
+ * overrides it (neutral themes whose accent is an illegible gray). */
139
+ --annotation-comment: var(--accent);
140
+ /* Sensible amber default so a "warning" color utility exists even for
141
+ * themes that don't define --warning. Matches the plannotator theme;
142
+ * per-theme files override these. */
143
+ --warning: oklch(0.75 0.15 85);
144
+ --warning-foreground: oklch(0.20 0.02 260);
145
+ --card-ring: rgba(255, 255, 255, 0.08);
146
+ --card-shadow:
147
+ 0 0 0 1px var(--card-ring), 0 1px 3px 0 rgba(0, 0, 0, 0.2), 0 2px 8px -2px rgba(0, 0, 0, 0.3);
148
+ }
149
+
150
+ html {
151
+ --terminal-background: var(--card);
152
+ --terminal-foreground: var(--foreground);
153
+ --terminal-cursor: var(--primary);
154
+ --terminal-cursor-accent: var(--terminal-background);
155
+ --terminal-selection-background: color-mix(in oklab, var(--primary) 32%, var(--terminal-background));
156
+ --terminal-selection-foreground: var(--foreground);
157
+ --terminal-selection-inactive-background: var(--border);
158
+ --terminal-black: var(--terminal-background);
159
+ --terminal-red: var(--destructive);
160
+ --terminal-green: var(--success);
161
+ --terminal-yellow: var(--warning);
162
+ --terminal-blue: var(--primary);
163
+ --terminal-magenta: var(--accent);
164
+ --terminal-cyan: var(--secondary);
165
+ --terminal-white: var(--foreground);
166
+ --terminal-bright-black: var(--muted-foreground);
167
+ --terminal-bright-red: color-mix(in oklab, var(--destructive) 80%, white);
168
+ --terminal-bright-green: color-mix(in oklab, var(--success) 80%, white);
169
+ --terminal-bright-yellow: color-mix(in oklab, var(--warning) 80%, white);
170
+ --terminal-bright-blue: color-mix(in oklab, var(--primary) 80%, white);
171
+ --terminal-bright-magenta: color-mix(in oklab, var(--accent) 80%, white);
172
+ --terminal-bright-cyan: color-mix(in oklab, var(--secondary) 80%, white);
173
+ --terminal-bright-white: var(--foreground);
174
+ }
175
+
176
+ .light {
177
+ --warning: oklch(0.55 0.18 85);
178
+ --warning-foreground: oklch(0.18 0.02 260);
179
+ --terminal-bright-red: color-mix(in oklab, var(--destructive) 84%, black);
180
+ --terminal-bright-green: color-mix(in oklab, var(--success) 84%, black);
181
+ --terminal-bright-yellow: color-mix(in oklab, var(--warning) 84%, black);
182
+ --terminal-bright-blue: color-mix(in oklab, var(--primary) 84%, black);
183
+ --terminal-bright-magenta: color-mix(in oklab, var(--accent) 84%, black);
184
+ --terminal-bright-cyan: color-mix(in oklab, var(--secondary) 84%, black);
185
+ --card-ring: rgba(0, 0, 0, 0.06);
186
+ --card-shadow:
187
+ 0 0 0 1px var(--card-ring), 0 1px 3px 0 rgba(0, 0, 0, 0.04),
188
+ 0 2px 8px -2px rgba(0, 0, 0, 0.06);
189
+ }
190
+
191
+ * {
192
+ border-color: var(--border);
193
+ }
194
+ }
195
+
196
+ body {
197
+ font-family: var(--font-sans);
198
+ background: var(--background);
199
+ color: var(--foreground);
200
+ font-feature-settings: "ss01", "ss02", "cv01";
201
+ }
202
+
203
+ .math-inline {
204
+ display: inline-flex;
205
+ align-items: center;
206
+ max-width: 100%;
207
+ vertical-align: text-bottom;
208
+ line-height: 1;
209
+ }
210
+
211
+ /* Signal that a rendered formula is a clickable annotation target. */
212
+ .math-annotatable {
213
+ cursor: pointer;
214
+ }
215
+
216
+ .math-block {
217
+ max-width: 100%;
218
+ }
219
+
220
+ .math-inline .katex,
221
+ .math-block .katex {
222
+ color: inherit;
223
+ font-size: 1.02em;
224
+ }
225
+
226
+ .math-inline .katex {
227
+ line-height: inherit;
228
+ }
229
+
230
+ .math-block .katex-display {
231
+ margin: 0;
232
+ text-align: center;
233
+ }
234
+
235
+ /* Subtle grid background */
236
+ .bg-grid {
237
+ background-image:
238
+ linear-gradient(to right, oklch(0.32 0.02 260 / 0.5) 1px, transparent 1px),
239
+ linear-gradient(to bottom, oklch(0.32 0.02 260 / 0.5) 1px, transparent 1px);
240
+ background-size: 24px 24px;
241
+ }
242
+
243
+ .light .bg-grid {
244
+ background-image:
245
+ linear-gradient(to right, oklch(0.90 0.01 260 / 0.6) 1px, transparent 1px),
246
+ linear-gradient(to bottom, oklch(0.90 0.01 260 / 0.6) 1px, transparent 1px);
247
+ }
248
+
249
+
250
+ /* Glow effects */
251
+ .glow-primary {
252
+ box-shadow: 0 0 20px oklch(from var(--primary) l c h / 0.15), 0 0 40px oklch(from var(--primary) l c h / 0.05);
253
+ }
254
+
255
+ .glow-sm {
256
+ box-shadow: 0 0 10px oklch(from var(--primary) l c h / 0.1);
257
+ }
258
+
259
+ /* ------------------------------------------------------------------ */
260
+ /* Goal setup interview — glass outer + opaque rows */
261
+ /* ------------------------------------------------------------------ */
262
+
263
+ .goal-shell {
264
+ position: relative;
265
+ border-radius: 1rem;
266
+ border: 1px solid oklch(from var(--border) l c h / 0.3);
267
+ background: oklch(from var(--muted) l c h / 0.5);
268
+ padding: 1.25rem;
269
+ }
270
+
271
+ .goal-row {
272
+ position: relative;
273
+ border-radius: 0.625rem;
274
+ background: var(--card);
275
+ border: 1px solid oklch(from var(--border) l c h / 0.3);
276
+ box-shadow: 0 1px 2px -1px rgba(0, 0, 0, 0.12);
277
+ transition: background-color 150ms, box-shadow 150ms, border-color 150ms, opacity 120ms;
278
+ }
279
+
280
+ .goal-row + .goal-row {
281
+ margin-top: 0.375rem;
282
+ }
283
+
284
+ .goal-row.answered {
285
+ border-color: oklch(from var(--success) l c h / 0.25);
286
+ }
287
+
288
+ .goal-row.skipped {
289
+ border-color: oklch(from var(--warning) l c h / 0.25);
290
+ }
291
+
292
+ .goal-row.active {
293
+ box-shadow:
294
+ 0 0 0 1px oklch(from var(--primary) l c h / 0.3),
295
+ 0 2px 8px -2px rgba(0, 0, 0, 0.12);
296
+ }
297
+
298
+
299
+ .goal-row-divider {
300
+ height: 1px;
301
+ margin: 0 0.875rem;
302
+ background: oklch(from var(--border) l c h / 0.2);
303
+ }
304
+
305
+ /* CSS-grid accordion — animate rows 0fr ↔ 1fr without measuring */
306
+ .goal-question-body {
307
+ display: grid;
308
+ grid-template-rows: 0fr;
309
+ transition: grid-template-rows 180ms ease;
310
+ }
311
+
312
+ .goal-question-body.expanded {
313
+ grid-template-rows: 1fr;
314
+ }
315
+
316
+ .goal-question-body > .goal-question-body-inner {
317
+ overflow: hidden;
318
+ min-height: 0;
319
+ }
320
+
321
+ @keyframes goal-pill-in {
322
+ from {
323
+ opacity: 0;
324
+ transform: translate(-50%, 8px);
325
+ }
326
+ to {
327
+ opacity: 1;
328
+ transform: translate(-50%, 0);
329
+ }
330
+ }
331
+
332
+ .goal-shortcut-pill {
333
+ animation: goal-pill-in 220ms ease-out both;
334
+ }
335
+
336
+ .goal-shortcut-pill kbd {
337
+ display: inline-flex;
338
+ align-items: center;
339
+ justify-content: center;
340
+ min-width: 1rem;
341
+ height: 1rem;
342
+ padding: 0 0.25rem;
343
+ border-radius: 0.25rem;
344
+ border: 1px solid oklch(from var(--border) l c h / 0.5);
345
+ background: oklch(from var(--muted) l c h / 0.6);
346
+ color: var(--foreground);
347
+ font-family: var(--font-mono);
348
+ font-size: 0.625rem;
349
+ line-height: 1rem;
350
+ }
351
+
352
+ .goal-shortcut-pill kbd + kbd {
353
+ margin-left: -1px;
354
+ border-top-left-radius: 0;
355
+ border-bottom-left-radius: 0;
356
+ }
357
+
358
+ .goal-shortcut-pill kbd:has(+ kbd) {
359
+ border-top-right-radius: 0;
360
+ border-bottom-right-radius: 0;
361
+ }
362
+
363
+ /* ------------------------------------------------------------------ */
364
+ /* Scrollbars */
365
+ /* ------------------------------------------------------------------ */
366
+ /*
367
+ * All scroll containers use NATIVE OS scrollbars (the overlayscrollbars library
368
+ * was removed). <OverlayScrollArea> is now a thin native wrapper; everything is
369
+ * styled by the standard rule below.
370
+ *
371
+ * Note: transform/opacity were removed from global transitions in abc952f to
372
+ * prevent scroll jank. DO NOT re-add them.
373
+ */
374
+
375
+ /* Native OS scrollbars — thin + themed via the standard properties (cross-browser:
376
+ * Chrome 121+, Safari 18.2+, Firefox). Deliberately NO `::-webkit-scrollbar { width }`
377
+ * override: the old 6px rail was the "can't grab the scrollbar" bug (#354); the
378
+ * standard `thin` stays grabbable. (Replaced the overlayscrollbars os-theme.) */
379
+ * {
380
+ scrollbar-width: thin;
381
+ scrollbar-color: var(--border) transparent;
382
+ }
383
+
384
+ /* Selection */
385
+ ::selection {
386
+ background: oklch(from var(--primary) l c h / 0.3);
387
+ }
388
+
389
+ /* Suppress all color transitions until the app has mounted and the theme
390
+ is stable. Without this, the global * transition below fires on initial
391
+ load — className reassignments during React mount trigger a 150ms
392
+ transition from browser-default black to themed white, causing a visible
393
+ flash. ThemeProvider adds .transitions-ready after mount. */
394
+ html:not(.transitions-ready) * {
395
+ transition-duration: 0s !important;
396
+ }
397
+
398
+ /* Smooth transitions for theme switching and hover states.
399
+ Only color properties — transform/opacity are handled per-component
400
+ to avoid interfering with scroll compositing. */
401
+ * {
402
+ transition-property: color, background-color, border-color, box-shadow;
403
+ transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
404
+ transition-duration: 150ms;
405
+ }
406
+
407
+ /* Focus states */
408
+ :focus-visible {
409
+ outline: 2px solid var(--ring);
410
+ outline-offset: 2px;
411
+ }
412
+
413
+ /* Flash highlight for annotated files in sidebar */
414
+ .file-annotation-flash {
415
+ animation: file-flash 1.2s ease-out;
416
+ }
417
+
418
+ @keyframes file-flash {
419
+ 0% { background: transparent; }
420
+ 10% { background: var(--muted); }
421
+ 30% { background: transparent; }
422
+ 45% { background: var(--muted); }
423
+ 65% { background: transparent; }
424
+ 100% { background: transparent; }
425
+ }
426
+
427
+ /* Shared file tree styling used by review and annotation sidebars. */
428
+ .file-tree-item {
429
+ display: flex;
430
+ align-items: center;
431
+ gap: 0.5rem;
432
+ padding: 0.25rem 0.5rem;
433
+ border-radius: var(--radius-sm);
434
+ font-size: 0.8125rem; /* 13px — file rows felt small vs. the rest of the app */
435
+ cursor: pointer;
436
+ color: var(--muted-foreground);
437
+ }
438
+
439
+ .file-tree-item:hover {
440
+ background: var(--muted);
441
+ color: var(--foreground);
442
+ }
443
+
444
+ .file-tree-item:disabled {
445
+ cursor: default;
446
+ }
447
+
448
+ .file-tree-item:disabled:hover {
449
+ background: transparent;
450
+ }
451
+
452
+ .file-tree-item.active {
453
+ background: oklch(from var(--primary) l c h / 0.3);
454
+ color: var(--primary);
455
+ }
456
+
457
+ /* The stage (+) button's default border (--border) has no contrast against
458
+ the active row's primary tint and visually disappears — tint it with the
459
+ row color instead. :not(:hover) leaves the button's own hover border. */
460
+ .file-tree-item.active .stage-plus:not(:hover) {
461
+ border-color: oklch(from var(--primary) l c h / 0.5);
462
+ }
463
+
464
+ .file-tree-item.has-annotations {
465
+ background: oklch(from var(--primary) l c h / 0.08);
466
+ }
467
+
468
+ .file-tree-item.has-annotations:hover {
469
+ background: var(--muted);
470
+ }
471
+
472
+ .file-tree-item.active.has-annotations {
473
+ background: oklch(from var(--primary) l c h / 0.3);
474
+ }
475
+
476
+ .file-tree-item .additions,
477
+ .file-tree-folder .additions,
478
+ .file-tree-status-summary .additions {
479
+ color: var(--success);
480
+ }
481
+
482
+ .file-tree-item .deletions,
483
+ .file-tree-folder .deletions,
484
+ .file-tree-status-summary .deletions {
485
+ color: var(--destructive);
486
+ }
487
+
488
+
489
+ /* Word-level diff markers inside modified plan-diff blocks. Emitted as
490
+ <ins>/<del> by PlanCleanDiffView's inline renderer; keep the decoration
491
+ compact across line wraps via box-decoration-break: clone. */
492
+ .plan-diff-word-added,
493
+ .plan-diff-word-removed {
494
+ padding: 0 2px;
495
+ border-radius: 2px;
496
+ box-decoration-break: clone;
497
+ -webkit-box-decoration-break: clone;
498
+ }
499
+ .plan-diff-word-added {
500
+ background-color: color-mix(in oklab, var(--success) 20%, transparent);
501
+ text-decoration: none;
502
+ color: inherit;
503
+ }
504
+ .plan-diff-word-removed {
505
+ background-color: color-mix(in oklab, var(--destructive) 15%, transparent);
506
+ text-decoration: line-through;
507
+ text-decoration-color: color-mix(in oklab, var(--destructive) 60%, transparent);
508
+ opacity: 0.75;
509
+ color: inherit;
510
+ }
511
+
512
+ /* Inline code pills inside diff wrappers carry their own solid background
513
+ which would otherwise cover the green/red tint on the surrounding
514
+ <ins>/<del>. Override the pill background so added code pills read clearly
515
+ green and removed pills read clearly red-struck. */
516
+ .plan-diff-word-added code {
517
+ background-color: color-mix(in oklab, var(--success) 25%, var(--muted));
518
+ }
519
+ .plan-diff-word-removed code {
520
+ background-color: color-mix(in oklab, var(--destructive) 20%, var(--muted));
521
+ }
522
+
523
+ /* Annotation highlights */
524
+ .annotation-highlight {
525
+ border-radius: 2px;
526
+ padding: 0 2px;
527
+ margin: 0 -2px;
528
+ }
529
+
530
+ .annotation-highlight.deletion {
531
+ background: oklch(from var(--destructive) l c h / 0.35);
532
+ text-decoration: line-through;
533
+ text-decoration-color: var(--destructive);
534
+ text-decoration-thickness: 2px;
535
+ }
536
+
537
+ .annotation-highlight.comment {
538
+ background: oklch(0.70 0.18 60 / 0.3);
539
+ border-bottom: 2px solid var(--accent);
540
+ }
541
+
542
+ /* Light mode: softer highlights */
543
+ .light .annotation-highlight.deletion {
544
+ background: oklch(0.65 0.22 25 / 0.2);
545
+ }
546
+
547
+ .light .annotation-highlight.comment {
548
+ background: oklch(0.70 0.20 60 / 0.15);
549
+ }
550
+
551
+ .annotation-highlight.focused {
552
+ background: oklch(from var(--focus-highlight) l c h / 0.45) !important;
553
+ box-shadow: 0 0 8px oklch(from var(--focus-highlight) l c h / 0.4);
554
+ border-bottom: 2px solid var(--focus-highlight);
555
+ filter: none;
556
+ }
557
+
558
+ .light .annotation-highlight.focused {
559
+ background: oklch(0.70 0.22 200 / 0.3) !important;
560
+ box-shadow: 0 0 6px oklch(0.60 0.20 200 / 0.3);
561
+ }
562
+
563
+ .annotation-highlight:hover {
564
+ filter: brightness(1.2);
565
+ cursor: pointer;
566
+ }
567
+
568
+ /* ========================================
569
+ Plan Diff Styles
570
+ ======================================== */
571
+
572
+ /* Clean diff view - added content */
573
+ .plan-diff-added {
574
+ border-left: 3px solid var(--success);
575
+ background: oklch(from var(--success) l c h / 0.06);
576
+ padding-left: 0.75rem;
577
+ border-radius: 0 0.25rem 0.25rem 0;
578
+ margin: 0.25rem 0;
579
+ }
580
+ .light .plan-diff-added {
581
+ background: oklch(from var(--success) l c h / 0.06);
582
+ }
583
+
584
+ /* Clean diff view - removed content */
585
+ .plan-diff-removed {
586
+ border-left: 3px solid var(--destructive);
587
+ background: oklch(from var(--destructive) l c h / 0.06);
588
+ padding-left: 0.75rem;
589
+ border-radius: 0 0.25rem 0.25rem 0;
590
+ margin: 0.25rem 0;
591
+ }
592
+ .light .plan-diff-removed {
593
+ background: oklch(from var(--destructive) l c h / 0.06);
594
+ }
595
+
596
+ /* Clean diff view - modified content (mix of additions and deletions in one
597
+ block, rendered inline via word-level diff).
598
+ Deliberate asymmetry with added/removed: add/remove are BLOCK-scope events
599
+ — the whole block matters, so a loud fill is the right signal. Modify is
600
+ a WORD-scope event — the words matter, and the inline red-struck /
601
+ green-highlighted word markers already grab attention. A block-level fill
602
+ would compete with that inline work; an amber gutter on a normal
603
+ background says "look inside, the change is in the text" while staying
604
+ consistent with the green/red/yellow diff convention. */
605
+ .plan-diff-modified {
606
+ border-left: 3px solid oklch(from var(--warning) l c h / 0.75);
607
+ background: transparent;
608
+ padding-left: 0.75rem;
609
+ border-radius: 0 0.25rem 0.25rem 0;
610
+ margin: 0.25rem 0;
611
+ }
612
+
613
+ /* Clean diff view - unchanged (dimmed) */
614
+ .plan-diff-unchanged {
615
+ /* handled via opacity in component */
616
+ }
617
+
618
+ /* Raw diff view - line styles */
619
+ .plan-diff-line-added {
620
+ background: oklch(from var(--success) l c h / 0.15);
621
+ color: var(--success);
622
+ }
623
+ .plan-diff-line-removed {
624
+ background: oklch(from var(--destructive) l c h / 0.15);
625
+ color: var(--destructive);
626
+ opacity: 0.75;
627
+ text-decoration: line-through;
628
+ text-decoration-color: oklch(from var(--destructive) l c h / 0.4);
629
+ }
630
+ .light .plan-diff-line-added {
631
+ background: oklch(from var(--success) l c h / 0.12);
632
+ }
633
+ .light .plan-diff-line-removed {
634
+ background: oklch(from var(--destructive) l c h / 0.12);
635
+ }
636
+
637
+ /* Raw HTML blocks (CommonMark Type 6) rendered via dangerouslySetInnerHTML.
638
+ Minimal typography so <details>, <blockquote>, nested lists etc. inherit
639
+ sensible spacing without fighting the surrounding prose styles. */
640
+ .html-block details {
641
+ border: 1px solid var(--border);
642
+ border-radius: 6px;
643
+ padding: 0.5rem 0.75rem;
644
+ margin: 0.5rem 0;
645
+ background-color: color-mix(in oklab, var(--muted) 30%, transparent);
646
+ }
647
+ .html-block details[open] {
648
+ padding-bottom: 0.75rem;
649
+ }
650
+ .html-block summary {
651
+ cursor: pointer;
652
+ font-weight: 500;
653
+ color: var(--foreground);
654
+ list-style: revert;
655
+ }
656
+ .html-block summary::-webkit-details-marker {
657
+ color: color-mix(in oklab, var(--foreground) 60%, transparent);
658
+ }
659
+ .html-block details[open] > summary {
660
+ margin-bottom: 0.5rem;
661
+ }
662
+ .html-block p {
663
+ margin: 0.5rem 0;
664
+ }
665
+ .html-block ul,
666
+ .html-block ol {
667
+ margin: 0.5rem 0;
668
+ padding-left: 1.5rem;
669
+ }
670
+ .html-block ul { list-style: disc; }
671
+ .html-block ol { list-style: decimal; }
672
+ .html-block blockquote {
673
+ border-left: 2px solid color-mix(in oklab, var(--primary) 50%, transparent);
674
+ padding-left: 1rem;
675
+ margin: 0.75rem 0;
676
+ color: var(--muted-foreground);
677
+ font-style: italic;
678
+ }
679
+ .html-block code {
680
+ background-color: var(--muted);
681
+ padding: 0.1em 0.35em;
682
+ border-radius: 3px;
683
+ font-size: 0.9em;
684
+ }
685
+ .html-block pre {
686
+ background-color: color-mix(in oklab, var(--muted) 50%, transparent);
687
+ border: 1px solid color-mix(in oklab, var(--border) 30%, transparent);
688
+ border-radius: 6px;
689
+ padding: 0.75rem;
690
+ overflow-x: auto;
691
+ margin: 0.75rem 0;
692
+ }
693
+ .html-block pre code {
694
+ background: transparent;
695
+ padding: 0;
696
+ }
697
+ .html-block a {
698
+ color: var(--primary);
699
+ text-decoration: underline;
700
+ text-underline-offset: 2px;
701
+ }
702
+
703
+ /* While the table popout dialog is mounted, drop chrome that would
704
+ otherwise paint over the dialog behind it. :has() observes the dialog's
705
+ presence directly — no JS, no state sync. When the dialog unmounts the
706
+ selector stops matching and everything returns to natural stacking. */
707
+ body:has([data-popout="true"]) [data-annotation-panel="true"],
708
+ body:has([data-popout="true"]) [data-sticky-header-lane="true"],
709
+ body:has([data-popout="true"]) [data-app-header="true"],
710
+ body:has([data-popout="true"]) [data-sidebar-tabs="true"] {
711
+ z-index: -1;
712
+ }
713
+
714
+ /* GitHub-style alerts: > [!NOTE] / [!TIP] / [!WARNING] / [!CAUTION] / [!IMPORTANT] */
715
+ .alert-note { border-left-color: #0969da; }
716
+ .alert-note .alert-title { color: #0969da; }
717
+ .alert-tip { border-left-color: #1a7f37; }
718
+ .alert-tip .alert-title { color: #1a7f37; }
719
+ .alert-warning { border-left-color: #9a6700; }
720
+ .alert-warning .alert-title { color: #9a6700; }
721
+ .alert-caution { border-left-color: #cf222e; }
722
+ .alert-caution .alert-title { color: #cf222e; }
723
+ .alert-important { border-left-color: #8250df; }
724
+ .alert-important .alert-title { color: #8250df; }
725
+
726
+ @media (prefers-color-scheme: dark) {
727
+ .alert-note { border-left-color: #4493f8; }
728
+ .alert-note .alert-title { color: #4493f8; }
729
+ .alert-tip { border-left-color: #3fb950; }
730
+ .alert-tip .alert-title { color: #3fb950; }
731
+ .alert-warning { border-left-color: #d29922; }
732
+ .alert-warning .alert-title { color: #d29922; }
733
+ .alert-caution { border-left-color: #f85149; }
734
+ .alert-caution .alert-title { color: #f85149; }
735
+ .alert-important { border-left-color: #ab7df8; }
736
+ .alert-important .alert-title { color: #ab7df8; }
737
+ }
738
+
739
+ /* Directive containers: :::kind ... ::: */
740
+ .directive { border-color: var(--border); background: color-mix(in srgb, var(--muted) 50%, transparent); }
741
+ .directive-title { color: var(--muted-foreground); }
742
+ .directive-note, .directive-info { background: color-mix(in srgb, #3b82f6 10%, transparent); border-color: color-mix(in srgb, #3b82f6 40%, transparent); }
743
+ .directive-note .directive-title, .directive-info .directive-title { color: #3b82f6; }
744
+ .directive-tip, .directive-success { background: color-mix(in srgb, #10b981 10%, transparent); border-color: color-mix(in srgb, #10b981 40%, transparent); }
745
+ .directive-tip .directive-title, .directive-success .directive-title { color: #10b981; }
746
+ .directive-warning { background: color-mix(in srgb, #f59e0b 10%, transparent); border-color: color-mix(in srgb, #f59e0b 40%, transparent); }
747
+ .directive-warning .directive-title { color: #f59e0b; }
748
+ .directive-danger, .directive-caution { background: color-mix(in srgb, #ef4444 10%, transparent); border-color: color-mix(in srgb, #ef4444 40%, transparent); }
749
+ .directive-danger .directive-title, .directive-caution .directive-title { color: #ef4444; }
750
+
751
+ /* Shared AI chat rendering */
752
+ .ai-streaming-cursor {
753
+ display: inline-block;
754
+ width: 0.45em;
755
+ height: 1em;
756
+ background: currentColor;
757
+ border-radius: 1px;
758
+ vertical-align: -0.15em;
759
+ animation: ai-cursor-blink 1s steps(2, start) infinite;
760
+ }
761
+
762
+ @keyframes ai-cursor-blink {
763
+ 0%, 45% { opacity: 1; }
764
+ 46%, 100% { opacity: 0; }
765
+ }
766
+
767
+ @media (prefers-reduced-motion: reduce) {
768
+ .ai-streaming-cursor {
769
+ animation: none;
770
+ }
771
+ }
772
+
773
+ .ai-markdown {
774
+ line-height: 1.55;
775
+ }
776
+ .ai-markdown p {
777
+ margin: 0.45rem 0;
778
+ }
779
+ .ai-markdown p:first-child {
780
+ margin-top: 0;
781
+ }
782
+ .ai-markdown p:last-child {
783
+ margin-bottom: 0;
784
+ }
785
+ .ai-markdown h1,
786
+ .ai-markdown h2,
787
+ .ai-markdown h3,
788
+ .ai-markdown h4,
789
+ .ai-markdown h5,
790
+ .ai-markdown h6 {
791
+ font-weight: 600;
792
+ margin: 0.75rem 0 0.35rem;
793
+ }
794
+ .ai-markdown h1 { font-size: 0.875rem; }
795
+ .ai-markdown h2 { font-size: 0.8125rem; }
796
+ .ai-markdown h3,
797
+ .ai-markdown h4,
798
+ .ai-markdown h5,
799
+ .ai-markdown h6 { font-size: 0.75rem; }
800
+ .ai-markdown ul,
801
+ .ai-markdown ol {
802
+ margin: 0.45rem 0;
803
+ padding-left: 1rem;
804
+ }
805
+ .ai-markdown ul { list-style: disc; }
806
+ .ai-markdown ol { list-style: decimal; }
807
+ .ai-markdown li {
808
+ margin: 0.15rem 0;
809
+ }
810
+ .ai-markdown code {
811
+ background: color-mix(in oklab, var(--muted) 70%, transparent);
812
+ border: 1px solid color-mix(in oklab, var(--border) 45%, transparent);
813
+ border-radius: 4px;
814
+ padding: 0.05rem 0.3rem;
815
+ font-size: 0.9em;
816
+ }
817
+ .ai-markdown pre {
818
+ background: color-mix(in oklab, var(--muted) 55%, transparent);
819
+ border: 1px solid color-mix(in oklab, var(--border) 45%, transparent);
820
+ border-radius: 6px;
821
+ padding: 0.6rem;
822
+ overflow-x: auto;
823
+ margin: 0.5rem 0;
824
+ }
825
+ .ai-markdown pre code {
826
+ background: transparent;
827
+ border: 0;
828
+ padding: 0;
829
+ }
830
+ .ai-markdown blockquote {
831
+ border-left: 2px solid color-mix(in oklab, var(--primary) 45%, transparent);
832
+ padding-left: 0.6rem;
833
+ color: var(--muted-foreground);
834
+ }
835
+
836
+ /* Annotation highlights — shared by the plan editor and the code-review
837
+ description annotations. (Moved here from packages/editor/index.css so both
838
+ surfaces render web-highlighter marks identically.) */
839
+ .annotation-highlight {
840
+ border-radius: 2px;
841
+ padding: 0 2px;
842
+ margin: 0 -2px;
843
+ }
844
+
845
+ /* Math annotations style the rendered formula element directly rather than
846
+ wrapping text in a <mark>, so they need their own display handling. */
847
+ .annotation-highlight.math-inline-annotation {
848
+ display: inline-flex;
849
+ align-items: center;
850
+ line-height: 1;
851
+ }
852
+
853
+ .annotation-highlight.math-block-annotation {
854
+ display: block;
855
+ }
856
+
857
+ .annotation-highlight.deletion {
858
+ background: oklch(from var(--destructive) l c h / 0.35);
859
+ text-decoration: line-through;
860
+ text-decoration-color: var(--destructive);
861
+ text-decoration-thickness: 2px;
862
+ }
863
+
864
+ .annotation-highlight.comment {
865
+ background: oklch(0.70 0.18 60 / 0.3);
866
+ border-bottom: 2px solid var(--accent);
867
+ }
868
+
869
+ /* Light mode: softer highlights */
870
+ .light .annotation-highlight.deletion {
871
+ background: oklch(0.65 0.22 25 / 0.2);
872
+ }
873
+
874
+ .light .annotation-highlight.comment {
875
+ background: oklch(0.70 0.20 60 / 0.15);
876
+ }
877
+
878
+ .annotation-highlight.focused {
879
+ background: oklch(from var(--focus-highlight) l c h / 0.45) !important;
880
+ box-shadow: 0 0 8px oklch(from var(--focus-highlight) l c h / 0.4);
881
+ border-bottom: 2px solid var(--focus-highlight);
882
+ filter: none;
883
+ }
884
+
885
+ .light .annotation-highlight.focused {
886
+ background: oklch(0.70 0.22 200 / 0.3) !important;
887
+ box-shadow: 0 0 6px oklch(0.60 0.20 200 / 0.3);
888
+ }
889
+
890
+ .annotation-highlight:hover {
891
+ filter: brightness(1.2);
892
+ cursor: pointer;
893
+ }