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:
@@ -164,6 +164,19 @@ body {
|
|||||||
color: var(--lh-ink-italic);
|
color: var(--lh-ink-italic);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* lh-input (owner, typography round 2): lh-prose's 1.5 READING leading
|
||||||
|
makes typing carets tower over the glyphs — the caret fills the line
|
||||||
|
box (24.75px at 16.5px text, ~2.1× the glyph height). Inputs are not
|
||||||
|
paragraphs: a tighter 1.25 leading brings the caret to the font-metric
|
||||||
|
floor (~21px, as close to the glyphs as Chromium will draw it) while
|
||||||
|
wrapped lines in growing textareas still read fine. Rendered prose keeps
|
||||||
|
1.5 — the two share family and size, they differ only in leading. */
|
||||||
|
.lh-input {
|
||||||
|
font-family: var(--font-prose);
|
||||||
|
font-size: var(--lh-prose-size);
|
||||||
|
line-height: 1.25;
|
||||||
|
}
|
||||||
|
|
||||||
/* Thin dark native scrollbar (app-wide): dark thumb, transparent track. */
|
/* Thin dark native scrollbar (app-wide): dark thumb, transparent track. */
|
||||||
* {
|
* {
|
||||||
scrollbar-width: thin;
|
scrollbar-width: thin;
|
||||||
|
|||||||
@@ -59,7 +59,7 @@ export function Composer({
|
|||||||
placeholder="Ask, answer, or steer the lesson…"
|
placeholder="Ask, answer, or steer the lesson…"
|
||||||
autoFocus={autoFocus}
|
autoFocus={autoFocus}
|
||||||
rows={1}
|
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 ? (
|
{verdict && !busy ? (
|
||||||
// The plan verdict (docs/probe-teach-split.md §4): accept
|
// The plan verdict (docs/probe-teach-split.md §4): accept
|
||||||
|
|||||||
+1
-1
@@ -91,7 +91,7 @@ export function Home() {
|
|||||||
placeholder="What do you want to learn?"
|
placeholder="What do you want to learn?"
|
||||||
autoFocus
|
autoFocus
|
||||||
rows={1}
|
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
|
<button
|
||||||
type="submit"
|
type="submit"
|
||||||
|
|||||||
@@ -222,7 +222,7 @@ export function ModelControl({
|
|||||||
value={query}
|
value={query}
|
||||||
onChange={(e) => setQuery(e.target.value)}
|
onChange={(e) => setQuery(e.target.value)}
|
||||||
placeholder="Search models…"
|
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>}
|
{error && <div className="mb-1.5 text-destructive">{error}</div>}
|
||||||
{!catalog && (
|
{!catalog && (
|
||||||
|
|||||||
@@ -387,7 +387,7 @@ function QuestionDockForm({
|
|||||||
setSel((prev) => (prev.otherSelected ? prev : toggleOther(selectMode, prev)));
|
setSel((prev) => (prev.otherSelected ? prev : toggleOther(selectMode, prev)));
|
||||||
}}
|
}}
|
||||||
placeholder="Type your own answer…"
|
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()}
|
onClick={(e) => e.stopPropagation()}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
@@ -429,7 +429,7 @@ function QuestionDockForm({
|
|||||||
}}
|
}}
|
||||||
placeholder="Type your answer…"
|
placeholder="Type your answer…"
|
||||||
rows={1}
|
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
|
<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."
|
placeholder="Why this answer? What are you unsure about? Say as much as you like — the teacher reads all of this."
|
||||||
rows={1}
|
rows={1}
|
||||||
className={cn(
|
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,
|
// Phase-scaled prominence: teaching invites depth,
|
||||||
// probing stays quick.
|
// probing stays quick.
|
||||||
phase === "teach" ? "min-h-[4.5rem]" : "min-h-10",
|
phase === "teach" ? "min-h-[4.5rem]" : "min-h-10",
|
||||||
|
|||||||
@@ -138,7 +138,7 @@ export function SessionRow({
|
|||||||
the meta line below stays JetBrains Mono (machine data). One
|
the meta line below stays JetBrains Mono (machine data). One
|
||||||
rule, finally applied to the picker too (owner, typography
|
rule, finally applied to the picker too (owner, typography
|
||||||
round): mono = chrome, Source Sans = human words. */}
|
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 className="block text-xs text-muted-foreground">{sessionMeta(chat)}</span>
|
||||||
</span>
|
</span>
|
||||||
</button>
|
</button>
|
||||||
|
|||||||
Reference in New Issue
Block a user