Overhaul UI with chat-like interface

Major UI improvements:
- Revamp timeline messages with chat-like interface
  - User messages now on right with white text on blue background
  - Agent/tool messages on left with black text on grey background
  - Chat bubbles extend up to 80% of screen width
  - Maintain left-aligned text for code readability
  - Move metadata to outer gutters
  - Show turn duration for end-of-turn messages
  - Integrate tool calls within agent message bubbles
  - Add thinking indicator with animated dots when LLM is processing
  - Replace buttons with intuitive icons (copy, info, etc.)

- Improve tool call presentation
  - Simplify to single row design with all essential info
  - Add clear status indicators for success/pending/error
  - Fix horizontal scrolling for long commands and outputs
  - Prevent tool name truncation
  - Improve spacing and alignment throughout

- Enhance header and status displays
  - Move Last Commit to dedicated third column in header grid
  - Add proper labeling with two-row structure
  - Provide consistent styling across all status elements

- Other UI refinements
  - Add root URL redirection to demo page
  - Fix spacing throughout the interface
  - Optimize CSS for better performance
  - Ensure consistent styling across components
  - Improve command output display and wrapping

Co-Authored-By: sketch <hello@sketch.dev>
diff --git a/webui/src/web-components/sketch-tool-card.ts b/webui/src/web-components/sketch-tool-card.ts
index 80dd2e9..d03b29d 100644
--- a/webui/src/web-components/sketch-tool-card.ts
+++ b/webui/src/web-components/sketch-tool-card.ts
@@ -1,6 +1,6 @@
 import { css, html, LitElement } from "lit";
 import { unsafeHTML } from "lit/directives/unsafe-html.js";
-import { customElement, property } from "lit/decorators.js";
+import { customElement, property, state } from "lit/decorators.js";
 import { ToolCall, MultipleChoiceOption, MultipleChoiceParams } from "../types";
 import { marked, MarkedOptions } from "marked";
 
@@ -29,23 +29,100 @@
   @property()
   open: boolean;
 
+  @state()
+  detailsVisible: boolean = false;
+
   static styles = css`
     .tool-call {
       display: flex;
+      flex-direction: column;
+      width: 100%;
+    }
+
+    .tool-row {
+      display: flex;
+      width: 100%;
+      box-sizing: border-box;
+      padding: 6px 8px 6px 12px;
       align-items: center;
-      gap: 8px;
+      gap: 8px; /* Reduce gap slightly to accommodate longer tool names */
+      cursor: pointer;
+      border-radius: 4px;
+      position: relative;
+      overflow: hidden; /* Changed to hidden to prevent horizontal scrolling */
+    }
+
+    .tool-row:hover {
+      background-color: rgba(0, 0, 0, 0.02);
+    }
+
+    .tool-name {
+      font-family: monospace;
+      font-weight: 500;
+      color: #444;
+      background-color: rgba(0, 0, 0, 0.05);
+      border-radius: 3px;
+      padding: 2px 6px;
+      flex-shrink: 0;
+      min-width: 45px;
+      /* Remove max-width to prevent truncation */
+      font-size: 12px;
+      text-align: center;
+      /* Remove overflow/ellipsis to ensure names are fully visible */
       white-space: nowrap;
     }
 
+    .tool-success {
+      color: #5cb85c;
+      font-size: 14px;
+    }
+
+    .tool-error {
+      color: #d9534f;
+      font-size: 14px;
+    }
+
+    .tool-pending {
+      color: #f0ad4e;
+      font-size: 14px;
+    }
+
+    .summary-text {
+      white-space: nowrap;
+      text-overflow: ellipsis;
+      overflow: hidden;
+      flex-grow: 1;
+      flex-shrink: 1;
+      color: #444;
+      font-family: monospace;
+      font-size: 12px;
+      padding: 0 4px;
+      min-width: 50px;
+      max-width: calc(
+        100% - 250px
+      ); /* More space for tool-name and tool-status */
+      display: inline-block; /* Ensure proper truncation */
+    }
+
+    .tool-status {
+      display: flex;
+      align-items: center;
+      gap: 12px;
+      margin-left: auto;
+      flex-shrink: 0;
+      min-width: 120px; /* Increased width to prevent cutoff */
+      justify-content: flex-end;
+      padding-right: 8px;
+    }
+
     .tool-call-status {
-      margin-right: 4px;
-      text-align: center;
+      display: flex;
+      align-items: center;
+      justify-content: center;
     }
 
     .tool-call-status.spinner {
       animation: spin 1s infinite linear;
-      display: inline-block;
-      width: 1em;
     }
 
     @keyframes spin {
@@ -57,89 +134,61 @@
       }
     }
 
-    .title {
-      font-style: italic;
+    .elapsed {
+      font-size: 11px;
+      color: #777;
+      white-space: nowrap;
+      min-width: 40px;
+      text-align: right;
+    }
+
+    .tool-details {
+      padding: 8px;
+      background-color: rgba(0, 0, 0, 0.02);
+      margin-top: 1px;
+      border-top: 1px solid rgba(0, 0, 0, 0.05);
+      display: none;
+      font-family: monospace;
+      font-size: 12px;
+      color: #333;
+      border-radius: 0 0 4px 4px;
+      max-width: 100%;
+      width: 100%;
+      box-sizing: border-box;
+      overflow: hidden; /* Hide overflow at container level */
+    }
+
+    .tool-details.visible {
+      display: block;
+    }
+
+    .expand-indicator {
+      color: #aaa;
+      font-size: 10px;
+      width: 12px;
+      display: inline-block;
+      text-align: center;
     }
 
     .cancel-button {
-      background: rgb(76, 175, 80);
-      color: white;
-      border: none;
-      padding: 4px 10px;
-      border-radius: 4px;
       cursor: pointer;
-      font-size: 12px;
-      margin: 5px;
+      color: white;
+      background-color: #d9534f;
+      border: none;
+      border-radius: 3px;
+      font-size: 11px;
+      padding: 2px 6px;
+      white-space: nowrap;
+      min-width: 50px;
     }
 
     .cancel-button:hover {
-      background: rgb(200, 35, 51) !important;
+      background-color: #c9302c;
     }
 
-    .codereview-OK {
-      color: green;
-    }
-
-    details {
-      border-radius: 4px;
-      padding: 0.25em;
-      margin: 0.25em;
-      display: flex;
-      flex-direction: column;
-      align-items: start;
-    }
-
-    details summary {
-      list-style: none;
-      &::before {
-        cursor: hand;
-        font-family: monospace;
-        content: "+";
-        color: white;
-        background-color: darkgray;
-        border-radius: 1em;
-        padding-left: 0.5em;
-        margin: 0.25em;
-        min-width: 1em;
-      }
-      [open] &::before {
-        content: "-";
-      }
-    }
-
-    details summary:hover {
-      list-style: none;
-      &::before {
-        background-color: gray;
-      }
-    }
-    summary {
-      display: flex;
-      flex-direction: row;
-      flex-wrap: nowrap;
-      justify-content: flex-start;
-      align-items: baseline;
-    }
-
-    summary .tool-name {
-      font-family: monospace;
-      color: white;
-      background: rgb(124 145 160);
-      border-radius: 4px;
-      padding: 0.25em;
-      margin: 0.25em;
-      white-space: pre;
-    }
-
-    .summary-text {
-      padding: 0.25em;
-      display: flex;
-      overflow: hidden;
-      text-overflow: ellipsis;
-    }
-
-    details[open] .summary-text {
-      /*display: none;*/
+    .cancel-button[disabled] {
+      background-color: #999;
+      cursor: not-allowed;
     }
 
     .tool-error-message {
@@ -147,11 +196,8 @@
       color: #aa0909;
     }
 
-    .elapsed {
-      font-size: 10px;
-      color: #888;
-      font-style: italic;
-      margin-left: 3px;
+    .codereview-OK {
+      color: green;
     }
   `;
 
@@ -194,16 +240,28 @@
     }
   };
 
-  render() {
-    const toolCallStatus = this.toolCall?.result_message
-      ? this.toolCall?.result_message.tool_error
-        ? html`🙈
-            <span class="tool-error-message"
-              >${this.toolCall?.result_message.tool_result}</span
-            >`
-        : ""
-      : "⏳";
+  _toggleDetails(e: Event) {
+    e.stopPropagation();
+    this.detailsVisible = !this.detailsVisible;
+  }
 
+  render() {
+    // Determine the status indicator based on the tool call result
+    let statusIcon;
+    if (!this.toolCall?.result_message) {
+      // Pending status with spinner
+      statusIcon = html`<span class="tool-call-status spinner tool-pending"
+        >⏳</span
+      >`;
+    } else if (this.toolCall?.result_message.tool_error) {
+      // Error status
+      statusIcon = html`<span class="tool-call-status tool-error">⚠️</span>`;
+    } else {
+      // Success status
+      statusIcon = html`<span class="tool-call-status tool-success">✓</span>`;
+    }
+
+    // Cancel button for pending operations
     const cancelButton = this.toolCall?.result_message
       ? ""
       : html`<button
@@ -218,32 +276,29 @@
           Cancel
         </button>`;
 
-    const status = html`<span
-      class="tool-call-status ${this.toolCall?.result_message ? "" : "spinner"}"
-      >${toolCallStatus}</span
-    >`;
-
-    const elapsed = html`${this.toolCall?.result_message?.elapsed
+    // Elapsed time display
+    const elapsed = this.toolCall?.result_message?.elapsed
       ? html`<span class="elapsed"
-          >${(this.toolCall?.result_message?.elapsed / 1e9).toFixed(2)}s
-          elapsed</span
+          >${(this.toolCall?.result_message?.elapsed / 1e9).toFixed(1)}s</span
         >`
-      : ""}`;
+      : html`<span class="elapsed"></span>`; // Empty span to maintain layout
 
-    const ret = html`<div class="tool-call">
-      <details ?open=${this.open}>
-        <summary>
-          <span class="tool-name">${this.toolCall?.name}</span>
-          <span class="summary-text"><slot name="summary"></slot></span>
-          ${status} ${cancelButton} ${elapsed}
-        </summary>
+    // Initialize details visibility based on open property
+    if (this.open && !this.detailsVisible) {
+      this.detailsVisible = true;
+    }
+
+    return html`<div class="tool-call">
+      <div class="tool-row" @click=${this._toggleDetails}>
+        <span class="tool-name">${this.toolCall?.name}</span>
+        <span class="summary-text"><slot name="summary"></slot></span>
+        <div class="tool-status">${statusIcon} ${elapsed} ${cancelButton}</div>
+      </div>
+      <div class="tool-details ${this.detailsVisible ? "visible" : ""}">
         <slot name="input"></slot>
         <slot name="result"></slot>
-      </details>
-    </div> `;
-    if (true) {
-      return ret;
-    }
+      </div>
+    </div>`;
   }
 }
 
@@ -261,24 +316,57 @@
       color: black;
       padding: 0.5em;
       border-radius: 4px;
+      white-space: pre-wrap; /* Always wrap long lines */
+      word-break: break-word; /* Use break-word for a more readable break */
+      max-width: 100%;
+      width: 100%;
+      box-sizing: border-box;
+      overflow-wrap: break-word; /* Additional property for better wrapping */
     }
     .summary-text {
       overflow: hidden;
       text-overflow: ellipsis;
+      white-space: nowrap;
+      max-width: 100%;
       font-family: monospace;
     }
+
+    .command-wrapper {
+      overflow: hidden;
+      text-overflow: ellipsis;
+      white-space: nowrap;
+      max-width: 100%;
+    }
     .input {
       display: flex;
+      width: 100%;
+      flex-direction: column; /* Change to column layout */
     }
     .input pre {
       width: 100%;
       margin-bottom: 0;
       border-radius: 4px 4px 0 0;
+      box-sizing: border-box; /* Include padding in width calculation */
     }
     .result pre {
       margin-top: 0;
       color: #555;
       border-radius: 0 0 4px 4px;
+      width: 100%; /* Ensure it uses full width */
+      box-sizing: border-box; /* Include padding in width calculation */
+      overflow-wrap: break-word; /* Ensure long words wrap */
+    }
+
+    /* Add a special class for long output that should be scrollable on hover */
+    .result pre.scrollable-on-hover {
+      max-height: 300px;
+      overflow-y: auto;
+    }
+
+    /* Container for tool call results with proper text wrapping */
+    .tool-call-result-container {
+      width: 100%;
+      position: relative;
     }
     .background-badge {
       display: inline-block;
@@ -292,8 +380,11 @@
       vertical-align: middle;
     }
     .command-wrapper {
-      display: flex;
-      align-items: center;
+      display: inline-block;
+      max-width: 100%;
+      overflow: hidden;
+      text-overflow: ellipsis;
+      white-space: nowrap;
     }
   `;
 
@@ -318,19 +409,23 @@
     <sketch-tool-card .open=${this.open} .toolCall=${this.toolCall}>
     <span slot="summary" class="summary-text">
       <div class="command-wrapper">
-        🖥️ ${backgroundIcon}${inputData?.command}
+        ${backgroundIcon}${inputData?.command}
       </div>
     </span>
     <div slot="input" class="input">
-      <pre>🖥️ ${backgroundIcon}${inputData?.command}</pre>
+      <div class="tool-call-result-container">
+        <pre>${backgroundIcon}${inputData?.command}</pre>
+      </div>
     </div>
     ${
       this.toolCall?.result_message
         ? html` ${this.toolCall?.result_message.tool_result
             ? html`<div slot="result" class="result">
-                <pre class="tool-call-result">
+                <div class="tool-call-result-container">
+                  <pre class="tool-call-result">
 ${this.toolCall?.result_message.tool_result}</pre
-                >
+                  >
+                </div>
               </div>`
             : ""}`
         : ""
@@ -587,12 +682,15 @@
   render() {
     const inputData = JSON.parse(this.toolCall?.input || "{}");
     return html`
-      <span class="summary-text">
-        Setting title to
-        <b>${inputData.title}</b>
-        and branch to
-        <pre>sketch/${inputData.branch_name}</pre>
-      </span>
+      <sketch-tool-card .open=${this.open} .toolCall=${this.toolCall}>
+        <span slot="summary" class="summary-text">
+          Title: "${inputData.title}" | Branch: sketch/${inputData.branch_name}
+        </span>
+        <div slot="input">
+          <div>Set title to: <b>${inputData.title}</b></div>
+          <div>Set branch to: <code>sketch/${inputData.branch_name}</code></div>
+        </div>
+      </sketch-tool-card>
     `;
   }
 }