Typography round 2 (owner): lh-input (caret at the font-metric floor) + 14px session titles

- lh-input: lh-prose's 1.5 reading leading made typing carets tower
  (~25px box on 16.5px text, ~2.1× the glyphs — the caret fills the line
  box in Chromium). Inputs are not paragraphs: 1.25 leading drops the
  caret to ~21px, the font-metric floor (as close to the glyphs as
  Chromium will draw). Swapped on every typing surface — composer
  (chat + home), the thinking field, answer + editable-Other inputs, the
  model search; rendered prose (message.tsx container, option
  descriptions, chat.tsx pre-wrap) keeps lh-prose 1.5. Same family and
  size as prose; only leading differs.
- Session titles: 14px (text-base) — Source Sans at 12.5px read as
  small as the 11px mono meta under them; the title now holds its rank.
  Live: title "Source Sans 3" 14px vs meta "JetBrains Mono" 11px, row
  52px; composer line box 20.625px (was 24.75px).

Gates: typecheck, lint, 469/469.
This commit is contained in:
amosblomqvist
2026-09-17 13:15:35 +03:00
parent 1b7dbe2898
commit 5e6d5f124c
6 changed files with 20 additions and 7 deletions
+1 -1
View File
@@ -59,7 +59,7 @@ export function Composer({
placeholder="Ask, answer, or steer the lesson…"
autoFocus={autoFocus}
rows={1}
className="field-sizing-content lh-prose max-h-48 min-h-10 flex-1 resize-none bg-transparent px-2.5 py-2 outline-none placeholder:text-muted-foreground"
className="field-sizing-content lh-input max-h-48 min-h-10 flex-1 resize-none bg-transparent px-2.5 py-2 outline-none placeholder:text-muted-foreground"
/>
{verdict && !busy ? (
// The plan verdict (docs/probe-teach-split.md §4): accept
+1 -1
View File
@@ -91,7 +91,7 @@ export function Home() {
placeholder="What do you want to learn?"
autoFocus
rows={1}
className="field-sizing-content lh-prose max-h-48 min-h-10 flex-1 resize-none bg-transparent px-2.5 py-2 outline-none placeholder:text-muted-foreground"
className="field-sizing-content lh-input max-h-48 min-h-10 flex-1 resize-none bg-transparent px-2.5 py-2 outline-none placeholder:text-muted-foreground"
/>
<button
type="submit"
+1 -1
View File
@@ -222,7 +222,7 @@ export function ModelControl({
value={query}
onChange={(e) => setQuery(e.target.value)}
placeholder="Search models…"
className="lh-prose mb-1.5 w-full rounded-lg border bg-background px-2 py-1.5 text-foreground outline-none focus:ring-1 focus:ring-ring"
className="lh-input mb-1.5 w-full rounded-lg border bg-background px-2 py-1.5 text-foreground outline-none focus:ring-1 focus:ring-ring"
/>
{error && <div className="mb-1.5 text-destructive">{error}</div>}
{!catalog && (
+3 -3
View File
@@ -387,7 +387,7 @@ function QuestionDockForm({
setSel((prev) => (prev.otherSelected ? prev : toggleOther(selectMode, prev)));
}}
placeholder="Type your own answer…"
className="lh-prose w-full min-w-0 flex-1 bg-transparent outline-none placeholder:text-muted-foreground"
className="lh-input w-full min-w-0 flex-1 bg-transparent outline-none placeholder:text-muted-foreground"
onClick={(e) => e.stopPropagation()}
/>
</div>
@@ -429,7 +429,7 @@ function QuestionDockForm({
}}
placeholder="Type your answer…"
rows={1}
className="field-sizing-content lh-prose max-h-48 min-h-10 w-full resize-none bg-transparent px-2.5 py-2 outline-none placeholder:text-muted-foreground"
className="field-sizing-content lh-input max-h-48 min-h-10 w-full resize-none bg-transparent px-2.5 py-2 outline-none placeholder:text-muted-foreground"
/>
) : (
<textarea
@@ -446,7 +446,7 @@ function QuestionDockForm({
placeholder="Why this answer? What are you unsure about? Say as much as you like — the teacher reads all of this."
rows={1}
className={cn(
"field-sizing-content lh-prose max-h-48 w-full resize-none bg-transparent px-2.5 py-2 outline-none placeholder:text-muted-foreground/70",
"field-sizing-content lh-input max-h-48 w-full resize-none bg-transparent px-2.5 py-2 outline-none placeholder:text-muted-foreground/70",
// Phase-scaled prominence: teaching invites depth,
// probing stays quick.
phase === "teach" ? "min-h-[4.5rem]" : "min-h-10",
+1 -1
View File
@@ -138,7 +138,7 @@ export function SessionRow({
the meta line below stays JetBrains Mono (machine data). One
rule, finally applied to the picker too (owner, typography
round): mono = chrome, Source Sans = human words. */}
<span className="block truncate font-prose">{chat.title}</span>
<span className="block truncate font-prose text-base">{chat.title}</span>
<span className="block text-xs text-muted-foreground">{sessionMeta(chat)}</span>
</span>
</button>