webui: add print styles for full chat printing

Implement CSS print media queries across key webui components to ensure
complete chat conversations can be printed without content truncation.

They're not perfect but better than nothing.

Co-Authored-By: sketch <hello@sketch.dev>
Change-ID: s3815b4291912c721k
diff --git a/webui/src/sketch-app-shell.css b/webui/src/sketch-app-shell.css
index 65b06ae..4c57faa 100644
--- a/webui/src/sketch-app-shell.css
+++ b/webui/src/sketch-app-shell.css
@@ -20,3 +20,17 @@
   src: url("./monaco/min/vs/base/browser/ui/codicons/codicon/codicon.ttf")
     format("truetype");
 }
+
+/* Print styles for full chat printing */
+@media print {
+  html,
+  body {
+    height: auto !important;
+    overflow: visible !important;
+  }
+
+  body {
+    margin: 0;
+    padding: 0;
+  }
+}
diff --git a/webui/src/web-components/demo/print-test.html b/webui/src/web-components/demo/print-test.html
new file mode 100644
index 0000000..c4a62fe
--- /dev/null
+++ b/webui/src/web-components/demo/print-test.html
@@ -0,0 +1,207 @@
+<!doctype html>
+<html lang="en">
+  <head>
+    <meta charset="UTF-8" />
+    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+    <title>Sketch Print Test</title>
+    <style>
+      body {
+        font-family:
+          system-ui,
+          -apple-system,
+          sans-serif;
+        margin: 0;
+        padding: 20px;
+        background: #f5f5f5;
+      }
+
+      .container {
+        max-width: 800px;
+        margin: 0 auto;
+        background: white;
+        padding: 20px;
+        border-radius: 8px;
+        box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
+      }
+
+      .chat-container {
+        height: 400px;
+        overflow-y: auto;
+        border: 1px solid #ddd;
+        padding: 10px;
+        margin: 20px 0;
+      }
+
+      .message {
+        margin: 10px 0;
+        padding: 10px;
+        border-radius: 6px;
+      }
+
+      .user-message {
+        background: #e3f2fd;
+        border-left: 4px solid #2196f3;
+      }
+
+      .agent-message {
+        background: #f3e5f5;
+        border-left: 4px solid #9c27b0;
+      }
+
+      .print-button {
+        background: #4caf50;
+        color: white;
+        border: none;
+        padding: 10px 20px;
+        border-radius: 4px;
+        cursor: pointer;
+        font-size: 16px;
+      }
+
+      .print-button:hover {
+        background: #45a049;
+      }
+
+      /* Print styles */
+      @media print {
+        body {
+          background: white !important;
+          padding: 0 !important;
+        }
+
+        .container {
+          max-width: none !important;
+          margin: 0 !important;
+          padding: 0 !important;
+          box-shadow: none !important;
+          border-radius: 0 !important;
+        }
+
+        .chat-container {
+          height: auto !important;
+          max-height: none !important;
+          overflow: visible !important;
+          border: none !important;
+          padding: 0 !important;
+          margin: 0 !important;
+        }
+
+        .print-button {
+          display: none !important;
+        }
+
+        .message {
+          page-break-inside: avoid;
+          margin: 8px 0;
+        }
+
+        h1,
+        h2,
+        h3 {
+          page-break-after: avoid;
+        }
+      }
+    </style>
+  </head>
+  <body>
+    <div class="container">
+      <h1>Sketch Print Test</h1>
+      <p>
+        This page tests the print functionality for sketch chat. Use Ctrl+P (or
+        Cmd+P on Mac) to print.
+      </p>
+
+      <button class="print-button" onclick="window.print()">Print Test</button>
+
+      <div class="chat-container">
+        <div class="message user-message">
+          <strong>User:</strong> Hello, can you help me with some code?
+        </div>
+
+        <div class="message agent-message">
+          <strong>Agent:</strong> Of course! I'd be happy to help you with your
+          code. What specific programming language or problem are you working
+          on?
+        </div>
+
+        <div class="message user-message">
+          <strong>User:</strong> I need to fix a CSS issue with printing. The
+          content gets cut off when printing.
+        </div>
+
+        <div class="message agent-message">
+          <strong>Agent:</strong> That's a common issue with web applications.
+          The problem usually occurs when:
+          <ul>
+            <li>Container elements have fixed heights</li>
+            <li>Overflow properties are set to 'auto' or 'hidden'</li>
+            <li>Flexbox layouts don't expand properly for print</li>
+          </ul>
+
+          <p>Here's how to fix it:</p>
+
+          <pre><code>@media print {
+  .container {
+    height: auto !important;
+    max-height: none !important;
+    overflow: visible !important;
+  }
+  
+  .scrollable-content {
+    height: auto !important;
+    overflow: visible !important;
+  }
+}</code></pre>
+        </div>
+
+        <div class="message user-message">
+          <strong>User:</strong> That makes sense! Should I also hide
+          interactive elements during print?
+        </div>
+
+        <div class="message agent-message">
+          <strong>Agent:</strong> Absolutely! Interactive elements like buttons,
+          form inputs, and navigation menus should typically be hidden during
+          print since they're not functional on paper. You can do this with:
+
+          <pre><code>@media print {
+  .button, .interactive-element {
+    display: none !important;
+  }
+}</code></pre>
+
+          <p>Also consider:</p>
+          <ul>
+            <li>
+              Use <code>page-break-inside: avoid</code> on important content
+              blocks
+            </li>
+            <li>
+              Remove shadows, borders, and background colors that waste ink
+            </li>
+            <li>Ensure text is black on white for better readability</li>
+            <li>Adjust margins and padding for better paper layout</li>
+          </ul>
+        </div>
+
+        <div class="message user-message">
+          <strong>User:</strong> Perfect! This should solve my printing issues.
+          Thank you!
+        </div>
+
+        <div class="message agent-message">
+          <strong>Agent:</strong> You're welcome! The key is to remember that
+          print styles should make content flow naturally on paper rather than
+          being constrained by screen dimensions. Always test your print styles
+          by using your browser's print preview feature.
+        </div>
+      </div>
+
+      <p>
+        <strong>Instructions:</strong> Click the "Print Test" button or use
+        Ctrl+P to test the print functionality. The chat should print across
+        multiple pages if needed, with proper page breaks.
+      </p>
+    </div>
+  </body>
+</html>
diff --git a/webui/src/web-components/sketch-app-shell.ts b/webui/src/web-components/sketch-app-shell.ts
index b0177a0..0f0177c 100644
--- a/webui/src/web-components/sketch-app-shell.ts
+++ b/webui/src/web-components/sketch-app-shell.ts
@@ -466,6 +466,84 @@
       transform: rotate(45deg);
       transform-origin: center center;
     }
+
+    /* Print styles for full chat printing */
+    @media print {
+      :host {
+        height: auto !important;
+        overflow: visible !important;
+        display: block !important;
+      }
+
+      /* Hide non-essential UI elements during printing */
+      #top-banner {
+        border-bottom: 1px solid #000;
+        box-shadow: none;
+        page-break-inside: avoid;
+      }
+
+      /* Hide interactive elements that aren't useful in print */
+      .stop-button,
+      .end-button,
+      .notifications-toggle,
+      sketch-call-status,
+      sketch-network-status,
+      sketch-view-mode-select {
+        display: none !important;
+      }
+
+      /* Ensure view container can expand to full content */
+      #view-container {
+        overflow: visible !important;
+        flex: none !important;
+        height: auto !important;
+        max-height: none !important;
+      }
+
+      #view-container-inner {
+        height: auto !important;
+        max-height: none !important;
+        overflow: visible !important;
+      }
+
+      /* Remove todo panel from print to avoid layout issues */
+      .todo-panel-container {
+        display: none !important;
+      }
+
+      /* Ensure chat timeline container takes full width in print */
+      .chat-timeline-container {
+        margin-right: 0 !important;
+        width: 100% !important;
+        height: auto !important;
+        overflow: visible !important;
+      }
+
+      /* Make chat view fully visible */
+      .chat-view {
+        height: auto !important;
+        overflow: visible !important;
+      }
+
+      /* Hide chat input during printing */
+      #chat-input {
+        display: none !important;
+      }
+
+      /* Adjust diff2 and terminal views for print */
+      .diff2-view,
+      .terminal-view {
+        height: auto !important;
+        overflow: visible !important;
+      }
+
+      /* Ensure only active view is shown in print */
+      .chat-view:not(.view-active),
+      .diff2-view:not(.view-active),
+      .terminal-view:not(.view-active) {
+        display: none !important;
+      }
+    }
   `;
 
   // Header bar: Network connection status details
diff --git a/webui/src/web-components/sketch-timeline-message.ts b/webui/src/web-components/sketch-timeline-message.ts
index 9fa5b7a..35897b4 100644
--- a/webui/src/web-components/sketch-timeline-message.ts
+++ b/webui/src/web-components/sketch-timeline-message.ts
@@ -744,6 +744,56 @@
     .mermaid {
       text-align: center;
     }
+
+    /* Print styles for message components */
+    @media print {
+      .message {
+        page-break-inside: avoid;
+        margin-bottom: 12px;
+      }
+
+      .message-container {
+        page-break-inside: avoid;
+      }
+
+      /* Hide copy buttons and interactive elements during printing */
+      .copy-icon,
+      .info-icon,
+      .commit-diff-button {
+        display: none !important;
+      }
+
+      /* Ensure code blocks print properly */
+      .message-content pre {
+        white-space: pre-wrap;
+        word-wrap: break-word;
+        page-break-inside: avoid;
+        background: #f8f8f8 !important;
+        border: 1px solid #ddd !important;
+        padding: 8px !important;
+      }
+
+      /* Ensure tool calls section prints properly */
+      .tool-calls-section {
+        page-break-inside: avoid;
+      }
+
+      /* Simplify message metadata for print */
+      .message-metadata-left {
+        font-size: 10px;
+      }
+
+      /* Ensure content doesn't break poorly */
+      .message-content {
+        orphans: 3;
+        widows: 3;
+      }
+
+      /* Hide floating messages during print */
+      .floating-message {
+        display: none !important;
+      }
+    }
   `;
 
   // Track mermaid diagrams that need rendering
diff --git a/webui/src/web-components/sketch-timeline.ts b/webui/src/web-components/sketch-timeline.ts
index 2f8e5e3..964574e 100644
--- a/webui/src/web-components/sketch-timeline.ts
+++ b/webui/src/web-components/sketch-timeline.ts
@@ -259,8 +259,51 @@
         transform: rotate(360deg);
       }
     }
-  `;
 
+    /* Print styles for full timeline printing */
+    @media print {
+      .timeline-container {
+        height: auto !important;
+        max-height: none !important;
+        overflow: visible !important;
+        page-break-inside: avoid;
+      }
+
+      .timeline {
+        height: auto !important;
+        max-height: none !important;
+        overflow: visible !important;
+      }
+
+      #scroll-container {
+        height: auto !important;
+        max-height: none !important;
+        overflow: visible !important;
+        overflow-y: visible !important;
+        overflow-x: visible !important;
+      }
+
+      /* Hide the jump to latest button during printing */
+      #jump-to-latest {
+        display: none !important;
+      }
+
+      /* Hide the thinking indicator during printing */
+      .thinking-indicator {
+        display: none !important;
+      }
+
+      /* Hide the loading indicator during printing */
+      .loading-indicator {
+        display: none !important;
+      }
+
+      /* Ensure welcome box prints properly if visible */
+      .welcome-box {
+        page-break-inside: avoid;
+      }
+    }
+  `;
   constructor() {
     super();