feat(icon): Phosphor glyph card — hero + real-UI-size strip (T-313)

The icon card renders each glyph at a hero size plus a continuous sample
strip (10–48px) so legibility is judged at the sizes the app uses, with the
entry's optional label + description and a per-entry or card-level color.
Wired end to end: icon.show publishes on the `icon` bus, the Claude
extension injects an IconMessage, and conversation_view paints the card
(display-only, D-78). en+nl catalogs.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-06-29 13:10:53 +02:00
co-authored by Claude Opus 4.8
parent 9a2b4e9eca
commit 281fb2a869
10 changed files with 205 additions and 1 deletions
@@ -232,6 +232,31 @@ final class DrawingMessage extends ConversationItem {
String toString() => 'DrawingMessage(${label ?? '<svg>'})';
}
/// One glyph entry on an [IconMessage] (T-313): a resolved Phosphor [codepoint]
/// (its [name] kept for copy/debug), with optional per-entry [label],
/// [description], and [color] (hex or CSS name, parsed at render).
final class IconEntry {
const IconEntry({required this.codepoint, required this.name, this.label, this.description, this.color});
final int codepoint;
final String name;
final String? label, description, color;
}
/// A locally-injected Phosphor glyph card (T-313). Driven by `clide icon show`
/// (D-6 parity), display-only per D-78. Renders each [entries] glyph at a hero
/// size plus a sample strip of real UI sizes, with its optional label +
/// description; [color] is the card-level default glyph color.
final class IconMessage extends ConversationItem {
const IconMessage({required super.uuid, required super.timestamp, required super.isSidechain, required this.entries, this.color});
final List<IconEntry> entries;
final String? color;
@override
String toString() => 'IconMessage(${entries.length} glyph${entries.length == 1 ? '' : 's'})';
}
// ---------------------------------------------------------------------------
// Internal helpers
// ---------------------------------------------------------------------------