diff --git a/components/new-session.tsx b/components/new-session.tsx
index fdeb468..a7b19d0 100644
--- a/components/new-session.tsx
+++ b/components/new-session.tsx
@@ -5,7 +5,7 @@ import { useRouter } from "next/navigation";
import { Conversation, ConversationContent, ConversationEmptyState } from "@/components/ai-elements/conversation";
import { Composer } from "@/components/composer";
import { DictationBar, joinDictation, useDictation } from "@/components/dictation";
-import { TopBar } from "@/components/top-bar";
+import { SidebarToggle } from "@/components/sidebar";
import { SetupDialog } from "@/components/setup-dialog";
import { useStrongKeyless, useZeroKeys, ZeroKeysPill } from "@/components/setup-cta";
import { StatsBar } from "@/components/stats-bar";
@@ -144,17 +144,19 @@ export function DraftShell({
}
}, [dictation.active]);
return (
-
+ /* CHROME-LESS CREATION SURFACE (owner round 11, 2026-10-05): the
+ * drafts join home's register — no TopBar, no title (the serif title
+ * always names a session; a draft has none). Home's proven pattern
+ * verbatim: a drag mask first in the DOM, a floating reopen toggle
+ * (the only pointer-events-auto spot), the empty state carrying the
+ * orientation. The chain picker then owns the column top exactly
+ * like the graph view's — no stacked bars. */
+
+ {/* Window-drag strip — deliberately FIRST in the DOM (the mask
+ law: no-drag subtraction resolves by DOM order, so every
+ carved control later in the tree subtracts correctly). */}
+
- {/* The shared top bar (standardization ruling, 2026-09-29): one
- element, every surface — h-15, drag, sidebar reopen, lights
- gutter. h-15 (60px) matches the sidebar's wordmark band. */}
-
-
- {mode === "practice" ? "New practice session" : "New session"}
-
-
-
{/* The pointer-events pattern (953b22b): the sticky wrapper is
pointer-events-none so nothing here blocks the empty-state
@@ -237,6 +239,14 @@ export function DraftShell({
{overlay}
+ {/* The floating reopen toggle — pointer-events-none except the
+ toggle itself (home's pattern), painted AFTER the overlay's
+ column so nothing of it blocks the canvas area. */}
+
);
}
diff --git a/components/top-bar.tsx b/components/top-bar.tsx
index 7ac13ed..ec4a18b 100644
--- a/components/top-bar.tsx
+++ b/components/top-bar.tsx
@@ -23,7 +23,10 @@
* - border-b border-border px-3, gap-3 rhythm.
*
* The consumer brings the title (font-title text-3xl tracking-tight) and
- * any right-side controls. `drag={false}` is the one escape hatch —
+ * any right-side controls. THE TITLE LAW (owner round 11, 2026-10-05):
+ * the serif title ALWAYS names a session — chrome-less creation surfaces
+ * (home, both /chat/new drafts) and the chain table render NO title.
+ * `drag={false}` is the one escape hatch —
* chat's rename mode (app-region:drag would eat the mousedown that
* exits the input; owner ask).
*
diff --git a/tests/render-chain-table.test.tsx b/tests/render-chain-table.test.tsx
index c1ec76e..60ad1aa 100644
--- a/tests/render-chain-table.test.tsx
+++ b/tests/render-chain-table.test.tsx
@@ -125,12 +125,13 @@ describe("ChainTableBody — clusters (the outermost layer)", () => {
});
describe("ChainTableBody — THE shared TopBar + the lines law (owner, round 2)", () => {
- it("the body renders the standardized top bar: h-15, lh-drag, select-none, standard title size, close X", () => {
+ it("the body renders the standardized top bar: h-15, lh-drag, select-none, NO title (serif = session name, always), close X", () => {
const html = render();
assert.ok(html.includes("lh-drag"), "the window-drag band");
- assert.ok(html.includes("select-none"), "dragging never highlights the title");
+ assert.ok(html.includes("select-none"), "dragging never highlights the bar");
assert.ok(html.includes("h-15"), "the standard height");
- assert.ok(html.includes('font-title text-3xl tracking-tight">Chains<'), "the standard title size");
+ assert.ok(!html.includes(">Chains<"), "NO title (owner round 11): the serif register always names a session");
+ assert.ok(html.includes("chain"), "the counts remain");
assert.ok(html.includes('data-testid="chain-table-close"'), "the close X");
assert.ok(html.includes('data-testid="chain-table-search"'), "the search input");
});