diff --git a/frontend/src/lib/components/NavBreadcrumb.svelte b/frontend/src/lib/components/NavBreadcrumb.svelte
index 0ea6cd92f3..5bcfd4db24 100644
--- a/frontend/src/lib/components/NavBreadcrumb.svelte
+++ b/frontend/src/lib/components/NavBreadcrumb.svelte
@@ -34,7 +34,8 @@ same weight, size and icon size, so the line reads as one control rather than fo
section,
afterName,
actingWorkspaceId,
- narrow = false
+ narrow = false,
+ nameOnly = false
}: {
item?: PageHeaderItem
section?: PageHeaderSection
@@ -45,6 +46,10 @@ same weight, size and icon size, so the line reads as one control rather than fo
actingWorkspaceId?: string
/** The bar is short of room: the workspace part drops its names and keeps its marks. */
narrow?: boolean
+ /** Only the page's own name, with no workspace part and no picker — the band inside a
+ * session's preview frame, where the workspace is the host's and leading the reader out of
+ * it is exactly what that band must not offer. The page still has to say what it is. */
+ nameOnly?: boolean
} = $props()
const scopeId = $derived(actingWorkspaceId ?? $workspaceStore ?? undefined)
@@ -185,79 +190,81 @@ same weight, size and icon size, so the line reads as one control rather than fo
aria-label="Breadcrumb"
class="flex items-center gap-1.5 min-w-0 text-xs font-normal text-primary"
>
-
-
-
- {#snippet children({ createMenu })}
-
- {/snippet}
-
-
+ {/if}
- {#if item || section || routePage}
+ {#if !nameOnly && (item || section || routePage)}
{@render slash()}
{/if}
diff --git a/frontend/src/lib/components/PageHeaderBar.svelte b/frontend/src/lib/components/PageHeaderBar.svelte
index ca2927712a..eb9336dfa9 100644
--- a/frontend/src/lib/components/PageHeaderBar.svelte
+++ b/frontend/src/lib/components/PageHeaderBar.svelte
@@ -87,6 +87,10 @@ The row's height matches the sidebar's own header row, so the two read as one ba
class={twMerge(
'flex items-center gap-1 shrink-0 min-w-0 bg-surface transition-shadow duration-150',
phone ? 'flex-wrap content-center min-h-11 py-1 pl-1 pr-2' : 'h-11 pl-2 pr-4',
+ // The small left padding is there to sit a button against: the sidebar handle, or the
+ // workspace disc, both of which carry their own visual margin. Embedded there is neither,
+ // and the page's name would start as bare text 8px from the edge.
+ navHidden && 'pl-4',
showEdge &&
'shadow-[inset_0_-1px_0_0_rgb(var(--color-border-light))] dark:shadow-[inset_0_-1px_0_0_#374151] [html.github-dark_&]:shadow-[inset_0_-1px_0_0_rgb(var(--color-border-light))]'
)}
@@ -121,28 +125,28 @@ The row's height matches the sidebar's own header row, so the two read as one ba
On a phone it stops yielding at 10rem, and that floor is what makes the bar wrap: the
page's buttons no longer fit beside a trail that wide, so they take the line below
instead of squeezing the name down to an ellipsis.
- An embed (`navHidden`) gets the page's controls without the trail that would offer to
- navigate the host's workspace. -->
- {#if !navHidden}
-
-
- {#key content?.contexts}
-
-
-
- {/key}
-
- {/if}
+ An embed (`navHidden`) keeps the page's own name but drops the workspace part around it:
+ the trail would offer to navigate the host's workspace, while the name is what says which
+ page the controls beside it belong to. -->
+