diff --git a/src/pages/StreamPanel.tsx b/src/pages/StreamPanel.tsx
index 9fb876a..fe7cdda 100644
--- a/src/pages/StreamPanel.tsx
+++ b/src/pages/StreamPanel.tsx
@@ -1,5 +1,6 @@
import * as React from "react";
import { LiveRegion } from "../components/LiveRegion";
+import "../styles/print.css";
export type StreamStatus =
| "connected"
@@ -35,15 +36,17 @@ function formatLabel(status: StreamStatus): string {
export function StreamPanel({ status, label }: StreamPanelProps) {
return (
-
-
-
- {label ?? formatLabel(status)}
-
-
+
+
+
+
+ {label ?? formatLabel(status)}
+
+
+
);
}
diff --git a/src/pages/__tests__/StreamPanel.print.test.ts b/src/pages/__tests__/StreamPanel.print.test.ts
new file mode 100644
index 0000000..6bece1a
--- /dev/null
+++ b/src/pages/__tests__/StreamPanel.print.test.ts
@@ -0,0 +1,21 @@
+import fs from "node:fs";
+import path from "node:path";
+
+describe("StreamPanel print presentation", () => {
+ const componentPath = path.join(process.cwd(), "src/pages/StreamPanel.tsx");
+ const printCssPath = path.join(process.cwd(), "src/styles/print.css");
+
+ it("provides a print stylesheet for StreamPanel", () => {
+ const css = fs.readFileSync(printCssPath, "utf8");
+ expect(css).toContain("@media print");
+ expect(css).toContain(".stream-panel-container");
+ expect(css).toContain(".sr-only");
+ expect(css).toContain("display: none !important");
+ });
+
+ it("connects StreamPanel to the print stylesheet", () => {
+ const component = fs.readFileSync(componentPath, "utf8");
+ expect(component).toContain('import "../styles/print.css";');
+ expect(component).toContain("stream-panel-container");
+ });
+});
\ No newline at end of file
diff --git a/src/styles/print.css b/src/styles/print.css
index 8ecc56c..3c0e4e5 100644
--- a/src/styles/print.css
+++ b/src/styles/print.css
@@ -76,3 +76,39 @@
height: auto !important;
}
}
+
+/* StreamPanel print presentation. The aria-live region (screen-reader only)
+ * is omitted from printed output, while the status indicator and label are
+ * preserved as a clean summary. */
+@media print {
+ .stream-panel-container {
+ max-width: none !important;
+ padding: 0 !important;
+ background: #fff !important;
+ color: #000 !important;
+ }
+
+ .stream-panel-container .sr-only {
+ display: none !important;
+ }
+
+ .stream-panel-container [class*="text-muted-foreground"] {
+ color: #374151 !important;
+ }
+
+ .stream-panel-container [class*="bg-card"],
+ .stream-panel-container [class*="bg-background"],
+ .stream-panel-container [class*="bg-muted"] {
+ background: #fff !important;
+ }
+
+ .stream-panel-container a {
+ color: #000 !important;
+ text-decoration: none !important;
+ }
+
+ .stream-panel-container .stream-panel {
+ border: 1px solid #d1d5db !important;
+ box-shadow: none !important;
+ }
+}