Compare commits

..
1 Commits
Author SHA1 Message Date
Miguel PalhasandClaude Opus 4.6 f3a5cad789 feat(maestro): widen sidebar activity rail from 5px to 7px
Makes the coloured state bars more visible at a glance.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-09-10 21:53:18 +01:00
7 changed files with 22 additions and 23 deletions
+1 -1
View File
@@ -70,7 +70,7 @@ command. `<duration>` follows in the rail's colour when shown. There is no
state word and no second badge: the rail exists so the state is still legible
when a row is dimmed or the terminal renders the duration in the default fg.
In the **web client** the rail is a 5px bar pinned to the row's own left
In the **web client** the rail is a 7px bar pinned to the row's own left
edge, square corners, spanning the full card height edge to edge — it
shifts outward with nesting depth along with the row's own padding, since
it is positioned relative to the row. It carries motion only for states that
+1 -1
View File
@@ -105,7 +105,7 @@ describe("MultiView", () => {
expect(screen.getByText("Tab 1 · 1")).toBeTruthy();
const pane = document.querySelector('[data-session-id="s9"]');
expect(pane).toBeTruthy();
expect(pane!.classList.contains("is-preview")).toBe(true);
expect(pane!.querySelector(".bg-preview-tint")).toBeTruthy();
expect(screen.getByText("preview")).toBeTruthy();
});
+6 -4
View File
@@ -188,9 +188,8 @@ function Pane({
return (
<div
className={
"mv-pane flex h-full min-h-0 min-w-0 flex-col" +
(isFocused ? " is-focused" : "") +
(isPreview ? " is-preview" : "")
"mv-pane flex h-full min-h-0 min-w-0 flex-col border " +
(isFocused && !isPreview ? "border-accent" : "border-border-strong")
}
data-leaf-id={leaf.id}
data-session-id={leaf.sessionId ?? undefined}
@@ -202,7 +201,10 @@ function Pane({
}}
>
<div
className="mv-pane-header attach-header flex items-center justify-between gap-sp-2 border-b border-border-strong px-sp-2 py-sp-1 text-fs-12"
className={
"mv-pane-header flex items-center justify-between gap-sp-2 border-b border-border-strong px-sp-2 py-sp-1 text-fs-12 " +
(isPreview ? "bg-preview-tint text-preview" : "bg-surface")
}
>
{leaf.sessionId ? (
<PaneTitle sessionId={leaf.sessionId} session={session} />
+2 -2
View File
@@ -15,7 +15,7 @@ export interface PaneTitleProps {
export function PaneTitle({ sessionId, session, className }: PaneTitleProps) {
if (!session) {
return (
<span className={className ?? "attach-title"} title={sessionId}>
<span className={className ?? "at-title"} title={sessionId}>
session <span className="sid">{sessionId.slice(0, 8)}</span>
</span>
);
@@ -27,7 +27,7 @@ export function PaneTitle({ sessionId, session, className }: PaneTitleProps) {
const icon = tool ? toolIconSvg(tool) : null;
return (
<span className={className ?? "attach-title"} title={`${name} · ${session.command} (${sessionId})`}>
<span className={className ?? "at-title"} title={`${name} · ${session.command} (${sessionId})`}>
<span className="at-name">{name}</span>
{showCommand && (
<span className="at-cmd">
+2 -2
View File
@@ -1,4 +1,4 @@
// docs/SIDEBAR.md: a 5px bar pinned to the row's own left edge, square
// docs/SIDEBAR.md: a 7px bar pinned to the row's own left edge, square
// corners, full card height. It paints for every card, Idle included, and it
// carries the accessible name of the state so status is never colour-only.
@@ -37,7 +37,7 @@ export function ActivityRail({ activity }: { activity: ActivityState | string |
const word = STATE_WORDS[slug] ?? STATE_WORDS.idle;
return (
<span
className={`absolute left-0 top-0 bottom-0 w-[5px] ${RAIL_CLASS[slug] ?? RAIL_CLASS.idle}`}
className={`absolute left-0 top-0 bottom-0 w-[7px] ${RAIL_CLASS[slug] ?? RAIL_CLASS.idle}`}
data-activity={slug}
role="img"
title={word}
+9 -12
View File
@@ -44,17 +44,14 @@ export interface SessionCardProps {
onRenameCancel(): void;
}
/** The fill ladder from docs/SIDEBAR.md "Which row is filled" — the CSS
* cascade in styles.css carries the actual fills via `.is-active`, `.is-open`,
* `.is-previewing` (all inside `:where()` so source order is the precedence).
* We just apply the right class names here. */
function rowClasses(p: SessionCardProps): string {
const cls: string[] = [];
if (p.active) cls.push("is-active");
if (p.open) cls.push("is-open");
if (p.previewing) cls.push("is-previewing");
if (p.highlighted) cls.push("is-highlighted");
return cls.join(" ");
/** The fill ladder from docs/SIDEBAR.md "Which row is filled", furthest down
* wins. Written as one ordered run so the precedence is the order it reads in. */
function rowFill(p: SessionCardProps): string {
if (p.active) return "bg-accent-fill";
if (p.previewing) return "bg-preview-tint";
if (p.open) return "bg-accent/[0.06]";
if (p.highlighted) return "bg-preview-tint";
return "";
}
export function SessionCard(props: SessionCardProps) {
@@ -65,7 +62,7 @@ export function SessionCard(props: SessionCardProps) {
return (
<a
className={`session-card tree-leaf no-underline ${rowClasses(props)} ${
className={`session-card tree-leaf no-underline ${rowFill(props)} ${
running ? "" : "opacity-60"
}`}
href={`#/attach/${encodeURIComponent(s.id)}`}
+1 -1
View File
@@ -1623,7 +1623,7 @@ input.leaf-rename:focus {
top: 0;
bottom: 0;
left: 0;
width: 5px;
width: 7px;
background: currentColor;
}