2026-10-05 02:25:13 +03:00
|
|
|
"use client";
|
|
|
|
|
|
2026-10-05 03:41:39 +03:00
|
|
|
import { useState } from "react";
|
|
|
|
|
import { ChevronDownIcon } from "lucide-react";
|
2026-10-05 02:25:13 +03:00
|
|
|
import { cn } from "@/lib/utils";
|
|
|
|
|
|
2026-10-05 03:41:39 +03:00
|
|
|
/** The unified user-thinking row (owner round, 2026-10-05): ONE visual
|
2026-10-05 02:25:13 +03:00
|
|
|
* language for every surface where the learner's own thinking renders —
|
2026-10-05 03:41:39 +03:00
|
|
|
* practice thinking traces, the reading channel lifted above the answered
|
|
|
|
|
* card, the quiz answer's thinking inside its container. It arrives
|
|
|
|
|
* COLLAPSED as a trigger row in the exact register of the agent's
|
|
|
|
|
* reasoning rows (muted label + chevron + hover affordance); expanding
|
|
|
|
|
* opens the quote block — rail, 50% opacity, italics. The italics + the
|
|
|
|
|
* half-opacity text are the inner-voice signature; the rail marks it as
|
|
|
|
|
* learner material. No shell, no border: document material, full width.
|
2026-10-05 02:25:13 +03:00
|
|
|
*
|
2026-10-05 03:41:39 +03:00
|
|
|
* The glance-level law (owner): user thinking = rail + 50% italic;
|
|
|
|
|
* agent thinking = no rail. */
|
2026-10-05 02:25:13 +03:00
|
|
|
|
|
|
|
|
export function ThinkingBlock({
|
2026-10-05 04:14:21 +03:00
|
|
|
label = "YOUR THINKING",
|
2026-10-05 02:25:13 +03:00
|
|
|
text,
|
|
|
|
|
testId,
|
|
|
|
|
dataCommit,
|
|
|
|
|
}: {
|
2026-10-05 03:41:39 +03:00
|
|
|
label?: string;
|
2026-10-05 02:25:13 +03:00
|
|
|
text: string;
|
|
|
|
|
testId?: string;
|
|
|
|
|
/** The practice marker's register flag (commit vs nudge). */
|
|
|
|
|
dataCommit?: boolean;
|
|
|
|
|
}) {
|
2026-10-05 03:41:39 +03:00
|
|
|
const [open, setOpen] = useState(false); // arrives collapsed, always
|
2026-10-05 02:25:13 +03:00
|
|
|
return (
|
2026-10-05 03:57:35 +03:00
|
|
|
/* The rail GROUPS (owner correction, 2026-10-05): the label sits
|
|
|
|
|
INSIDE the rail — the block reads as one quote, ownership clear
|
|
|
|
|
from the rail alone, collapsed or expanded. Same shape as the
|
|
|
|
|
user text ("You") row. */
|
|
|
|
|
<div
|
|
|
|
|
data-testid={testId}
|
|
|
|
|
data-commit={dataCommit === undefined ? undefined : dataCommit ? "true" : "false"}
|
|
|
|
|
className="lh-card-enter my-1 w-full border-l-2 border-muted-foreground/30 pl-3"
|
|
|
|
|
>
|
2026-10-05 03:41:39 +03:00
|
|
|
<button
|
|
|
|
|
type="button"
|
|
|
|
|
data-testid={testId ? `${testId}-trigger` : undefined}
|
|
|
|
|
onClick={() => setOpen((v) => !v)}
|
|
|
|
|
aria-expanded={open}
|
|
|
|
|
className="flex w-full items-center gap-2 text-muted-foreground text-sm transition-colors hover:text-foreground"
|
|
|
|
|
>
|
|
|
|
|
{label}
|
|
|
|
|
<ChevronDownIcon className={cn("size-4 transition-transform", open ? "rotate-180" : "rotate-0")} />
|
|
|
|
|
</button>
|
|
|
|
|
{open && (
|
2026-10-05 03:57:35 +03:00
|
|
|
<span className="lh-prose mt-1.5 block whitespace-pre-wrap italic text-foreground/50">{text}</span>
|
2026-10-05 03:41:39 +03:00
|
|
|
)}
|
2026-10-05 02:25:13 +03:00
|
|
|
</div>
|
|
|
|
|
);
|
|
|
|
|
}
|