refactor(settings): ClideSettings — one live-preferences facade (D-101)
Introduce ClideSettings, a single widget-facing facade for the app's live user preferences, namespaced by concern: ClideSettings.fonts.monoOf(context) / .fonts.uiOf(context), ClideSettings.theme.of(context), ClideSettings.i18n.of(context). "Plumb once, use many." Fonts are carried by a new root-provided ClideSettingsScope (resolved from the font settings in root_shell, rebuilt on change); theme and i18n delegate to their existing live providers (ClideTheme / the I18n service) so there's one source of truth and their many consumers migrate incrementally rather than in a big-bang. Reads outside a scope fall back to the bundled font defaults, so a widget renders without a provider (isolated tests). Migrate ~93 monospace-font call sites across 33 files from the clideMonoFamily const to ClideSettings.fonts.monoOf(context) — pure refactor, identical family when no override is set. 11 context-less helper sites (markdown static spans, a few top-level/static builders) keep the const for now and are tracked in T-472. Records D-101; updates the ui-design skill's font-family rule. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -37,10 +37,13 @@ class ClaudeBanner extends StatelessWidget {
|
||||
const SizedBox(height: 18),
|
||||
ClideText('Claude', fontSize: clideFontDialogTitle, color: claudeAccent, fontWeight: FontWeight.w500),
|
||||
const SizedBox(height: 2),
|
||||
ClideText(role, fontSize: clideFontSmall, muted: true, fontFamily: clideMonoFamily),
|
||||
ClideText(role, fontSize: clideFontSmall, muted: true, fontFamily: ClideSettings.fonts.monoOf(context)),
|
||||
const SizedBox(height: 16),
|
||||
if (ws != null) ClideText(ws, fontSize: clideFontCaption, muted: true),
|
||||
if (statusLine != null) ...[const SizedBox(height: 2), ClideText(statusLine!, fontSize: clideFontSmall, muted: true, fontFamily: clideMonoFamily)],
|
||||
if (statusLine != null) ...[
|
||||
const SizedBox(height: 2),
|
||||
ClideText(statusLine!, fontSize: clideFontSmall, muted: true, fontFamily: ClideSettings.fonts.monoOf(context)),
|
||||
],
|
||||
const SizedBox(height: 16),
|
||||
const ClideText('Warming up — your conversation will appear here.', fontSize: clideFontSmall, muted: true),
|
||||
],
|
||||
|
||||
@@ -132,12 +132,13 @@ class _ClaudePaneState extends State<ClaudePane> {
|
||||
final seg = statusSegmentsAroundMode(_status);
|
||||
final mode = _status.permissionMode;
|
||||
|
||||
Widget text(String t) => ClideText(t, fontSize: clideFontSmall, fontFamily: clideMonoFamily, color: tokens.statusBarForeground, maxLines: 1);
|
||||
Widget text(String t) =>
|
||||
ClideText(t, fontSize: clideFontSmall, fontFamily: ClideSettings.fonts.monoOf(context), color: tokens.statusBarForeground, maxLines: 1);
|
||||
|
||||
final children = <Widget>[];
|
||||
void add(Widget w) {
|
||||
if (children.isNotEmpty) {
|
||||
children.add(ClideText(' · ', fontSize: clideFontSmall, fontFamily: clideMonoFamily, color: tokens.globalTextMuted, maxLines: 1));
|
||||
children.add(ClideText(' · ', fontSize: clideFontSmall, fontFamily: ClideSettings.fonts.monoOf(context), color: tokens.globalTextMuted, maxLines: 1));
|
||||
}
|
||||
children.add(w);
|
||||
}
|
||||
@@ -857,7 +858,13 @@ class _ModeBadge extends StatelessWidget {
|
||||
return Semantics(
|
||||
label: 'permission mode: ${permissionModeLabel(mode)}',
|
||||
excludeSemantics: true,
|
||||
child: ClideText(permissionModeLabel(mode), fontSize: clideFontSmall, fontFamily: clideMonoFamily, color: permissionModeColor(mode, tokens), maxLines: 1),
|
||||
child: ClideText(
|
||||
permissionModeLabel(mode),
|
||||
fontSize: clideFontSmall,
|
||||
fontFamily: ClideSettings.fonts.monoOf(context),
|
||||
color: permissionModeColor(mode, tokens),
|
||||
maxLines: 1,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -241,13 +241,13 @@ class _ConversationCardState extends State<ConversationCard> {
|
||||
if (widget.collapsible) _caret(tokens),
|
||||
// Header label size matches ClideCollapserCard (clideFontCaption) so
|
||||
// neighbouring cards in the conversation stream align (T-344).
|
||||
ClideText(widget.label, fontSize: clideFontCaption, color: widget.accent, fontFamily: clideMonoFamily),
|
||||
ClideText(widget.label, fontSize: clideFontCaption, color: widget.accent, fontFamily: ClideSettings.fonts.monoOf(context)),
|
||||
// While collapsed, show a one-line gist next to the label so the card
|
||||
// still says what it holds.
|
||||
if (_collapsed && summary != null) ...[
|
||||
const SizedBox(width: 10),
|
||||
Expanded(
|
||||
child: ClideText(summary, fontSize: clideFontMeta, color: tokens.globalTextMuted, fontFamily: clideMonoFamily, maxLines: 1),
|
||||
child: ClideText(summary, fontSize: clideFontMeta, color: tokens.globalTextMuted, fontFamily: ClideSettings.fonts.monoOf(context), maxLines: 1),
|
||||
),
|
||||
] else
|
||||
const Spacer(),
|
||||
@@ -322,7 +322,7 @@ class _ConversationCardState extends State<ConversationCard> {
|
||||
padding: const EdgeInsets.only(top: 8, bottom: 4),
|
||||
child: Row(
|
||||
children: [
|
||||
ClideText(label, fontSize: clideFontMeta, color: tokens.globalTextMuted, fontFamily: clideMonoFamily),
|
||||
ClideText(label, fontSize: clideFontMeta, color: tokens.globalTextMuted, fontFamily: ClideSettings.fonts.monoOf(context)),
|
||||
const SizedBox(width: 8),
|
||||
Expanded(child: Container(height: 1, color: tokens.panelBorder)),
|
||||
],
|
||||
@@ -349,7 +349,7 @@ class _ConversationCardState extends State<ConversationCard> {
|
||||
onTap: items[i].onTap,
|
||||
builder: (_, hovered, pressed) => Padding(
|
||||
padding: const EdgeInsets.only(left: 10),
|
||||
child: ClideText(items[i].label, fontSize: clideFontMeta, color: tokens.globalTextMuted, fontFamily: clideMonoFamily),
|
||||
child: ClideText(items[i].label, fontSize: clideFontMeta, color: tokens.globalTextMuted, fontFamily: ClideSettings.fonts.monoOf(context)),
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
@@ -147,9 +147,14 @@ class _ModelPickerCardState extends State<ModelPickerCard> {
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
ClideText(widget.title, fontSize: clideFontSmall, fontFamily: clideMonoFamily, color: tokens.statusInfo),
|
||||
ClideText(widget.title, fontSize: clideFontSmall, fontFamily: ClideSettings.fonts.monoOf(context), color: tokens.statusInfo),
|
||||
const Spacer(),
|
||||
ClideText('↑↓ · 1-${widget.models.length} · Enter · Esc', fontSize: clideFontMeta, fontFamily: clideMonoFamily, color: tokens.globalTextMuted),
|
||||
ClideText(
|
||||
'↑↓ · 1-${widget.models.length} · Enter · Esc',
|
||||
fontSize: clideFontMeta,
|
||||
fontFamily: ClideSettings.fonts.monoOf(context),
|
||||
color: tokens.globalTextMuted,
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
|
||||
@@ -122,7 +122,7 @@ class _ToolPromptCardState extends State<ToolPromptCard> {
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
ClideText(label, fontSize: clideFontSmall, fontFamily: clideMonoFamily, color: accent),
|
||||
ClideText(label, fontSize: clideFontSmall, fontFamily: ClideSettings.fonts.monoOf(context), color: accent),
|
||||
const SizedBox(height: 8),
|
||||
...children,
|
||||
],
|
||||
@@ -362,14 +362,21 @@ class _ToolPromptCardState extends State<ToolPromptCard> {
|
||||
border: Border.all(color: tokens.statusInfo),
|
||||
borderRadius: BorderRadius.circular(4),
|
||||
),
|
||||
child: ClideText(text, fontSize: clideFontMeta, fontFamily: clideMonoFamily, color: tokens.globalForeground),
|
||||
child: ClideText(text, fontSize: clideFontMeta, fontFamily: ClideSettings.fonts.monoOf(context), color: tokens.globalForeground),
|
||||
),
|
||||
);
|
||||
} else {
|
||||
chips.add(ClideText(text, fontSize: clideFontMeta, fontFamily: clideMonoFamily, color: done ? tokens.statusSuccess : tokens.globalTextMuted));
|
||||
chips.add(
|
||||
ClideText(
|
||||
text,
|
||||
fontSize: clideFontMeta,
|
||||
fontFamily: ClideSettings.fonts.monoOf(context),
|
||||
color: done ? tokens.statusSuccess : tokens.globalTextMuted,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
chips.add(ClideText('Review', fontSize: clideFontMeta, fontFamily: clideMonoFamily, color: tokens.globalTextMuted));
|
||||
chips.add(ClideText('Review', fontSize: clideFontMeta, fontFamily: ClideSettings.fonts.monoOf(context), color: tokens.globalTextMuted));
|
||||
chips.add(ClideText('›', color: tokens.globalTextMuted, fontSize: 15));
|
||||
return Wrap(spacing: 10, runSpacing: 6, crossAxisAlignment: WrapCrossAlignment.center, children: chips);
|
||||
}
|
||||
@@ -399,7 +406,8 @@ class _ToolPromptCardState extends State<ToolPromptCard> {
|
||||
return Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
if (q.header.isNotEmpty) ClideText(q.header.toUpperCase(), fontSize: clideFontMeta, fontFamily: clideMonoFamily, color: tokens.globalTextMuted),
|
||||
if (q.header.isNotEmpty)
|
||||
ClideText(q.header.toUpperCase(), fontSize: clideFontMeta, fontFamily: ClideSettings.fonts.monoOf(context), color: tokens.globalTextMuted),
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(top: 2, bottom: 6),
|
||||
child: ClideText(q.question, color: tokens.globalForeground),
|
||||
|
||||
@@ -178,7 +178,7 @@ class _TeammateTile extends StatelessWidget {
|
||||
children: [
|
||||
Container(width: 3, height: 13, color: accent),
|
||||
const SizedBox(width: 6),
|
||||
ClideText(member.name, fontSize: clideFontSmall, color: accent, fontFamily: clideMonoFamily),
|
||||
ClideText(member.name, fontSize: clideFontSmall, color: accent, fontFamily: ClideSettings.fonts.monoOf(context)),
|
||||
const SizedBox(width: 8),
|
||||
Expanded(
|
||||
child: ClideText(
|
||||
|
||||
@@ -148,19 +148,22 @@ class _DecisionDetailViewState extends State<DecisionDetailView> {
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 8),
|
||||
ClideText(id, fontSize: clideFontSmall, color: typeColor, fontFamily: clideMonoFamily),
|
||||
ClideText(id, fontSize: clideFontSmall, color: typeColor, fontFamily: ClideSettings.fonts.monoOf(context)),
|
||||
const Spacer(),
|
||||
if (domain != null)
|
||||
Container(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 6, vertical: 2),
|
||||
decoration: BoxDecoration(color: tokens.panelBorder, borderRadius: BorderRadius.circular(3)),
|
||||
child: ClideText(domain, fontSize: clideFontBadge, color: tokens.globalTextMuted, fontFamily: clideMonoFamily),
|
||||
child: ClideText(domain, fontSize: clideFontBadge, color: tokens.globalTextMuted, fontFamily: ClideSettings.fonts.monoOf(context)),
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
ClideText(title, fontSize: 15, fontWeight: FontWeight.w500),
|
||||
if (date != null) ...[const SizedBox(height: 6), ClideText(date, muted: true, fontSize: clideFontSmall, fontFamily: clideMonoFamily)],
|
||||
if (date != null) ...[
|
||||
const SizedBox(height: 6),
|
||||
ClideText(date, muted: true, fontSize: clideFontSmall, fontFamily: ClideSettings.fonts.monoOf(context)),
|
||||
],
|
||||
if (status != null && status != 'active') ...[const SizedBox(height: 8), _StatusBadge(status: status, tokens: tokens)],
|
||||
],
|
||||
),
|
||||
@@ -168,7 +171,7 @@ class _DecisionDetailViewState extends State<DecisionDetailView> {
|
||||
if (body != null && body.isNotEmpty) ...[const SizedBox(height: 12), ClideMarkdown(body, onRecordTap: (id) => _navigateToRecord(context, id))],
|
||||
if (refs.isNotEmpty) ...[
|
||||
const SizedBox(height: 16),
|
||||
ClideText('CROSS-REFERENCES', fontSize: clideFontSmall, color: tokens.sidebarSectionHeader, fontFamily: clideMonoFamily),
|
||||
ClideText('CROSS-REFERENCES', fontSize: clideFontSmall, color: tokens.sidebarSectionHeader, fontFamily: ClideSettings.fonts.monoOf(context)),
|
||||
const SizedBox(height: 6),
|
||||
for (final ref in refs) _RefCard(ref: ref, tokens: tokens),
|
||||
],
|
||||
@@ -201,7 +204,7 @@ class _RefCard extends StatelessWidget {
|
||||
),
|
||||
child: Row(
|
||||
children: [
|
||||
ClideText(targetId, fontSize: clideFontSmall, color: tokens.globalFocus, fontFamily: clideMonoFamily),
|
||||
ClideText(targetId, fontSize: clideFontSmall, color: tokens.globalFocus, fontFamily: ClideSettings.fonts.monoOf(context)),
|
||||
const SizedBox(width: 8),
|
||||
ClideText(refType, fontSize: clideFontSmall, color: tokens.globalTextMuted),
|
||||
],
|
||||
@@ -227,7 +230,7 @@ class _StatusBadge extends StatelessWidget {
|
||||
return Container(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 6, vertical: 2),
|
||||
decoration: BoxDecoration(color: color.withAlpha(0x30), borderRadius: BorderRadius.circular(3)),
|
||||
child: ClideText(status.toUpperCase(), fontSize: clideFontBadge, color: color, fontFamily: clideMonoFamily),
|
||||
child: ClideText(status.toUpperCase(), fontSize: clideFontBadge, color: color, fontFamily: ClideSettings.fonts.monoOf(context)),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -309,9 +309,10 @@ class _DecisionCard extends StatelessWidget {
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 6),
|
||||
ClideText(entry.id, fontSize: clideFontSmall, color: tokens.globalTextMuted, fontFamily: clideMonoFamily),
|
||||
ClideText(entry.id, fontSize: clideFontSmall, color: tokens.globalTextMuted, fontFamily: ClideSettings.fonts.monoOf(context)),
|
||||
const Spacer(),
|
||||
if (entry.domain != null) ClideText(entry.domain!, fontSize: clideFontBadge, color: tokens.globalTextMuted, fontFamily: clideMonoFamily),
|
||||
if (entry.domain != null)
|
||||
ClideText(entry.domain!, fontSize: clideFontBadge, color: tokens.globalTextMuted, fontFamily: ClideSettings.fonts.monoOf(context)),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 4),
|
||||
@@ -321,7 +322,7 @@ class _DecisionCard extends StatelessWidget {
|
||||
Container(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 6, vertical: 2),
|
||||
decoration: BoxDecoration(color: tokens.statusSuccess.withAlpha(0x30), borderRadius: BorderRadius.circular(3)),
|
||||
child: ClideText('resolved', fontSize: clideFontBadge, color: tokens.statusSuccess, fontFamily: clideMonoFamily),
|
||||
child: ClideText('resolved', fontSize: clideFontBadge, color: tokens.statusSuccess, fontFamily: ClideSettings.fonts.monoOf(context)),
|
||||
),
|
||||
],
|
||||
],
|
||||
|
||||
@@ -83,7 +83,7 @@ class _DeepLinkConfirmDialog extends StatelessWidget {
|
||||
const SizedBox(height: 6),
|
||||
ClideText('A clide:// link from outside the app is asking to:', muted: true, fontSize: clideFontSmall),
|
||||
const SizedBox(height: 8),
|
||||
ClideText(action.describe, fontFamily: clideMonoFamily, fontSize: clideFontSmall, color: t.globalForeground),
|
||||
ClideText(action.describe, fontFamily: ClideSettings.fonts.monoOf(context), fontSize: clideFontSmall, color: t.globalForeground),
|
||||
const SizedBox(height: 8),
|
||||
ClideText('Only allow this if you trust where the link came from.', fontSize: clideFontMeta, color: t.statusWarning),
|
||||
const SizedBox(height: 14),
|
||||
|
||||
@@ -250,7 +250,7 @@ class _HunkView extends StatelessWidget {
|
||||
children: [
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 2),
|
||||
child: ClideText(header, fontSize: clideFontMono, muted: true, fontFamily: clideMonoFamily),
|
||||
child: ClideText(header, fontSize: clideFontMono, muted: true, fontFamily: ClideSettings.fonts.monoOf(context)),
|
||||
),
|
||||
for (final lineObj in lines) _DiffLineRow(line: (lineObj as Map).cast<String, Object?>()),
|
||||
],
|
||||
@@ -294,7 +294,7 @@ class _DiffLineRow extends StatelessWidget {
|
||||
oldLineNo != null ? '${oldLineNo.toInt()}' : '',
|
||||
fontSize: clideFontMono,
|
||||
muted: true,
|
||||
fontFamily: clideMonoFamily,
|
||||
fontFamily: ClideSettings.fonts.monoOf(context),
|
||||
textAlign: TextAlign.right,
|
||||
),
|
||||
),
|
||||
@@ -305,15 +305,22 @@ class _DiffLineRow extends StatelessWidget {
|
||||
newLineNo != null ? '${newLineNo.toInt()}' : '',
|
||||
fontSize: clideFontMono,
|
||||
muted: true,
|
||||
fontFamily: clideMonoFamily,
|
||||
fontFamily: ClideSettings.fonts.monoOf(context),
|
||||
textAlign: TextAlign.right,
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 4),
|
||||
ClideText(prefix, fontSize: clideFontMono, color: fg, fontFamily: clideMonoFamily),
|
||||
ClideText(prefix, fontSize: clideFontMono, color: fg, fontFamily: ClideSettings.fonts.monoOf(context)),
|
||||
const SizedBox(width: 2),
|
||||
Expanded(
|
||||
child: ClideText(text, fontSize: clideFontMono, color: fg, fontFamily: clideMonoFamily, maxLines: 1, overflow: TextOverflow.clip),
|
||||
child: ClideText(
|
||||
text,
|
||||
fontSize: clideFontMono,
|
||||
color: fg,
|
||||
fontFamily: ClideSettings.fonts.monoOf(context),
|
||||
maxLines: 1,
|
||||
overflow: TextOverflow.clip,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
|
||||
@@ -371,7 +371,12 @@ class _TextBody extends StatelessWidget {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final style = TextStyle(color: foreground, fontSize: clideFontMono, fontFamily: clideMonoFamily, fontFamilyFallback: clideMonoFamilyFallback);
|
||||
final style = TextStyle(
|
||||
color: foreground,
|
||||
fontSize: clideFontMono,
|
||||
fontFamily: ClideSettings.fonts.monoOf(context),
|
||||
fontFamilyFallback: clideMonoFamilyFallback,
|
||||
);
|
||||
final editable = EditableText(
|
||||
controller: controller,
|
||||
focusNode: focus,
|
||||
|
||||
@@ -48,7 +48,7 @@ class ExtensionsNotice extends StatelessWidget {
|
||||
i.string('notice.tracked', namespace: ns, placeholder: 'Tracked in T-8 (Tier 6) · D-16'),
|
||||
color: tokens.globalTextMuted,
|
||||
fontSize: clideFontCaption,
|
||||
fontFamily: clideMonoFamily,
|
||||
fontFamily: ClideSettings.fonts.monoOf(context),
|
||||
),
|
||||
],
|
||||
);
|
||||
|
||||
@@ -164,7 +164,12 @@ class _BranchPickerState extends State<_BranchPicker> {
|
||||
child: Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child: ClideText('Switch branch', fontSize: clideFontCaption, color: tokens.globalTextMuted, fontFamily: clideMonoFamily),
|
||||
child: ClideText(
|
||||
'Switch branch',
|
||||
fontSize: clideFontCaption,
|
||||
color: tokens.globalTextMuted,
|
||||
fontFamily: ClideSettings.fonts.monoOf(context),
|
||||
),
|
||||
),
|
||||
GestureDetector(
|
||||
onTap: () => widget.onDismiss(),
|
||||
@@ -229,7 +234,7 @@ class _BranchRow extends StatelessWidget {
|
||||
Expanded(
|
||||
child: ClideText(
|
||||
name,
|
||||
fontFamily: clideMonoFamily,
|
||||
fontFamily: ClideSettings.fonts.monoOf(context),
|
||||
fontSize: clideFontMono,
|
||||
color: current ? tokens.globalForeground : tokens.listItemForeground,
|
||||
),
|
||||
|
||||
@@ -67,7 +67,7 @@ class _Kv extends StatelessWidget {
|
||||
children: [
|
||||
SizedBox(width: 90, child: ClideText(label, fontSize: 13, color: tokens.globalTextMuted)),
|
||||
Expanded(
|
||||
child: ClideText(value, fontSize: 13, fontFamily: clideMonoFamily, maxLines: 1, overflow: TextOverflow.ellipsis),
|
||||
child: ClideText(value, fontSize: 13, fontFamily: ClideSettings.fonts.monoOf(context), maxLines: 1, overflow: TextOverflow.ellipsis),
|
||||
),
|
||||
],
|
||||
),
|
||||
@@ -106,7 +106,7 @@ class _Licenses extends StatelessWidget {
|
||||
child: ClideText(
|
||||
'${d.name} ${d.version} · ${d.license}',
|
||||
fontSize: 12,
|
||||
fontFamily: clideMonoFamily,
|
||||
fontFamily: ClideSettings.fonts.monoOf(context),
|
||||
color: tokens.globalTextMuted,
|
||||
maxLines: 1,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
|
||||
@@ -137,7 +137,12 @@ class _OpenFolderDialogState extends State<OpenFolderDialog> {
|
||||
child: EditableText(
|
||||
controller: _controller,
|
||||
focusNode: _focus,
|
||||
style: TextStyle(color: tokens.globalForeground, fontSize: 14, fontFamily: clideMonoFamily, fontFamilyFallback: clideMonoFamilyFallback),
|
||||
style: TextStyle(
|
||||
color: tokens.globalForeground,
|
||||
fontSize: 14,
|
||||
fontFamily: ClideSettings.fonts.monoOf(context),
|
||||
fontFamilyFallback: clideMonoFamilyFallback,
|
||||
),
|
||||
cursorColor: tokens.globalForeground,
|
||||
backgroundCursorColor: tokens.globalTextMuted,
|
||||
onSubmitted: (_) => unawaited(_submit()),
|
||||
|
||||
@@ -162,7 +162,12 @@ class _TopMenuButtonState extends State<_TopMenuButton> {
|
||||
label: node.title,
|
||||
enabled: node.enabled,
|
||||
trailing: node.keybinding != null
|
||||
? ClideText(node.keybinding!, fontSize: clideFontSmall, fontFamily: clideMonoFamily, color: ClideTheme.of(ctx).surface.globalTextMuted)
|
||||
? ClideText(
|
||||
node.keybinding!,
|
||||
fontSize: clideFontSmall,
|
||||
fontFamily: ClideSettings.fonts.monoOf(context),
|
||||
color: ClideTheme.of(ctx).surface.globalTextMuted,
|
||||
)
|
||||
: null,
|
||||
onSelect: () => unawaited(widget.kernel.commands.execute(node.commandId)),
|
||||
)
|
||||
|
||||
@@ -217,11 +217,11 @@ class _LogRow extends StatelessWidget {
|
||||
child: Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
ClideText('$hh:$mm:$ss', fontSize: clideFontMono, color: tokens.globalTextMuted, fontFamily: clideMonoFamily),
|
||||
ClideText('$hh:$mm:$ss', fontSize: clideFontMono, color: tokens.globalTextMuted, fontFamily: ClideSettings.fonts.monoOf(context)),
|
||||
const SizedBox(width: 8),
|
||||
SizedBox(
|
||||
width: 48,
|
||||
child: ClideText(record.level.name.toUpperCase(), fontSize: clideFontMono, color: fg, fontFamily: clideMonoFamily),
|
||||
child: ClideText(record.level.name.toUpperCase(), fontSize: clideFontMono, color: fg, fontFamily: ClideSettings.fonts.monoOf(context)),
|
||||
),
|
||||
const SizedBox(width: 8),
|
||||
SizedBox(
|
||||
@@ -230,14 +230,14 @@ class _LogRow extends StatelessWidget {
|
||||
record.source,
|
||||
fontSize: clideFontMono,
|
||||
color: tokens.globalTextMuted,
|
||||
fontFamily: clideMonoFamily,
|
||||
fontFamily: ClideSettings.fonts.monoOf(context),
|
||||
maxLines: 1,
|
||||
overflow: TextOverflow.clip,
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 8),
|
||||
Expanded(
|
||||
child: ClideText(record.message, fontSize: clideFontMono, color: fg, fontFamily: clideMonoFamily),
|
||||
child: ClideText(record.message, fontSize: clideFontMono, color: fg, fontFamily: ClideSettings.fonts.monoOf(context)),
|
||||
),
|
||||
],
|
||||
),
|
||||
|
||||
@@ -228,7 +228,7 @@ class _ScoreBar extends StatelessWidget {
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 6),
|
||||
ClideText('${(score * 100).round()}%', fontSize: clideFontBadge, muted: true, fontFamily: clideMonoFamily),
|
||||
ClideText('${(score * 100).round()}%', fontSize: clideFontBadge, muted: true, fontFamily: ClideSettings.fonts.monoOf(context)),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
@@ -113,7 +113,7 @@ class _ProblemRow extends StatelessWidget {
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
ClideText(problem.source, fontSize: clideFontMono, color: tokens.statusWarning, fontFamily: clideMonoFamily),
|
||||
ClideText(problem.source, fontSize: clideFontMono, color: tokens.statusWarning, fontFamily: ClideSettings.fonts.monoOf(context)),
|
||||
const SizedBox(width: 6),
|
||||
Expanded(child: ClideText(problem.message, color: tokens.sidebarForeground, maxLines: 2)),
|
||||
],
|
||||
@@ -121,7 +121,7 @@ class _ProblemRow extends StatelessWidget {
|
||||
if (problem.hint != null)
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(left: 44, top: 2),
|
||||
child: ClideText(problem.hint!, fontSize: clideFontMono, muted: true, fontFamily: clideMonoFamily),
|
||||
child: ClideText(problem.hint!, fontSize: clideFontMono, muted: true, fontFamily: ClideSettings.fonts.monoOf(context)),
|
||||
),
|
||||
],
|
||||
),
|
||||
|
||||
@@ -255,7 +255,7 @@ class _Toggle extends StatelessWidget {
|
||||
),
|
||||
child: ClideText(
|
||||
label,
|
||||
fontFamily: clideMonoFamily,
|
||||
fontFamily: ClideSettings.fonts.monoOf(context),
|
||||
fontSize: clideFontCaption,
|
||||
color: active ? tokens.listItemSelectedForeground : tokens.sidebarForeground,
|
||||
),
|
||||
@@ -344,7 +344,7 @@ class _MatchRow extends StatelessWidget {
|
||||
children: [
|
||||
SizedBox(
|
||||
width: 36,
|
||||
child: ClideText('${match.line}', fontSize: clideFontCaption, fontFamily: clideMonoFamily, color: tokens.globalTextMuted),
|
||||
child: ClideText('${match.line}', fontSize: clideFontCaption, fontFamily: ClideSettings.fonts.monoOf(context), color: tokens.globalTextMuted),
|
||||
),
|
||||
Expanded(child: replacement.isEmpty ? _highlighted() : _preview()),
|
||||
],
|
||||
|
||||
@@ -128,7 +128,12 @@ class _SectionCard extends StatelessWidget {
|
||||
if (section.label.isNotEmpty)
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(left: 2, bottom: 6),
|
||||
child: ClideText(section.label.toUpperCase(), fontSize: clideFontCaption, color: tokens.sidebarSectionHeader, fontFamily: clideMonoFamily),
|
||||
child: ClideText(
|
||||
section.label.toUpperCase(),
|
||||
fontSize: clideFontCaption,
|
||||
color: tokens.sidebarSectionHeader,
|
||||
fontFamily: ClideSettings.fonts.monoOf(context),
|
||||
),
|
||||
),
|
||||
ClideSurface(
|
||||
// Card surface (surface.md): panelHeader resolves to the `surface`
|
||||
@@ -440,7 +445,7 @@ class _EditControlState extends State<_EditControl> {
|
||||
child: EditableText(
|
||||
controller: _controller,
|
||||
focusNode: _focus,
|
||||
style: TextStyle(fontFamily: clideMonoFamily, fontSize: clideFontMono, color: tokens.globalForeground),
|
||||
style: TextStyle(fontFamily: ClideSettings.fonts.monoOf(context), fontSize: clideFontMono, color: tokens.globalForeground),
|
||||
cursorColor: tokens.globalFocus,
|
||||
backgroundCursorColor: tokens.globalTextMuted,
|
||||
maxLines: 1,
|
||||
|
||||
@@ -202,7 +202,7 @@ class _CategoryRail extends StatelessWidget {
|
||||
i.string('rail.header', namespace: SettingsModal.ns, placeholder: 'Categories'),
|
||||
fontSize: clideFontCaption,
|
||||
color: tokens.sidebarSectionHeader,
|
||||
fontFamily: clideMonoFamily,
|
||||
fontFamily: ClideSettings.fonts.monoOf(context),
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
|
||||
@@ -75,7 +75,7 @@ class _SettingsViewState extends State<SettingsView> {
|
||||
i.string('section.appearance', namespace: SettingsView.ns, placeholder: 'Appearance'),
|
||||
fontSize: clideFontCaption,
|
||||
color: tokens.sidebarSectionHeader,
|
||||
fontFamily: clideMonoFamily,
|
||||
fontFamily: ClideSettings.fonts.monoOf(context),
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
_HighContrastToggle(
|
||||
|
||||
@@ -148,16 +148,17 @@ class _TicketHeader extends StatelessWidget {
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 8),
|
||||
ClideText(detail.id, fontSize: clideFontSmall, color: typeColor, fontFamily: clideMonoFamily),
|
||||
ClideText(detail.id, fontSize: clideFontSmall, color: typeColor, fontFamily: ClideSettings.fonts.monoOf(context)),
|
||||
const Spacer(),
|
||||
if (detail.priority != null) ClideText(detail.priority!, fontSize: clideFontSmall, color: tokens.globalTextMuted, fontFamily: clideMonoFamily),
|
||||
if (detail.priority != null)
|
||||
ClideText(detail.priority!, fontSize: clideFontSmall, color: tokens.globalTextMuted, fontFamily: ClideSettings.fonts.monoOf(context)),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
ClideText(detail.title, fontSize: 15, fontWeight: FontWeight.w500),
|
||||
if (detail.assignedTo != null) ...[
|
||||
const SizedBox(height: 6),
|
||||
ClideText('assigned: ${detail.assignedTo}', muted: true, fontSize: clideFontSmall, fontFamily: clideMonoFamily),
|
||||
ClideText('assigned: ${detail.assignedTo}', muted: true, fontSize: clideFontSmall, fontFamily: ClideSettings.fonts.monoOf(context)),
|
||||
],
|
||||
],
|
||||
),
|
||||
@@ -206,7 +207,7 @@ class _StatusControls extends StatelessWidget {
|
||||
border: Border.all(color: active ? tokens.statusInfo : tokens.panelBorder),
|
||||
),
|
||||
alignment: Alignment.center,
|
||||
child: ClideText(_shortLabel(s), fontSize: clideFontBadge, color: color, fontFamily: clideMonoFamily),
|
||||
child: ClideText(_shortLabel(s), fontSize: clideFontBadge, color: color, fontFamily: ClideSettings.fonts.monoOf(context)),
|
||||
);
|
||||
},
|
||||
),
|
||||
@@ -234,7 +235,7 @@ class _SectionLabel extends StatelessWidget {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return ClideText(label, fontSize: clideFontSmall, color: tokens.sidebarSectionHeader, fontFamily: clideMonoFamily);
|
||||
return ClideText(label, fontSize: clideFontSmall, color: tokens.sidebarSectionHeader, fontFamily: ClideSettings.fonts.monoOf(context));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -270,7 +271,7 @@ class _CompactCard extends StatelessWidget {
|
||||
decoration: BoxDecoration(color: typeColor, shape: BoxShape.circle),
|
||||
),
|
||||
const SizedBox(width: 6),
|
||||
ClideText(id, fontSize: clideFontSmall, color: tokens.globalTextMuted, fontFamily: clideMonoFamily),
|
||||
ClideText(id, fontSize: clideFontSmall, color: tokens.globalTextMuted, fontFamily: ClideSettings.fonts.monoOf(context)),
|
||||
const SizedBox(width: 8),
|
||||
Expanded(child: ClideText(title, fontSize: clideFontSmall)),
|
||||
],
|
||||
@@ -320,9 +321,10 @@ class _DecisionRefCard extends StatelessWidget {
|
||||
decoration: BoxDecoration(color: color, shape: BoxShape.circle),
|
||||
),
|
||||
const SizedBox(width: 6),
|
||||
ClideText(id, fontSize: clideFontSmall, color: color, fontFamily: clideMonoFamily),
|
||||
ClideText(id, fontSize: clideFontSmall, color: color, fontFamily: ClideSettings.fonts.monoOf(context)),
|
||||
const Spacer(),
|
||||
if (domain != null) ClideText(domain, fontSize: clideFontBadge, color: tokens.globalTextMuted, fontFamily: clideMonoFamily),
|
||||
if (domain != null)
|
||||
ClideText(domain, fontSize: clideFontBadge, color: tokens.globalTextMuted, fontFamily: ClideSettings.fonts.monoOf(context)),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 3),
|
||||
|
||||
@@ -314,7 +314,12 @@ class _TypeChip extends StatelessWidget {
|
||||
decoration: BoxDecoration(color: dotColor, shape: BoxShape.circle),
|
||||
),
|
||||
const SizedBox(width: 6),
|
||||
ClideText(label, fontSize: clideFontSmall, fontFamily: clideMonoFamily, color: active ? tokens.globalForeground : tokens.globalTextMuted),
|
||||
ClideText(
|
||||
label,
|
||||
fontSize: clideFontSmall,
|
||||
fontFamily: ClideSettings.fonts.monoOf(context),
|
||||
color: active ? tokens.globalForeground : tokens.globalTextMuted,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
@@ -386,7 +391,7 @@ class _TicketCard extends StatelessWidget {
|
||||
entry.parentId!,
|
||||
fontSize: clideFontSmall,
|
||||
color: hovered ? tokens.globalForeground : tokens.globalTextMuted,
|
||||
fontFamily: clideMonoFamily,
|
||||
fontFamily: ClideSettings.fonts.monoOf(context),
|
||||
),
|
||||
),
|
||||
),
|
||||
@@ -402,7 +407,13 @@ class _TicketCard extends StatelessWidget {
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 6),
|
||||
ClideText(entry.id, fontSize: clideFontSmall, color: tokens.globalForeground, fontFamily: clideMonoFamily, fontWeight: FontWeight.w600),
|
||||
ClideText(
|
||||
entry.id,
|
||||
fontSize: clideFontSmall,
|
||||
color: tokens.globalForeground,
|
||||
fontFamily: ClideSettings.fonts.monoOf(context),
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 4),
|
||||
@@ -480,7 +491,7 @@ class _StatusBadge extends StatelessWidget {
|
||||
return Container(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 6, vertical: 2),
|
||||
decoration: BoxDecoration(color: color.withAlpha(0x30), borderRadius: BorderRadius.circular(3)),
|
||||
child: ClideText(label, fontSize: clideFontBadge, color: color, fontFamily: clideMonoFamily),
|
||||
child: ClideText(label, fontSize: clideFontBadge, color: color, fontFamily: ClideSettings.fonts.monoOf(context)),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,7 +20,12 @@ class VimModeIndicator extends StatelessWidget {
|
||||
final tokens = ClideTheme.of(context).surface;
|
||||
return Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 8),
|
||||
child: ClideText('-- ${service.mode.label} --', fontFamily: clideMonoFamily, fontSize: clideFontCaption, color: tokens.statusBarForeground),
|
||||
child: ClideText(
|
||||
'-- ${service.mode.label} --',
|
||||
fontFamily: ClideSettings.fonts.monoOf(context),
|
||||
fontSize: clideFontCaption,
|
||||
color: tokens.statusBarForeground,
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
|
||||
@@ -105,7 +105,7 @@ class _TipsCard extends StatelessWidget {
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
ClideText('TIPS', fontSize: clideFontSmall, color: tokens.sidebarSectionHeader, fontFamily: clideMonoFamily),
|
||||
ClideText('TIPS', fontSize: clideFontSmall, color: tokens.sidebarSectionHeader, fontFamily: ClideSettings.fonts.monoOf(context)),
|
||||
const SizedBox(height: 14),
|
||||
_tipRow(firstRow),
|
||||
const SizedBox(height: 8),
|
||||
@@ -170,7 +170,7 @@ class _StartColumn extends StatelessWidget {
|
||||
return Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
ClideText('START', fontSize: clideFontSmall, color: tokens.sidebarSectionHeader, fontFamily: clideMonoFamily),
|
||||
ClideText('START', fontSize: clideFontSmall, color: tokens.sidebarSectionHeader, fontFamily: ClideSettings.fonts.monoOf(context)),
|
||||
const SizedBox(height: 20),
|
||||
// Only flows that exist get a tile — the old Clone-from-git and
|
||||
// Start-a-Claude-session rows were inert and advertised shortcuts
|
||||
@@ -233,7 +233,7 @@ class _ActionRow extends StatelessWidget {
|
||||
Expanded(
|
||||
child: ClideText(label, fontSize: clideFontBody, color: tokens.globalForeground),
|
||||
),
|
||||
if (shortcut != null) ClideText(shortcut!, fontSize: clideFontMeta, color: tokens.globalTextMuted, fontFamily: clideMonoFamily),
|
||||
if (shortcut != null) ClideText(shortcut!, fontSize: clideFontMeta, color: tokens.globalTextMuted, fontFamily: ClideSettings.fonts.monoOf(context)),
|
||||
],
|
||||
),
|
||||
),
|
||||
@@ -255,7 +255,7 @@ class _RecentColumn extends StatelessWidget {
|
||||
return Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
ClideText('RECENT', fontSize: clideFontSmall, color: tokens.sidebarSectionHeader, fontFamily: clideMonoFamily),
|
||||
ClideText('RECENT', fontSize: clideFontSmall, color: tokens.sidebarSectionHeader, fontFamily: ClideSettings.fonts.monoOf(context)),
|
||||
const SizedBox(height: 20),
|
||||
if (recents.isEmpty)
|
||||
const ClideText('No recent projects.', muted: true, fontSize: clideFontCaption)
|
||||
@@ -309,7 +309,7 @@ class _RecentRow extends StatelessWidget {
|
||||
project.relativePath,
|
||||
muted: true,
|
||||
fontSize: clideFontMeta,
|
||||
fontFamily: clideMonoFamily,
|
||||
fontFamily: ClideSettings.fonts.monoOf(context),
|
||||
maxLines: 1,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
@@ -323,7 +323,7 @@ class _RecentRow extends StatelessWidget {
|
||||
project.branch!,
|
||||
muted: true,
|
||||
fontSize: clideFontMeta,
|
||||
fontFamily: clideMonoFamily,
|
||||
fontFamily: ClideSettings.fonts.monoOf(context),
|
||||
maxLines: 1,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
@@ -399,17 +399,17 @@ class _StatusLine extends StatelessWidget {
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
ClideText('$clideName $clideVersion', muted: true, fontSize: clideFontSmall, fontFamily: clideMonoFamily),
|
||||
ClideText('$clideName $clideVersion', muted: true, fontSize: clideFontSmall, fontFamily: ClideSettings.fonts.monoOf(context)),
|
||||
ClideText(' · ', muted: true, fontSize: clideFontSmall),
|
||||
if (!tc.resolved)
|
||||
ClideText('checking…', muted: true, fontSize: clideFontSmall, fontFamily: clideMonoFamily)
|
||||
ClideText('checking…', muted: true, fontSize: clideFontSmall, fontFamily: ClideSettings.fonts.monoOf(context))
|
||||
else if (tc.allOk)
|
||||
ClideText('application ok', fontSize: clideFontSmall, fontFamily: clideMonoFamily, color: tokens.statusSuccess)
|
||||
ClideText('application ok', fontSize: clideFontSmall, fontFamily: ClideSettings.fonts.monoOf(context), color: tokens.statusSuccess)
|
||||
else
|
||||
ClideText(
|
||||
tc.missing.map((t) => '$t not found').join(' · '),
|
||||
fontSize: clideFontSmall,
|
||||
fontFamily: clideMonoFamily,
|
||||
fontFamily: ClideSettings.fonts.monoOf(context),
|
||||
color: tokens.statusWarning,
|
||||
),
|
||||
ClideText(' · ', muted: true, fontSize: clideFontSmall),
|
||||
@@ -435,8 +435,13 @@ class _ThemeLink extends StatelessWidget {
|
||||
builder: (ctx, hovered, _) => Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
ClideText('theme: ', muted: true, fontSize: clideFontSmall, fontFamily: clideMonoFamily),
|
||||
ClideText(themeName, fontSize: clideFontSmall, fontFamily: clideMonoFamily, color: hovered ? tokens.globalForeground : tokens.globalFocus),
|
||||
ClideText('theme: ', muted: true, fontSize: clideFontSmall, fontFamily: ClideSettings.fonts.monoOf(context)),
|
||||
ClideText(
|
||||
themeName,
|
||||
fontSize: clideFontSmall,
|
||||
fontFamily: ClideSettings.fonts.monoOf(context),
|
||||
color: hovered ? tokens.globalForeground : tokens.globalFocus,
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
@@ -518,7 +523,7 @@ class _OpenProjectDialogState extends State<_OpenProjectDialog> {
|
||||
style: TextStyle(
|
||||
color: tokens.globalForeground,
|
||||
fontSize: clideFontCaption,
|
||||
fontFamily: clideMonoFamily,
|
||||
fontFamily: ClideSettings.fonts.monoOf(context),
|
||||
fontFamilyFallback: clideMonoFamilyFallback,
|
||||
),
|
||||
cursorColor: tokens.globalForeground,
|
||||
|
||||
Reference in New Issue
Block a user