webui: implement comprehensive dark mode support
Add complete dark mode implementation across all web UI components with
theme initialization and consistent styling:
Core infrastructure:
- Update DARK_MODE.md documentation with current implementation details
- Add theme initialization to sketch-app-shell-base component
- Implement ThemeService integration with existing theme toggle system
Component updates with dark mode variants:
- sketch-app-shell: Main container backgrounds and text colors
- sketch-app-shell-base: Top banner, todo panel container with gradient backgrounds
- sketch-chat-input: Input fields, buttons, overlay messages, and drop zones
- sketch-container-status: Info panels, SSH connection displays, and expandable details
- sketch-call-status: Status indicators, banners, and activity states
- sketch-view-mode-select: Tab container, button states, and active tab styling
- sketch-timeline-message: Message bubbles, markdown content, code blocks, and commit info
- sketch-push-button: Overlay popup, form controls, and result containers
- sketch-todo-panel: Todo items, headers, comment modal, and form elements
- sketch-diff-range-picker: Dropdown interface, commit display, and git reference badges
CSS and styling improvements:
- Comprehensive markdown content styling for dark theme
- Code block backgrounds and syntax highlighting adjustments
- Mermaid diagram container styling for dark mode
- Auto-generated link styling with proper contrast
- Git reference badge colors (tags: amber, branches: green, sketch-base: blue)
Interactive element enhancements:
- Consistent hover states across light and dark themes
- Proper focus indicators with accessible contrast ratios
- Loading spinners and progress indicators adapted for dark backgrounds
- Error and success message styling with semantic color preservation
Key implementation details:
- Consistent color mappings: white→gray-900, gray-100→gray-800, gray-200→gray-700
- Preserved brand colors (blue-500, red-600, green-600) that work in both themes
- Maintained semantic color coding for success/error/warning states
- Ensured accessibility with proper contrast ratios throughout
- Theme system integration enables seamless switching without page reload
The web UI now provides a complete, professional dark mode experience
with excellent usability and visual consistency while preserving all
existing functionality and accessibility standards.
Co-Authored-By: sketch <hello@sketch.dev>
Change-ID: s8219557c3ecba46dk
diff --git a/webui/src/web-components/sketch-diff-range-picker.ts b/webui/src/web-components/sketch-diff-range-picker.ts
index 5c51de4..0e20636 100644
--- a/webui/src/web-components/sketch-diff-range-picker.ts
+++ b/webui/src/web-components/sketch-diff-range-picker.ts
@@ -104,12 +104,16 @@
render() {
return html`
- <div class="block w-full font-system text-gray-800">
+ <div class="block w-full font-system text-gray-800 dark:text-gray-200">
<div class="flex flex-col gap-3 w-full">
${this.loading
- ? html`<div class="italic text-gray-500">Loading commits...</div>`
+ ? html`<div class="italic text-gray-500 dark:text-gray-400">
+ Loading commits...
+ </div>`
: this.error
- ? html`<div class="text-red-600 text-sm">${this.error}</div>`
+ ? html`<div class="text-red-600 dark:text-red-400 text-sm">
+ ${this.error}
+ </div>`
: this.renderRangePicker()}
</div>
</div>
@@ -134,7 +138,9 @@
return html`
<div class="flex items-center gap-2 flex-1 relative">
- <label for="fromCommit" class="font-medium text-sm text-gray-700"
+ <label
+ for="fromCommit"
+ class="font-medium text-sm text-gray-700 dark:text-gray-300"
>Diff from:</label
>
<div
@@ -142,9 +148,9 @@
@click=${this.toggleDropdown}
>
<button
- class="w-full py-2 px-3 pr-8 border rounded text-left min-h-[36px] text-sm relative cursor-pointer bg-white ${isDefaultCommit
- ? "border-blue-500 bg-blue-50"
- : "border-gray-300 hover:border-gray-400"} focus:outline-none focus:border-blue-500 focus:ring-2 focus:ring-blue-200"
+ class="w-full py-2 px-3 pr-8 border rounded text-left min-h-[36px] text-sm relative cursor-pointer bg-white dark:bg-gray-800 text-gray-900 dark:text-gray-100 ${isDefaultCommit
+ ? "border-blue-500 bg-blue-50 dark:bg-blue-900/30"
+ : "border-gray-300 dark:border-gray-600 hover:border-gray-400 dark:hover:border-gray-500"} focus:outline-none focus:border-blue-500 focus:ring-2 focus:ring-blue-200 dark:focus:ring-blue-800"
@click=${this.toggleDropdown}
@blur=${this.handleBlur}
>
@@ -168,16 +174,16 @@
${this.dropdownOpen
? html`
<div
- class="absolute top-full left-0 right-0 bg-white border border-gray-300 rounded shadow-lg z-50 max-h-[300px] overflow-y-auto mt-0.5"
+ class="absolute top-full left-0 right-0 bg-white dark:bg-gray-800 border border-gray-300 dark:border-gray-600 rounded shadow-lg z-50 max-h-[300px] overflow-y-auto mt-0.5"
>
${this.commits.map(
(commit) => html`
<div
- class="px-3 py-2.5 cursor-pointer border-b border-gray-100 last:border-b-0 flex items-start gap-2 text-sm leading-5 hover:bg-gray-50 ${commit.hash ===
+ class="px-3 py-2.5 cursor-pointer border-b border-gray-100 dark:border-gray-700 last:border-b-0 flex items-start gap-2 text-sm leading-5 hover:bg-gray-50 dark:hover:bg-gray-700 ${commit.hash ===
this.fromCommit
- ? "bg-blue-50"
+ ? "bg-blue-50 dark:bg-blue-900/30"
: ""} ${this.isSketchBaseCommit(commit)
- ? "bg-blue-50 border-l-4 border-l-blue-500 pl-2"
+ ? "bg-blue-50 dark:bg-blue-900/30 border-l-4 border-l-blue-500 pl-2"
: ""}"
@click=${() => this.selectCommit(commit.hash)}
>
@@ -362,8 +368,12 @@
}
return html`
- <span class="font-mono text-gray-600 text-xs">${shortHash}</span>
- <span class="text-gray-800 text-xs truncate">${subject}</span>
+ <span class="font-mono text-gray-600 dark:text-gray-400 text-xs"
+ >${shortHash}</span
+ >
+ <span class="text-gray-800 dark:text-gray-200 text-xs truncate"
+ >${subject}</span
+ >
${this.isSketchBaseCommit(commit)
? html`
<span
@@ -386,8 +396,11 @@
}
return html`
- <span class="font-mono text-gray-600 text-xs">${shortHash}</span>
- <span class="text-gray-800 text-xs flex-1 truncate min-w-[200px]"
+ <span class="font-mono text-gray-600 dark:text-gray-400 text-xs"
+ >${shortHash}</span
+ >
+ <span
+ class="text-gray-800 dark:text-gray-200 text-xs flex-1 truncate min-w-[200px]"
>${subject}</span
>
${commit.refs && commit.refs.length > 0
@@ -412,8 +425,8 @@
const refClass = isSketchBase
? "bg-blue-600 text-white font-semibold"
: ref.includes("tag")
- ? "bg-amber-100 text-amber-800"
- : "bg-green-100 text-green-800";
+ ? "bg-amber-100 dark:bg-amber-900 text-amber-800 dark:text-amber-200"
+ : "bg-green-100 dark:bg-green-900 text-green-800 dark:text-green-200";
return html`<span
class="px-1.5 py-0.5 rounded-full text-xs font-medium ${refClass}"
>${shortRef}</span