+
+
+ );
+}
+
+// Tailwind v4 preflight resets headings/lists; the structural typography
+// (headings, lists, markers, counters, checkboxes, callouts) lives in
+// prose.css as one `.chat-prose` system. The component map below only covers
+// behavioral overrides: link attrs, callout swap-in, inline code / fenced
+// blocks, and the chat table.
const COMPONENTS = {
- h1: ({ children }) => {children}
+ {children}
, - h2: ({ children }) =>{children}
, - h3: ({ children }) =>{children}
, - p: ({ children }) =>{children}
, - ul: ({ children }) =>- {children}
- {children}
{children}; + }, table: ({ children }) => (
- {children}
+
+ {children}
+
),
- thead: ({ children }) => {children},
- tbody: ({ children }) => {children},
+ thead: ({ children }) => {children},
+ tbody: ({ children }) => {children},
tr: ({ children }) =>
+
{String(source || "")}
diff --git a/viewer/src/client/components/chat/PlanBlock.jsx b/viewer/src/client/components/chat/PlanBlock.jsx
index e6ea370..006a326 100644
--- a/viewer/src/client/components/chat/PlanBlock.jsx
+++ b/viewer/src/client/components/chat/PlanBlock.jsx
@@ -1,5 +1,5 @@
import { useState } from "react";
-import { ClipboardList, Pencil, MessageSquare } from "lucide-react";
+import { ClipboardList, Check } from "lucide-react";
import { Button } from "@/components/ui/button";
import { Textarea } from "@/components/ui/textarea";
import { cn } from "@/ui/utils";
@@ -12,6 +12,21 @@ const STATUS_PILL = {
superseded: { label: "Superseded", cls: "border-white/10 bg-white/5 text-zinc-400" },
};
+// Plan-body markdown styling. The plan content drives the layout: `###`
+// headings become the small uppercase section labels ("What I'll make",
+// "Build steps"), inline `code` becomes the dimension chips, and the ordered
+// list is rendered as numbered badge steps via CSS counters.
+const PLAN_MD = cn(
+ "text-[13.5px] leading-relaxed text-zinc-300",
+ "[&_strong]:font-semibold [&_strong]:text-white",
+ "[&_h3]:mt-5 [&_h3]:mb-2.5 [&_h3]:text-[11px] [&_h3]:font-semibold [&_h3]:uppercase [&_h3]:tracking-[0.09em] [&_h3]:text-zinc-500 [&_h3:first-child]:mt-0",
+ "[&_p]:my-0 [&_p]:text-[13.5px] [&_p]:leading-relaxed [&_p]:text-zinc-300",
+ "[&_code]:rounded-md [&_code]:bg-white/[0.04] [&_code]:px-1.5 [&_code]:py-0.5 [&_code]:font-mono [&_code]:text-[12px] [&_code]:text-zinc-300",
+ "[&_ol]:mt-2.5 [&_ol]:mb-0 [&_ol]:flex [&_ol]:list-none [&_ol]:flex-col [&_ol]:gap-2.5 [&_ol]:pl-0 [&_ol]:[counter-reset:step]",
+ "[&_ol>li]:m-0 [&_ol>li]:flex [&_ol>li]:items-start [&_ol>li]:gap-3 [&_ol>li]:[counter-increment:step]",
+ "[&_ol>li]:before:[content:counter(step)] [&_ol>li]:before:mt-px [&_ol>li]:before:flex [&_ol>li]:before:size-5 [&_ol>li]:before:shrink-0 [&_ol>li]:before:items-center [&_ol>li]:before:justify-center [&_ol>li]:before:rounded-md [&_ol>li]:before:bg-white/[0.04] [&_ol>li]:before:text-[11px] [&_ol>li]:before:font-semibold [&_ol>li]:before:leading-none [&_ol>li]:before:text-zinc-400",
+);
+
/**
* Inline plan-review card. Renders the proposed plan as markdown with
* edit / approve / request-changes controls. Modeled on PreflightModal's
@@ -45,90 +60,76 @@ export default function PlanBlock({ plan, status }) {
data-slot="chat-plan"
data-status={status}
className={cn(
- "rounded-xl border border-border/70 bg-[#202124] p-3 text-sm text-zinc-100 shadow-(--ui-shadow-soft)",
- !isProposed && "bg-card/70",
+ "overflow-hidden rounded-2xl border border-white/[0.08] bg-[#16181c] text-sm text-zinc-100",
+ "bg-[linear-gradient(to_bottom,rgba(52,211,153,0.1)_0,rgba(52,211,153,0.1)_46px,rgba(52,211,153,0)_64px)]",
status === "superseded" && "opacity-60",
)}
>
-