diff --git a/ui/src/components/icons-tools.ts b/ui/src/components/icons-tools.ts
index b221741147cc..c70fa0c8a05d 100644
--- a/ui/src/components/icons-tools.ts
+++ b/ui/src/components/icons-tools.ts
@@ -1,255 +1,151 @@
// Control UI tool icon set, split from icons.ts to keep both under the max-lines cap.
-import { html } from "lit";
+import { html, svg, type SVGTemplateResult, type TemplateResult } from "lit";
+
+// Shared Lucide icon shell. Inline presentation attributes keep icons visible
+// inside shadow roots that global stylesheet icon rules cannot reach; CSS
+// rules still override them where a surface wants a different stroke width.
+// Bodies must be svg`` fragments: html`` would parse the shapes outside the
+// SVG namespace and they would silently render as nothing.
+export function strokeIcon(body: SVGTemplateResult): TemplateResult {
+ return html`
+
+ `;
+}
export const toolIcons = {
- wrench: html`
-
- `,
- fileCode: html`
-
- `,
- edit: html`
-
- `,
- home: html`
-
- `,
- penLine: html`
-
- `,
- paperclip: html`
-
- `,
- globe: html`
-
- `,
- image: html`
-
- `,
- camera: html`
-
- `,
- cameraOff: html`
-
- `,
- smartphone: html`
-
- `,
- circleQuestionMark: html`
-
- `,
- plug: html`
-
- `,
- circle: html` `,
- puzzle: html`
-
- `,
- panelLeft: html`
-
- `,
- panelLeftClose: html`
-
- `,
- panelLeftOpen: html`
-
- `,
- chevronDown: html`
-
- `,
- chevronRight: html`
-
- `,
- chevronLeft: html`
-
- `,
- externalLink: html`
-
- `,
- send: html`
-
- `,
- stop: html` `,
- pin: html`
-
- `,
- pinOff: html`
-
- `,
- download: html`
-
- `,
- mic: html`
-
- `,
- volume2: html`
-
- `,
- bookmark: html`
-
- `,
- plus: html`
-
- `,
- gitBranch: html`
-
- `,
- gitPullRequest: html`
-
- `,
- gitMerge: html`
-
- `,
- terminal: html`
-
- `,
- claw: html`
-
- `,
- spark: html`
-
- `,
+ wrench: strokeIcon(svg` `),
+ fileCode: strokeIcon(svg`
+
+
+ `),
+ edit: strokeIcon(svg`
+ `),
+ home: strokeIcon(svg`
+ `),
+ penLine: strokeIcon(svg`
+ `),
+ paperclip: strokeIcon(svg` `),
+ globe: strokeIcon(svg`
+
+ `),
+ image: strokeIcon(svg`
+
+ `),
+ camera: strokeIcon(svg`
+ `),
+ cameraOff: strokeIcon(svg`
+
+
+ `),
+ smartphone: strokeIcon(svg`
+ `),
+ circleQuestionMark: strokeIcon(svg`
+
+ `),
+ plug: strokeIcon(svg`
+
+
+ `),
+ circle: strokeIcon(svg``),
+ puzzle: strokeIcon(svg` `),
+ panelLeft: strokeIcon(svg`
+ `),
+ panelLeftClose: strokeIcon(svg`
+
+ `),
+ panelLeftOpen: strokeIcon(svg`
+
+ `),
+ chevronDown: strokeIcon(svg` `),
+ chevronRight: strokeIcon(svg` `),
+ chevronLeft: strokeIcon(svg` `),
+ externalLink: strokeIcon(svg`
+ `),
+ send: strokeIcon(svg`
+ `),
+ stop: strokeIcon(svg``),
+ pin: strokeIcon(svg`
+ `),
+ pinOff: strokeIcon(svg`
+
+ `),
+ download: strokeIcon(svg`
+
+ `),
+ mic: strokeIcon(svg`
+
+ `),
+ volume2: strokeIcon(svg`
+
+ `),
+ bookmark: strokeIcon(svg``),
+ plus: strokeIcon(svg`
+ `),
+ gitBranch: strokeIcon(svg`
+
+
+
+ `),
+ gitPullRequest: strokeIcon(svg`
+
+
+ `),
+ gitMerge: strokeIcon(svg`
+
+ `),
+ terminal: strokeIcon(svg`
+ `),
+ claw: strokeIcon(svg`
+ `),
+ spark: strokeIcon(svg` `),
lobster: html`
`,
- circleUser: html`
-
- `,
- bell: html`
-
- `,
- palette: html`
-
- `,
- flaskConical: html`
-
- `,
- badgeCheck: html`
-
- `,
- refresh: html`
-
- `,
- trash: html`
-
- `,
- eye: html`
-
- `,
- eyeOff: html`
-
- `,
- moreHorizontal: html`
-
- `,
- arrowUpDown: html`
-
- `,
- panelRightOpen: html`
-
- `,
- panelRightClose: html`
-
- `,
- columns2: html`
-
- `,
- panelBottomOpen: html`
-
- `,
- panelBottomClose: html`
-
- `,
- maximize: html`
-
- `,
- minimize: html`
-
- `,
+ circleUser: strokeIcon(svg`
+
+ `),
+ bell: strokeIcon(svg`
+ `),
+ palette: strokeIcon(svg`
+
+
+
+ `),
+ flaskConical: strokeIcon(svg`
+
+ `),
+ badgeCheck: strokeIcon(svg`
+ `),
+ refresh: strokeIcon(svg`
+ `),
+ trash: strokeIcon(svg`
+
+
+
+ `),
+ eye: strokeIcon(svg`
+ `),
+ eyeOff: strokeIcon(svg`
+
+
+ `),
+ moreHorizontal: strokeIcon(svg`
+
+ `),
+ arrowUpDown: strokeIcon(svg`
+
+
+ `),
+ panelRightOpen: strokeIcon(svg`
+
+ `),
+ panelRightClose: strokeIcon(svg`
+
+ `),
+ columns2: strokeIcon(svg`
+ `),
+ panelBottomOpen: strokeIcon(svg`
+
+ `),
+ panelBottomClose: strokeIcon(svg`
+
+ `),
+ maximize: strokeIcon(svg`
+
+
+ `),
+ minimize: strokeIcon(svg`
+
+
+ `),
} as const;
diff --git a/ui/src/components/icons.ts b/ui/src/components/icons.ts
index 56e38c8af224..bf1a5d8157b1 100644
--- a/ui/src/components/icons.ts
+++ b/ui/src/components/icons.ts
@@ -1,400 +1,216 @@
// Control UI module implements icons behavior.
-import { html, type TemplateResult } from "lit";
-import { toolIcons } from "./icons-tools.ts";
+import { svg, type TemplateResult } from "lit";
+import { strokeIcon, toolIcons } from "./icons-tools.ts";
-// Lucide-style SVG icons
-// All icons use currentColor for stroke
+// Lucide-style SVG icons rendered through the shared strokeIcon() shell,
+// which carries the stroke presentation attributes inline (see icons-tools.ts).
export const icons = {
// Navigation icons
- messageSquare: html`
-
- `,
- layoutGrid: html`
-
- `,
- barChart: html`
-
- `,
- layoutDashboard: html`
-
- `,
- coins: html`
-
- `,
- activity: html`
-
- `,
- clock: html`
-
- `,
- link: html`
-
- `,
- radio: html`
-
- `,
- fileText: html`
-
- `,
- zap: html`
-
- `,
- monitor: html`
-
- `,
- monitorSmartphone: html`
-
- `,
- server: html`
-
- `,
- sun: html`
-
- `,
- moon: html`
-
- `,
- settings: html`
-
- `,
- bug: html`
-
- `,
- scrollText: html`
-
- `,
- folder: html`
-
- `,
- kanban: html`
-
- `,
- bot: html`
-
- `,
- users: html`
-
- `,
- shieldCheck: html`
-
- `,
+ messageSquare: strokeIcon(svg` `),
+ layoutGrid: strokeIcon(svg`
+
+
+ `),
+ barChart: strokeIcon(svg`
+
+ `),
+ layoutDashboard: strokeIcon(svg`
+
+
+ `),
+ coins: strokeIcon(svg`
+
+
+ `),
+ activity: strokeIcon(svg` `),
+ clock: strokeIcon(svg`
+ `),
+ link: strokeIcon(svg`
+ `),
+ radio: strokeIcon(svg`
+ `),
+ fileText: strokeIcon(svg`
+
+
+
+ `),
+ zap: strokeIcon(svg``),
+ monitor: strokeIcon(svg`
+
+ `),
+ monitorSmartphone: strokeIcon(svg`
+
+
+ `),
+ server: strokeIcon(svg`
+
+
+ `),
+ sun: strokeIcon(svg`
+
+
+
+
+
+
+
+ `),
+ moon: strokeIcon(svg` `),
+ settings: strokeIcon(svg`
+ `),
+ bug: strokeIcon(svg`
+
+
+
+
+
+
+
+
+
+ `),
+ scrollText: strokeIcon(svg`
+
+
+ `),
+ folder: strokeIcon(svg` `),
+ kanban: strokeIcon(svg`
+
+
+ `),
+ bot: strokeIcon(svg`
+
+
+
+
+ `),
+ users: strokeIcon(svg`
+
+
+ `),
+ shieldCheck: strokeIcon(svg`
+ `),
// UI icons
- menu: html`
-
- `,
- x: html`
-
- `,
- check: html` `,
- play: html` `,
- pause: html`
-
- `,
- target: html`
-
- `,
- switchCamera: html`
-
- `,
- archive: html`
-
- `,
- archiveRestore: html`
-
- `,
- alertTriangle: html`
-
- `,
- hand: html`
-
- `,
- key: html`
-
- `,
- flag: html`
-
- `,
- lock: html`
-
- `,
- hourglass: html`
-
- `,
- layoutComfortable: html`
-
- `,
- layoutCompact: html`
-
- `,
- listFilter: html`
-
- `,
- arrowDown: html` `,
- arrowUp: html` `,
- chevronUp: html` `,
- arrowLeft: html`
-
- `,
- cornerDownLeft: html`
-
- `,
- cornerDownRight: html`
-
- `,
- copy: html`
-
- `,
- search: html`
-
- `,
- brain: html`
-
- `,
- book: html`
-
- `,
- loader: html`
-
- `,
- calendarClock: html`
-
- `,
- listChecks: html`
-
- `,
+ menu: strokeIcon(svg`
+
+ `),
+ x: strokeIcon(svg`
+ `),
+ check: strokeIcon(svg``),
+ play: strokeIcon(svg``),
+ pause: strokeIcon(svg`
+ `),
+ target: strokeIcon(svg`
+
+ `),
+ switchCamera: strokeIcon(svg`
+
+
+ `),
+ archive: strokeIcon(svg`
+
+ `),
+ archiveRestore: strokeIcon(svg`
+
+
+ `),
+ alertTriangle: strokeIcon(svg`
+
+ `),
+ hand: strokeIcon(svg`
+
+
+ `),
+ key: strokeIcon(svg`
+
+ `),
+ flag: strokeIcon(svg`
+ `),
+ lock: strokeIcon(svg`
+ `),
+ hourglass: strokeIcon(svg`
+
+
+ `),
+ layoutComfortable: strokeIcon(svg`
+
+
+ `),
+ layoutCompact: strokeIcon(svg`
+
+
+ `),
+ listFilter: strokeIcon(svg`
+
+ `),
+ arrowDown: strokeIcon(svg``),
+ arrowUp: strokeIcon(svg``),
+ chevronUp: strokeIcon(svg``),
+ arrowLeft: strokeIcon(svg`
+ `),
+ cornerDownLeft: strokeIcon(svg`
+ `),
+ cornerDownRight: strokeIcon(svg`
+ `),
+ copy: strokeIcon(svg`
+ `),
+ search: strokeIcon(svg`
+ `),
+ brain: strokeIcon(svg`
+
+
+
+
+
+
+
+ `),
+ book: strokeIcon(
+ svg` `,
+ ),
+ loader: strokeIcon(svg`
+
+
+
+
+
+
+ `),
+ calendarClock: strokeIcon(svg`
+
+
+
+
+ `),
+ listChecks: strokeIcon(svg`
+
+
+
+ `),
...toolIcons,
} as const;