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-view-mode-select.ts b/webui/src/web-components/sketch-view-mode-select.ts
index 0264f87..8498f55 100644
--- a/webui/src/web-components/sketch-view-mode-select.ts
+++ b/webui/src/web-components/sketch-view-mode-select.ts
@@ -74,14 +74,14 @@
   render() {
     return html`
       <div
-        class="flex mr-2.5 bg-gray-100 rounded border border-gray-300 overflow-hidden"
+        class="flex mr-2.5 bg-gray-100 dark:bg-gray-800 rounded border border-gray-300 dark:border-gray-600 overflow-hidden"
       >
         <button
           id="showConversationButton"
-          class="px-3 py-2 bg-none border-0 border-b-2 cursor-pointer text-xs flex items-center gap-1.5 text-gray-600 border-transparent transition-all whitespace-nowrap ${this
+          class="px-3 py-2 bg-none border-0 border-b-2 cursor-pointer text-xs flex items-center gap-1.5 text-gray-600 dark:text-gray-400 border-transparent transition-all whitespace-nowrap ${this
             .activeMode === "chat"
-            ? "!border-b-blue-600 text-blue-600 font-medium bg-blue-50"
-            : "hover:bg-gray-200"} @xl:px-3 @xl:py-2 @max-xl:px-2.5 @max-xl:[&>span:not(.tab-icon):not(.diff-stats)]:hidden @max-xl:[&>.diff-stats]:inline @max-xl:[&>.diff-stats]:text-xs @max-xl:[&>.diff-stats]:ml-0.5 border-r border-gray-200 last-of-type:border-r-0"
+            ? "border-b-blue-600 dark:border-b-gray-500 text-blue-600 font-medium bg-blue-50 dark:bg-gray-700"
+            : "hover:bg-gray-200 dark:hover:bg-gray-700"} @xl:px-3 @xl:py-2 @max-xl:px-2.5 @max-xl:[&>span:not(.tab-icon):not(.diff-stats)]:hidden @max-xl:[&>.diff-stats]:inline @max-xl:[&>.diff-stats]:text-xs @max-xl:[&>.diff-stats]:ml-0.5 border-r border-gray-200 dark:border-gray-600 last-of-type:border-r-0"
           title="Conversation View"
           @click=${() => this._handleViewModeClick("chat")}
         >
@@ -90,10 +90,10 @@
         </button>
         <button
           id="showDiff2Button"
-          class="px-3 py-2 bg-none border-0 border-b-2 cursor-pointer text-xs flex items-center gap-1.5 text-gray-600 border-transparent transition-all whitespace-nowrap ${this
+          class="px-3 py-2 bg-none border-0 border-b-2 cursor-pointer text-xs flex items-center gap-1.5 text-gray-600 dark:text-gray-400 border-transparent transition-all whitespace-nowrap ${this
             .activeMode === "diff2"
-            ? "!border-b-blue-600 text-blue-600 font-medium bg-blue-50"
-            : "hover:bg-gray-200"} @xl:px-3 @xl:py-2 @max-xl:px-2.5 @max-xl:[&>span:not(.tab-icon):not(.diff-stats)]:hidden @max-xl:[&>.diff-stats]:inline @max-xl:[&>.diff-stats]:text-xs @max-xl:[&>.diff-stats]:ml-0.5 border-r border-gray-200 last-of-type:border-r-0"
+            ? "border-b-blue-600 dark:border-b-gray-500 text-blue-600 font-medium bg-blue-50 dark:bg-gray-700"
+            : "hover:bg-gray-200 dark:hover:bg-gray-700"} @xl:px-3 @xl:py-2 @max-xl:px-2.5 @max-xl:[&>span:not(.tab-icon):not(.diff-stats)]:hidden @max-xl:[&>.diff-stats]:inline @max-xl:[&>.diff-stats]:text-xs @max-xl:[&>.diff-stats]:ml-0.5 border-r border-gray-200 dark:border-gray-600 last-of-type:border-r-0"
           title="Diff View - ${this.diffLinesAdded > 0 ||
           this.diffLinesRemoved > 0
             ? `+${this.diffLinesAdded} -${this.diffLinesRemoved}`
@@ -115,10 +115,10 @@
 
         <button
           id="showTerminalButton"
-          class="px-3 py-2 bg-none border-0 border-b-2 cursor-pointer text-xs flex items-center gap-1.5 text-gray-600 border-transparent transition-all whitespace-nowrap ${this
+          class="px-3 py-2 bg-none border-0 border-b-2 cursor-pointer text-xs flex items-center gap-1.5 text-gray-600 dark:text-gray-400 border-transparent transition-all whitespace-nowrap ${this
             .activeMode === "terminal"
-            ? "!border-b-blue-600 text-blue-600 font-medium bg-blue-50"
-            : "hover:bg-gray-200"} @xl:px-3 @xl:py-2 @max-xl:px-2.5 @max-xl:[&>span:not(.tab-icon):not(.diff-stats)]:hidden @max-xl:[&>.diff-stats]:inline @max-xl:[&>.diff-stats]:text-xs @max-xl:[&>.diff-stats]:ml-0.5 border-r border-gray-200 last-of-type:border-r-0"
+            ? "border-b-blue-600 !dark:border-b-gray-500 text-blue-600 font-medium bg-blue-50 dark:bg-gray-700"
+            : "hover:bg-gray-200 dark:hover:bg-gray-700"} @xl:px-3 @xl:py-2 @max-xl:px-2.5 @max-xl:[&>span:not(.tab-icon):not(.diff-stats)]:hidden @max-xl:[&>.diff-stats]:inline @max-xl:[&>.diff-stats]:text-xs @max-xl:[&>.diff-stats]:ml-0.5 border-r border-gray-200 dark:border-gray-600 last-of-type:border-r-0"
           title="Terminal View"
           @click=${() => this._handleViewModeClick("terminal")}
         >