diff --git a/CHANGELOG.md b/CHANGELOG.md
index 277e3bd..e598aa4 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -31,6 +31,8 @@ All notable user-visible changes to this project are documented in this file.
### Changed
+- A surface card's open and delete actions are now minimal Lucide icons
+ (external-link and trash) instead of text labels; delete turns red on hover.
- `sideshow-term watch` now starts a local server in the background when needed,
and bare `sideshow-term` opens the watcher. Terminal servers default to port
4243, with `--port` for choosing another local port. The watcher supports
diff --git a/viewer/src/Card.tsx b/viewer/src/Card.tsx
index 893950b..f1e5da5 100644
--- a/viewer/src/Card.tsx
+++ b/viewer/src/Card.tsx
@@ -8,6 +8,7 @@ import {
type TracePart as TracePartData,
} from "./api.ts";
import { DiffPart } from "./DiffPart.tsx";
+import { OpenIcon, TrashIcon } from "./icons.tsx";
import { ImagePart } from "./ImagePart.tsx";
import { TracePart } from "./TracePart.tsx";
import {
@@ -88,18 +89,26 @@ export function Card(props: { surface: Surface }) {
{relTime(props.surface.updatedAt)}
-
- open ↗
+
+
{/* Parts render in order, dispatched by kind. Each kind is an explicit
diff --git a/viewer/src/icons.tsx b/viewer/src/icons.tsx
new file mode 100644
index 0000000..adb0422
--- /dev/null
+++ b/viewer/src/icons.tsx
@@ -0,0 +1,44 @@
+import type { JSX } from "solid-js";
+
+// Inline Lucide icons (https://lucide.dev, ISC license) — a couple of glyphs
+// for the card chrome. Inlined rather than pulling in a package: it keeps the
+// bundle lean and the icons inherit `currentColor` and the CSS-driven size.
+function Icon(props: { children: JSX.Element }) {
+ return (
+
+ );
+}
+
+// lucide: external-link
+export function OpenIcon() {
+ return (
+
+
+
+
+
+ );
+}
+
+// lucide: trash-2
+export function TrashIcon() {
+ return (
+
+
+
+
+
+
+
+ );
+}
diff --git a/viewer/src/styles.css b/viewer/src/styles.css
index f8cf394..0eece36 100644
--- a/viewer/src/styles.css
+++ b/viewer/src/styles.css
@@ -10,6 +10,7 @@
--accent: #185fa5;
--accent-bg: #e6f1fb;
--hover: rgba(20, 20, 10, 0.05);
+ --danger: #c0392b;
}
@media (prefers-color-scheme: dark) {
:root {
@@ -24,6 +25,7 @@
--accent: #85b7eb;
--accent-bg: rgba(55, 138, 221, 0.16);
--hover: rgba(255, 255, 250, 0.06);
+ --danger: #e8776b;
}
}
* {
@@ -344,6 +346,24 @@ select.vbadge {
color: var(--text);
background: var(--hover);
}
+/* Icon-only actions (open/delete): square hit area, centered glyph. Unlike the
+ text actions, these stay visible at all times — they're subtle enough not to
+ need the hover reveal. */
+.card-head .act.icon {
+ display: inline-flex;
+ align-items: center;
+ justify-content: center;
+ padding: 4px;
+ opacity: 1;
+}
+.card-head .act.icon svg {
+ width: 13px;
+ height: 13px;
+ display: block;
+}
+.card-head .act.icon.del:hover {
+ color: var(--danger);
+}
iframe {
display: block;
width: 100%;